aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-02-01 10:43:45 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-02-01 10:43:45 -0800
commitefc518eb318c4d776933c23e7b82c2e5402b62de (patch)
treeee9100af7dd17039524c7833e0128de49eab5be1
parentfea8893da7c52906caa1a8dc3199f4b2ed3b8dbd (diff)
parentd22e6338db7f613dd4f6095c190682fcc519e4b7 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "Several obvious fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: Fix mountpoint reference leakage in linkat hfsplus: use xattr handlers for removexattr Typo in compat_sys_lseek() declaration fs/super.c: sync ro remount after blocking writers vfs: unexport the getname() symbol
-rw-r--r--fs/hfsplus/dir.c2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hfsplus/xattr.c60
-rw-r--r--fs/hfsplus/xattr.h2
-rw-r--r--fs/namei.c6
-rw-r--r--fs/super.c3
-rw-r--r--include/linux/compat.h2
7 files changed, 26 insertions, 51 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 9ee62985e73..bdec66522de 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -529,7 +529,7 @@ const struct inode_operations hfsplus_dir_inode_operations = {
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.listxattr = hfsplus_listxattr,
- .removexattr = hfsplus_removexattr,
+ .removexattr = generic_removexattr,
#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
.get_acl = hfsplus_get_posix_acl,
.set_acl = hfsplus_set_posix_acl,
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 4551cbd6bd4..fa929f325f8 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -331,7 +331,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.listxattr = hfsplus_listxattr,
- .removexattr = hfsplus_removexattr,
+ .removexattr = generic_removexattr,
#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
.get_acl = hfsplus_get_posix_acl,
.set_acl = hfsplus_set_posix_acl,
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 0b4a5c9b93c..4e27edc082a 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -11,6 +11,8 @@
#include "xattr.h"
#include "acl.h"
+static int hfsplus_removexattr(struct inode *inode, const char *name);
+
const struct xattr_handler *hfsplus_xattr_handlers[] = {
&hfsplus_xattr_osx_handler,
&hfsplus_xattr_user_handler,
@@ -274,14 +276,8 @@ int __hfsplus_setxattr(struct inode *inode, const char *name,
HFSPLUS_IS_RSRC(inode))
return -EOPNOTSUPP;
- if (strncmp(name, XATTR_MAC_OSX_PREFIX,
- XATTR_MAC_OSX_PREFIX_LEN) == 0)
- name += XATTR_MAC_OSX_PREFIX_LEN;
-
- if (value == NULL) {
- value = "";
- size = 0;
- }
+ if (value == NULL)
+ return hfsplus_removexattr(inode, name);
err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &cat_fd);
if (err) {
@@ -399,16 +395,11 @@ end_setxattr:
return err;
}
-static inline int is_osx_xattr(const char *xattr_name)
-{
- return !is_known_namespace(xattr_name);
-}
-
static int name_len(const char *xattr_name, int xattr_name_len)
{
int len = xattr_name_len + 1;
- if (is_osx_xattr(xattr_name))
+ if (!is_known_namespace(xattr_name))
len += XATTR_MAC_OSX_PREFIX_LEN;
return len;
@@ -419,7 +410,7 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len)
int len = name_len;
int offset = 0;
- if (is_osx_xattr(xattr_name)) {
+ if (!is_known_namespace(xattr_name)) {
strncpy(buffer, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN);
offset += XATTR_MAC_OSX_PREFIX_LEN;
len += XATTR_MAC_OSX_PREFIX_LEN;
@@ -497,18 +488,6 @@ ssize_t __hfsplus_getxattr(struct inode *inode, const char *name,
HFSPLUS_IS_RSRC(inode))
return -EOPNOTSUPP;
- if (strncmp(name, XATTR_MAC_OSX_PREFIX,
- XATTR_MAC_OSX_PREFIX_LEN) == 0) {
- /* skip "osx." prefix */
- name += XATTR_MAC_OSX_PREFIX_LEN;
- /*
- * Don't allow retrieving properly prefixed attributes
- * by prepending them with "osx."
- */
- if (is_known_namespace(name))
- return -EOPNOTSUPP;
- }
-
if (!strcmp_xattr_finder_info(name))
return hfsplus_getxattr_finder_info(inode, value, size);
@@ -743,28 +722,18 @@ end_listxattr:
return res;
}
-int hfsplus_removexattr(struct dentry *dentry, const char *name)
+static int hfsplus_removexattr(struct inode *inode, const char *name)
{
int err = 0;
- struct inode *inode = dentry->d_inode;
struct hfs_find_data cat_fd;
u16 flags;
u16 cat_entry_type;
int is_xattr_acl_deleted = 0;
int is_all_xattrs_deleted = 0;
- if ((!S_ISREG(inode->i_mode) &&
- !S_ISDIR(inode->i_mode)) ||
- HFSPLUS_IS_RSRC(inode))
- return -EOPNOTSUPP;
-
if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
return -EOPNOTSUPP;
- if (strncmp(name, XATTR_MAC_OSX_PREFIX,
- XATTR_MAC_OSX_PREFIX_LEN) == 0)
- name += XATTR_MAC_OSX_PREFIX_LEN;
-
if (!strcmp_xattr_finder_info(name))
return -EOPNOTSUPP;
@@ -838,8 +807,12 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name,
if (len > HFSPLUS_ATTR_MAX_STRLEN)
return -EOPNOTSUPP;
- strcpy(xattr_name, XATTR_MAC_OSX_PREFIX);
- strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name);
+ /*
+ * Don't allow retrieving properly prefixed attributes
+ * by prepending them with "osx."
+ */
+ if (is_known_namespace(name))
+ return -EOPNOTSUPP;
return hfsplus_getxattr(dentry, xattr_name, buffer, size);
}
@@ -857,12 +830,13 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name,
if (len > HFSPLUS_ATTR_MAX_STRLEN)
return -EOPNOTSUPP;
+ /*
+ * Don't allow setting properly prefixed attributes
+ * by prepending them with "osx."
+ */
if (is_known_namespace(name))
return -EOPNOTSUPP;
- strcpy(xattr_name, XATTR_MAC_OSX_PREFIX);
- strcpy(xattr_name + XATTR_MAC_OSX_PREFIX_LEN, name);
-
return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags);
}
diff --git a/fs/hfsplus/xattr.h b/fs/hfsplus/xattr.h
index 9e214490c31..288530cf80b 100644
--- a/fs/hfsplus/xattr.h
+++ b/fs/hfsplus/xattr.h
@@ -40,8 +40,6 @@ static inline ssize_t hfsplus_getxattr(struct dentry *dentry,
ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
-int hfsplus_removexattr(struct dentry *dentry, const char *name);
-
int hfsplus_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr);
diff --git a/fs/namei.c b/fs/namei.c
index bcb838e2e52..d580df2e680 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -209,7 +209,6 @@ getname(const char __user * filename)
{
return getname_flags(filename, 0, NULL);
}
-EXPORT_SYMBOL(getname);
#ifdef CONFIG_AUDITSYSCALL
void putname(struct filename *name)
@@ -3927,10 +3926,13 @@ out_dput:
done_path_create(&new_path, new_dentry);
if (delegated_inode) {
error = break_deleg_wait(&delegated_inode);
- if (!error)
+ if (!error) {
+ path_put(&old_path);
goto retry;
+ }
}
if (retry_estale(error, how)) {
+ path_put(&old_path);
how |= LOOKUP_REVAL;
goto retry;
}
diff --git a/fs/super.c b/fs/super.c
index cecd780e0f4..80d5cf2ca76 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -703,7 +703,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
if (flags & MS_RDONLY)
acct_auto_close(sb);
shrink_dcache_sb(sb);
- sync_filesystem(sb);
remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
@@ -720,6 +719,8 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
}
}
+ sync_filesystem(sb);
+
if (sb->s_op->remount_fs) {
retval = sb->s_op->remount_fs(sb, &flags, data);
if (retval) {
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 19f6003291d..3f448c65511 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -337,7 +337,7 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
const struct compat_iovec __user *vec,
compat_ulong_t vlen, u32 pos_low, u32 pos_high);
-asmlinkage long comat_sys_lseek(unsigned int, compat_off_t, unsigned int);
+asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int);
asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
const compat_uptr_t __user *envp);