aboutsummaryrefslogtreecommitdiff
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorLinus Torvalds2014-10-13 11:28:42 +0200
committerLinus Torvalds2014-10-13 11:28:42 +0200
commit77c688ac87183537ed0fb84ec2cb8fa8ec97c458 (patch)
treed18e117e05c0d71463823536165ddd9ad75b6bc5 /fs/xattr.c
parent5e40d331bd72447197f26525f21711c4a265b6a6 (diff)
parenta457606a6f81cfddfc9da1ef2a8bf2c65a8eb35e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "The big thing in this pile is Eric's unmount-on-rmdir series; we finally have everything we need for that. The final piece of prereqs is delayed mntput() - now filesystem shutdown always happens on shallow stack. Other than that, we have several new primitives for iov_iter (Matt Wilcox, culled from his XIP-related series) pushing the conversion to ->read_iter()/ ->write_iter() a bit more, a bunch of fs/dcache.c cleanups and fixes (including the external name refcounting, which gives consistent behaviour of d_move() wrt procfs symlinks for long and short names alike) and assorted cleanups and fixes all over the place. This is just the first pile; there's a lot of stuff from various people that ought to go in this window. Starting with unionmount/overlayfs mess... ;-/" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (60 commits) fs/file_table.c: Update alloc_file() comment vfs: Deduplicate code shared by xattr system calls operating on paths reiserfs: remove pointless forward declaration of struct nameidata don't need that forward declaration of struct nameidata in dcache.h anymore take dname_external() into fs/dcache.c let path_init() failures treated the same way as subsequent link_path_walk() fix misuses of f_count() in ppp and netlink ncpfs: use list_for_each_entry() for d_subdirs walk vfs: move getname() from callers to do_mount() gfs2_atomic_open(): skip lookups on hashed dentry [infiniband] remove pointless assignments gadgetfs: saner API for gadgetfs_create_file() f_fs: saner API for ffs_sb_create_file() jfs: don't hash direct inode [s390] remove pointless assignment of ->f_op in vmlogrdr ->open() ecryptfs: ->f_op is never NULL android: ->f_op is never NULL nouveau: __iomem misannotations missing annotation in fs/file.c fs: namespace: suppress 'may be used uninitialized' warnings ...
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c116
1 files changed, 39 insertions, 77 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index c69e6d43a0d2..64e83efb742d 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -364,13 +364,12 @@ out:
return error;
}
-SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
- const char __user *, name, const void __user *, value,
- size_t, size, int, flags)
+static int path_setxattr(const char __user *pathname,
+ const char __user *name, const void __user *value,
+ size_t size, int flags, unsigned int lookup_flags)
{
struct path path;
int error;
- unsigned int lookup_flags = LOOKUP_FOLLOW;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
@@ -388,28 +387,18 @@ retry:
return error;
}
+SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
+ const char __user *, name, const void __user *, value,
+ size_t, size, int, flags)
+{
+ return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
+}
+
SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
- struct path path;
- int error;
- unsigned int lookup_flags = 0;
-retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
- if (error)
- return error;
- error = mnt_want_write(path.mnt);
- if (!error) {
- error = setxattr(path.dentry, name, value, size, flags);
- mnt_drop_write(path.mnt);
- }
- path_put(&path);
- if (retry_estale(error, lookup_flags)) {
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
- return error;
+ return path_setxattr(pathname, name, value, size, flags, 0);
}
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
@@ -481,12 +470,12 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
return error;
}
-SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
- const char __user *, name, void __user *, value, size_t, size)
+static ssize_t path_getxattr(const char __user *pathname,
+ const char __user *name, void __user *value,
+ size_t size, unsigned int lookup_flags)
{
struct path path;
ssize_t error;
- unsigned int lookup_flags = LOOKUP_FOLLOW;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
@@ -500,23 +489,16 @@ retry:
return error;
}
+SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
+ const char __user *, name, void __user *, value, size_t, size)
+{
+ return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
+}
+
SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
- struct path path;
- ssize_t error;
- unsigned int lookup_flags = 0;
-retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
- if (error)
- return error;
- error = getxattr(path.dentry, name, value, size);
- path_put(&path);
- if (retry_estale(error, lookup_flags)) {
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
- return error;
+ return path_getxattr(pathname, name, value, size, 0);
}
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
@@ -571,12 +553,11 @@ listxattr(struct dentry *d, char __user *list, size_t size)
return error;
}
-SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
- size_t, size)
+static ssize_t path_listxattr(const char __user *pathname, char __user *list,
+ size_t size, unsigned int lookup_flags)
{
struct path path;
ssize_t error;
- unsigned int lookup_flags = LOOKUP_FOLLOW;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
@@ -590,23 +571,16 @@ retry:
return error;
}
+SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
+ size_t, size)
+{
+ return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
+}
+
SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
- struct path path;
- ssize_t error;
- unsigned int lookup_flags = 0;
-retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
- if (error)
- return error;
- error = listxattr(path.dentry, list, size);
- path_put(&path);
- if (retry_estale(error, lookup_flags)) {
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
- return error;
+ return path_listxattr(pathname, list, size, 0);
}
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
@@ -640,12 +614,11 @@ removexattr(struct dentry *d, const char __user *name)
return vfs_removexattr(d, kname);
}
-SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
- const char __user *, name)
+static int path_removexattr(const char __user *pathname,
+ const char __user *name, unsigned int lookup_flags)
{
struct path path;
int error;
- unsigned int lookup_flags = LOOKUP_FOLLOW;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
@@ -663,27 +636,16 @@ retry:
return error;
}
+SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
+ const char __user *, name)
+{
+ return path_removexattr(pathname, name, LOOKUP_FOLLOW);
+}
+
SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
const char __user *, name)
{
- struct path path;
- int error;
- unsigned int lookup_flags = 0;
-retry:
- error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
- if (error)
- return error;
- error = mnt_want_write(path.mnt);
- if (!error) {
- error = removexattr(path.dentry, name);
- mnt_drop_write(path.mnt);
- }
- path_put(&path);
- if (retry_estale(error, lookup_flags)) {
- lookup_flags |= LOOKUP_REVAL;
- goto retry;
- }
- return error;
+ return path_removexattr(pathname, name, 0);
}
SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)