diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-13 21:02:30 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-13 21:02:30 -0500 |
| commit | 5d2eb548b309be34ecf3b91f0b7300a2b9d09b8c (patch) | |
| tree | 89ce62fe154e6f10a018abb67f5f09015dd394fc | |
| parent | 2870f6c4d136e093e22159b8916918ff42c92218 (diff) | |
| parent | 29608d208b3619b3b508a6871622db789611d8a3 (diff) | |
Merge branch 'for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr cleanups from Al Viro.
* 'for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
f2fs: xattr simplifications
squashfs: xattr simplifications
9p: xattr simplifications
xattr handlers: Pass handler to operations instead of flags
jffs2: Add missing capability check for listing trusted xattrs
hfsplus: Remove unused xattr handler list operations
ubifs: Remove unused security xattr handler
vfs: Fix the posix_acl_xattr_list return value
vfs: Check attribute names in posix acl xattr handers
39 files changed, 390 insertions, 651 deletions
diff --git a/fs/9p/Makefile b/fs/9p/Makefile index ff7be98f84f2..9619ccadd2fc 100644 --- a/fs/9p/Makefile +++ b/fs/9p/Makefile | |||
| @@ -10,10 +10,7 @@ obj-$(CONFIG_9P_FS) := 9p.o | |||
| 10 | vfs_dentry.o \ | 10 | vfs_dentry.o \ |
| 11 | v9fs.o \ | 11 | v9fs.o \ |
| 12 | fid.o \ | 12 | fid.o \ |
| 13 | xattr.o \ | 13 | xattr.o |
| 14 | xattr_user.o \ | ||
| 15 | xattr_trusted.o | ||
| 16 | 14 | ||
| 17 | 9p-$(CONFIG_9P_FSCACHE) += cache.o | 15 | 9p-$(CONFIG_9P_FSCACHE) += cache.o |
| 18 | 9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o | 16 | 9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o |
| 19 | 9p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o | ||
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 31c010372660..a7e28890f5ef 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
| @@ -212,26 +212,9 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep, | |||
| 212 | return 0; | 212 | return 0; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, | 215 | static int v9fs_xattr_get_acl(const struct xattr_handler *handler, |
| 216 | void *buffer, size_t size, int type) | 216 | struct dentry *dentry, const char *name, |
| 217 | { | 217 | void *buffer, size_t size) |
| 218 | char *full_name; | ||
| 219 | |||
| 220 | switch (type) { | ||
| 221 | case ACL_TYPE_ACCESS: | ||
| 222 | full_name = POSIX_ACL_XATTR_ACCESS; | ||
| 223 | break; | ||
| 224 | case ACL_TYPE_DEFAULT: | ||
| 225 | full_name = POSIX_ACL_XATTR_DEFAULT; | ||
| 226 | break; | ||
| 227 | default: | ||
| 228 | BUG(); | ||
| 229 | } | ||
| 230 | return v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 231 | } | ||
| 232 | |||
| 233 | static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | ||
| 234 | void *buffer, size_t size, int type) | ||
| 235 | { | 218 | { |
| 236 | struct v9fs_session_info *v9ses; | 219 | struct v9fs_session_info *v9ses; |
| 237 | struct posix_acl *acl; | 220 | struct posix_acl *acl; |
| @@ -245,9 +228,9 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | |||
| 245 | * We allow set/get/list of acl when access=client is not specified | 228 | * We allow set/get/list of acl when access=client is not specified |
| 246 | */ | 229 | */ |
| 247 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | 230 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) |
| 248 | return v9fs_remote_get_acl(dentry, name, buffer, size, type); | 231 | return v9fs_xattr_get(dentry, handler->prefix, buffer, size); |
| 249 | 232 | ||
| 250 | acl = v9fs_get_cached_acl(d_inode(dentry), type); | 233 | acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags); |
| 251 | if (IS_ERR(acl)) | 234 | if (IS_ERR(acl)) |
| 252 | return PTR_ERR(acl); | 235 | return PTR_ERR(acl); |
| 253 | if (acl == NULL) | 236 | if (acl == NULL) |
| @@ -258,29 +241,9 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | |||
| 258 | return error; | 241 | return error; |
| 259 | } | 242 | } |
| 260 | 243 | ||
| 261 | static int v9fs_remote_set_acl(struct dentry *dentry, const char *name, | 244 | static int v9fs_xattr_set_acl(const struct xattr_handler *handler, |
| 262 | const void *value, size_t size, | 245 | struct dentry *dentry, const char *name, |
| 263 | int flags, int type) | 246 | const void *value, size_t size, int flags) |
| 264 | { | ||
| 265 | char *full_name; | ||
| 266 | |||
| 267 | switch (type) { | ||
| 268 | case ACL_TYPE_ACCESS: | ||
| 269 | full_name = POSIX_ACL_XATTR_ACCESS; | ||
| 270 | break; | ||
| 271 | case ACL_TYPE_DEFAULT: | ||
| 272 | full_name = POSIX_ACL_XATTR_DEFAULT; | ||
| 273 | break; | ||
| 274 | default: | ||
| 275 | BUG(); | ||
| 276 | } | ||
| 277 | return v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 278 | } | ||
| 279 | |||
| 280 | |||
| 281 | static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | ||
| 282 | const void *value, size_t size, | ||
| 283 | int flags, int type) | ||
| 284 | { | 247 | { |
| 285 | int retval; | 248 | int retval; |
| 286 | struct posix_acl *acl; | 249 | struct posix_acl *acl; |
| @@ -296,8 +259,8 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | |||
| 296 | * xattr value. We leave it to the server to validate | 259 | * xattr value. We leave it to the server to validate |
| 297 | */ | 260 | */ |
| 298 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) | 261 | if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) |
| 299 | return v9fs_remote_set_acl(dentry, name, | 262 | return v9fs_xattr_set(dentry, handler->prefix, value, size, |
| 300 | value, size, flags, type); | 263 | flags); |
| 301 | 264 | ||
| 302 | if (S_ISLNK(inode->i_mode)) | 265 | if (S_ISLNK(inode->i_mode)) |
| 303 | return -EOPNOTSUPP; | 266 | return -EOPNOTSUPP; |
| @@ -316,9 +279,8 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | |||
| 316 | } else | 279 | } else |
| 317 | acl = NULL; | 280 | acl = NULL; |
| 318 | 281 | ||
| 319 | switch (type) { | 282 | switch (handler->flags) { |
| 320 | case ACL_TYPE_ACCESS: | 283 | case ACL_TYPE_ACCESS: |
| 321 | name = POSIX_ACL_XATTR_ACCESS; | ||
| 322 | if (acl) { | 284 | if (acl) { |
| 323 | umode_t mode = inode->i_mode; | 285 | umode_t mode = inode->i_mode; |
| 324 | retval = posix_acl_equiv_mode(acl, &mode); | 286 | retval = posix_acl_equiv_mode(acl, &mode); |
| @@ -349,7 +311,6 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | |||
| 349 | } | 311 | } |
| 350 | break; | 312 | break; |
| 351 | case ACL_TYPE_DEFAULT: | 313 | case ACL_TYPE_DEFAULT: |
| 352 | name = POSIX_ACL_XATTR_DEFAULT; | ||
| 353 | if (!S_ISDIR(inode->i_mode)) { | 314 | if (!S_ISDIR(inode->i_mode)) { |
| 354 | retval = acl ? -EINVAL : 0; | 315 | retval = acl ? -EINVAL : 0; |
| 355 | goto err_out; | 316 | goto err_out; |
| @@ -358,9 +319,9 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | |||
| 358 | default: | 319 | default: |
| 359 | BUG(); | 320 | BUG(); |
| 360 | } | 321 | } |
| 361 | retval = v9fs_xattr_set(dentry, name, value, size, flags); | 322 | retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags); |
| 362 | if (!retval) | 323 | if (!retval) |
| 363 | set_cached_acl(inode, type, acl); | 324 | set_cached_acl(inode, handler->flags, acl); |
| 364 | err_out: | 325 | err_out: |
| 365 | posix_acl_release(acl); | 326 | posix_acl_release(acl); |
| 366 | return retval; | 327 | return retval; |
diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c index 0cf44b6cccd6..e3d026ac382e 100644 --- a/fs/9p/xattr.c +++ b/fs/9p/xattr.c | |||
| @@ -137,6 +137,48 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
| 137 | return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); | 137 | return v9fs_xattr_get(dentry, NULL, buffer, buffer_size); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | static int v9fs_xattr_handler_get(const struct xattr_handler *handler, | ||
| 141 | struct dentry *dentry, const char *name, | ||
| 142 | void *buffer, size_t size) | ||
| 143 | { | ||
| 144 | const char *full_name = xattr_full_name(handler, name); | ||
| 145 | |||
| 146 | if (strcmp(name, "") == 0) | ||
| 147 | return -EINVAL; | ||
| 148 | return v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int v9fs_xattr_handler_set(const struct xattr_handler *handler, | ||
| 152 | struct dentry *dentry, const char *name, | ||
| 153 | const void *value, size_t size, int flags) | ||
| 154 | { | ||
| 155 | const char *full_name = xattr_full_name(handler, name); | ||
| 156 | |||
| 157 | if (strcmp(name, "") == 0) | ||
| 158 | return -EINVAL; | ||
| 159 | return v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct xattr_handler v9fs_xattr_user_handler = { | ||
| 163 | .prefix = XATTR_USER_PREFIX, | ||
| 164 | .get = v9fs_xattr_handler_get, | ||
| 165 | .set = v9fs_xattr_handler_set, | ||
| 166 | }; | ||
| 167 | |||
| 168 | static struct xattr_handler v9fs_xattr_trusted_handler = { | ||
| 169 | .prefix = XATTR_TRUSTED_PREFIX, | ||
| 170 | .get = v9fs_xattr_handler_get, | ||
| 171 | .set = v9fs_xattr_handler_set, | ||
| 172 | }; | ||
| 173 | |||
| 174 | #ifdef CONFIG_9P_FS_SECURITY | ||
| 175 | static struct xattr_handler v9fs_xattr_security_handler = { | ||
| 176 | .prefix = XATTR_SECURITY_PREFIX, | ||
| 177 | .get = v9fs_xattr_handler_get, | ||
| 178 | .set = v9fs_xattr_handler_set, | ||
| 179 | }; | ||
| 180 | #endif | ||
| 181 | |||
| 140 | const struct xattr_handler *v9fs_xattr_handlers[] = { | 182 | const struct xattr_handler *v9fs_xattr_handlers[] = { |
| 141 | &v9fs_xattr_user_handler, | 183 | &v9fs_xattr_user_handler, |
| 142 | &v9fs_xattr_trusted_handler, | 184 | &v9fs_xattr_trusted_handler, |
diff --git a/fs/9p/xattr.h b/fs/9p/xattr.h index d3e2ea3840be..c63c3bea5de5 100644 --- a/fs/9p/xattr.h +++ b/fs/9p/xattr.h | |||
| @@ -19,9 +19,6 @@ | |||
| 19 | #include <net/9p/client.h> | 19 | #include <net/9p/client.h> |
| 20 | 20 | ||
| 21 | extern const struct xattr_handler *v9fs_xattr_handlers[]; | 21 | extern const struct xattr_handler *v9fs_xattr_handlers[]; |
| 22 | extern struct xattr_handler v9fs_xattr_user_handler; | ||
| 23 | extern struct xattr_handler v9fs_xattr_trusted_handler; | ||
| 24 | extern struct xattr_handler v9fs_xattr_security_handler; | ||
| 25 | extern const struct xattr_handler v9fs_xattr_acl_access_handler; | 22 | extern const struct xattr_handler v9fs_xattr_acl_access_handler; |
| 26 | extern const struct xattr_handler v9fs_xattr_acl_default_handler; | 23 | extern const struct xattr_handler v9fs_xattr_acl_default_handler; |
| 27 | 24 | ||
diff --git a/fs/9p/xattr_security.c b/fs/9p/xattr_security.c deleted file mode 100644 index cb247a142a6e..000000000000 --- a/fs/9p/xattr_security.c +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corporation, 2010 | ||
| 3 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of version 2.1 of the GNU Lesser General Public License | ||
| 7 | * as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include "xattr.h" | ||
| 21 | |||
| 22 | static int v9fs_xattr_security_get(struct dentry *dentry, const char *name, | ||
| 23 | void *buffer, size_t size, int type) | ||
| 24 | { | ||
| 25 | int retval; | ||
| 26 | char *full_name; | ||
| 27 | size_t name_len; | ||
| 28 | size_t prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
| 29 | |||
| 30 | if (name == NULL) | ||
| 31 | return -EINVAL; | ||
| 32 | |||
| 33 | if (strcmp(name, "") == 0) | ||
| 34 | return -EINVAL; | ||
| 35 | |||
| 36 | name_len = strlen(name); | ||
| 37 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 38 | if (!full_name) | ||
| 39 | return -ENOMEM; | ||
| 40 | memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len); | ||
| 41 | memcpy(full_name+prefix_len, name, name_len); | ||
| 42 | full_name[prefix_len + name_len] = '\0'; | ||
| 43 | |||
| 44 | retval = v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 45 | kfree(full_name); | ||
| 46 | return retval; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int v9fs_xattr_security_set(struct dentry *dentry, const char *name, | ||
| 50 | const void *value, size_t size, int flags, int type) | ||
| 51 | { | ||
| 52 | int retval; | ||
| 53 | char *full_name; | ||
| 54 | size_t name_len; | ||
| 55 | size_t prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
| 56 | |||
| 57 | if (name == NULL) | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | if (strcmp(name, "") == 0) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | name_len = strlen(name); | ||
| 64 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 65 | if (!full_name) | ||
| 66 | return -ENOMEM; | ||
| 67 | memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len); | ||
| 68 | memcpy(full_name + prefix_len, name, name_len); | ||
| 69 | full_name[prefix_len + name_len] = '\0'; | ||
| 70 | |||
| 71 | retval = v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 72 | kfree(full_name); | ||
| 73 | return retval; | ||
| 74 | } | ||
| 75 | |||
| 76 | struct xattr_handler v9fs_xattr_security_handler = { | ||
| 77 | .prefix = XATTR_SECURITY_PREFIX, | ||
| 78 | .get = v9fs_xattr_security_get, | ||
| 79 | .set = v9fs_xattr_security_set, | ||
| 80 | }; | ||
diff --git a/fs/9p/xattr_trusted.c b/fs/9p/xattr_trusted.c deleted file mode 100644 index e30d33b8a3fb..000000000000 --- a/fs/9p/xattr_trusted.c +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corporation, 2010 | ||
| 3 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of version 2.1 of the GNU Lesser General Public License | ||
| 7 | * as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include "xattr.h" | ||
| 21 | |||
| 22 | static int v9fs_xattr_trusted_get(struct dentry *dentry, const char *name, | ||
| 23 | void *buffer, size_t size, int type) | ||
| 24 | { | ||
| 25 | int retval; | ||
| 26 | char *full_name; | ||
| 27 | size_t name_len; | ||
| 28 | size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; | ||
| 29 | |||
| 30 | if (name == NULL) | ||
| 31 | return -EINVAL; | ||
| 32 | |||
| 33 | if (strcmp(name, "") == 0) | ||
| 34 | return -EINVAL; | ||
| 35 | |||
| 36 | name_len = strlen(name); | ||
| 37 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 38 | if (!full_name) | ||
| 39 | return -ENOMEM; | ||
| 40 | memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len); | ||
| 41 | memcpy(full_name+prefix_len, name, name_len); | ||
| 42 | full_name[prefix_len + name_len] = '\0'; | ||
| 43 | |||
| 44 | retval = v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 45 | kfree(full_name); | ||
| 46 | return retval; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int v9fs_xattr_trusted_set(struct dentry *dentry, const char *name, | ||
| 50 | const void *value, size_t size, int flags, int type) | ||
| 51 | { | ||
| 52 | int retval; | ||
| 53 | char *full_name; | ||
| 54 | size_t name_len; | ||
| 55 | size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; | ||
| 56 | |||
| 57 | if (name == NULL) | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | if (strcmp(name, "") == 0) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | name_len = strlen(name); | ||
| 64 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 65 | if (!full_name) | ||
| 66 | return -ENOMEM; | ||
| 67 | memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len); | ||
| 68 | memcpy(full_name + prefix_len, name, name_len); | ||
| 69 | full_name[prefix_len + name_len] = '\0'; | ||
| 70 | |||
| 71 | retval = v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 72 | kfree(full_name); | ||
| 73 | return retval; | ||
| 74 | } | ||
| 75 | |||
| 76 | struct xattr_handler v9fs_xattr_trusted_handler = { | ||
| 77 | .prefix = XATTR_TRUSTED_PREFIX, | ||
| 78 | .get = v9fs_xattr_trusted_get, | ||
| 79 | .set = v9fs_xattr_trusted_set, | ||
| 80 | }; | ||
diff --git a/fs/9p/xattr_user.c b/fs/9p/xattr_user.c deleted file mode 100644 index d0b701b72080..000000000000 --- a/fs/9p/xattr_user.c +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corporation, 2010 | ||
| 3 | * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of version 2.1 of the GNU Lesser General Public License | ||
| 7 | * as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include "xattr.h" | ||
| 21 | |||
| 22 | static int v9fs_xattr_user_get(struct dentry *dentry, const char *name, | ||
| 23 | void *buffer, size_t size, int type) | ||
| 24 | { | ||
| 25 | int retval; | ||
| 26 | char *full_name; | ||
| 27 | size_t name_len; | ||
| 28 | size_t prefix_len = XATTR_USER_PREFIX_LEN; | ||
| 29 | |||
| 30 | if (name == NULL) | ||
| 31 | return -EINVAL; | ||
| 32 | |||
| 33 | if (strcmp(name, "") == 0) | ||
| 34 | return -EINVAL; | ||
| 35 | |||
| 36 | name_len = strlen(name); | ||
| 37 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 38 | if (!full_name) | ||
| 39 | return -ENOMEM; | ||
| 40 | memcpy(full_name, XATTR_USER_PREFIX, prefix_len); | ||
| 41 | memcpy(full_name+prefix_len, name, name_len); | ||
| 42 | full_name[prefix_len + name_len] = '\0'; | ||
| 43 | |||
| 44 | retval = v9fs_xattr_get(dentry, full_name, buffer, size); | ||
| 45 | kfree(full_name); | ||
| 46 | return retval; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int v9fs_xattr_user_set(struct dentry *dentry, const char *name, | ||
| 50 | const void *value, size_t size, int flags, int type) | ||
| 51 | { | ||
| 52 | int retval; | ||
| 53 | char *full_name; | ||
| 54 | size_t name_len; | ||
| 55 | size_t prefix_len = XATTR_USER_PREFIX_LEN; | ||
| 56 | |||
| 57 | if (name == NULL) | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | if (strcmp(name, "") == 0) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | name_len = strlen(name); | ||
| 64 | full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL); | ||
| 65 | if (!full_name) | ||
| 66 | return -ENOMEM; | ||
| 67 | memcpy(full_name, XATTR_USER_PREFIX, prefix_len); | ||
| 68 | memcpy(full_name + prefix_len, name, name_len); | ||
| 69 | full_name[prefix_len + name_len] = '\0'; | ||
| 70 | |||
| 71 | retval = v9fs_xattr_set(dentry, full_name, value, size, flags); | ||
| 72 | kfree(full_name); | ||
| 73 | return retval; | ||
| 74 | } | ||
| 75 | |||
| 76 | struct xattr_handler v9fs_xattr_user_handler = { | ||
| 77 | .prefix = XATTR_USER_PREFIX, | ||
| 78 | .get = v9fs_xattr_user_get, | ||
| 79 | .set = v9fs_xattr_user_set, | ||
| 80 | }; | ||
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 0b6bfd3a398b..fa70848afa8f 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
| @@ -293,10 +293,9 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", | |||
| 293 | ext2_xattr_handler(entry->e_name_index); | 293 | ext2_xattr_handler(entry->e_name_index); |
| 294 | 294 | ||
| 295 | if (handler) { | 295 | if (handler) { |
| 296 | size_t size = handler->list(dentry, buffer, rest, | 296 | size_t size = handler->list(handler, dentry, buffer, |
| 297 | entry->e_name, | 297 | rest, entry->e_name, |
| 298 | entry->e_name_len, | 298 | entry->e_name_len); |
| 299 | handler->flags); | ||
| 300 | if (buffer) { | 299 | if (buffer) { |
| 301 | if (size > rest) { | 300 | if (size > rest) { |
| 302 | error = -ERANGE; | 301 | error = -ERANGE; |
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index 702fc6840246..dfb08750370d 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
| @@ -8,8 +8,9 @@ | |||
| 8 | #include "xattr.h" | 8 | #include "xattr.h" |
| 9 | 9 | ||
| 10 | static size_t | 10 | static size_t |
| 11 | ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, | 11 | ext2_xattr_security_list(const struct xattr_handler *handler, |
| 12 | const char *name, size_t name_len, int type) | 12 | struct dentry *dentry, char *list, size_t list_size, |
| 13 | const char *name, size_t name_len) | ||
| 13 | { | 14 | { |
| 14 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; | 15 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; |
| 15 | const size_t total_len = prefix_len + name_len + 1; | 16 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -23,8 +24,9 @@ ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | static int | 26 | static int |
| 26 | ext2_xattr_security_get(struct dentry *dentry, const char *name, | 27 | ext2_xattr_security_get(const struct xattr_handler *handler, |
| 27 | void *buffer, size_t size, int type) | 28 | struct dentry *dentry, const char *name, |
| 29 | void *buffer, size_t size) | ||
| 28 | { | 30 | { |
| 29 | if (strcmp(name, "") == 0) | 31 | if (strcmp(name, "") == 0) |
| 30 | return -EINVAL; | 32 | return -EINVAL; |
| @@ -33,8 +35,9 @@ ext2_xattr_security_get(struct dentry *dentry, const char *name, | |||
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | static int | 37 | static int |
| 36 | ext2_xattr_security_set(struct dentry *dentry, const char *name, | 38 | ext2_xattr_security_set(const struct xattr_handler *handler, |
| 37 | const void *value, size_t size, int flags, int type) | 39 | struct dentry *dentry, const char *name, |
| 40 | const void *value, size_t size, int flags) | ||
| 38 | { | 41 | { |
| 39 | if (strcmp(name, "") == 0) | 42 | if (strcmp(name, "") == 0) |
| 40 | return -EINVAL; | 43 | return -EINVAL; |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 42b6e9874bcc..3150dd3a7859 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
| @@ -9,8 +9,9 @@ | |||
| 9 | #include "xattr.h" | 9 | #include "xattr.h" |
| 10 | 10 | ||
| 11 | static size_t | 11 | static size_t |
| 12 | ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, | 12 | ext2_xattr_trusted_list(const struct xattr_handler *handler, |
| 13 | const char *name, size_t name_len, int type) | 13 | struct dentry *dentry, char *list, size_t list_size, |
| 14 | const char *name, size_t name_len) | ||
| 14 | { | 15 | { |
| 15 | const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; | 16 | const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; |
| 16 | const size_t total_len = prefix_len + name_len + 1; | 17 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -27,8 +28,9 @@ ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | static int | 30 | static int |
| 30 | ext2_xattr_trusted_get(struct dentry *dentry, const char *name, | 31 | ext2_xattr_trusted_get(const struct xattr_handler *handler, |
| 31 | void *buffer, size_t size, int type) | 32 | struct dentry *dentry, const char *name, |
| 33 | void *buffer, size_t size) | ||
| 32 | { | 34 | { |
| 33 | if (strcmp(name, "") == 0) | 35 | if (strcmp(name, "") == 0) |
| 34 | return -EINVAL; | 36 | return -EINVAL; |
| @@ -37,8 +39,9 @@ ext2_xattr_trusted_get(struct dentry *dentry, const char *name, | |||
| 37 | } | 39 | } |
| 38 | 40 | ||
| 39 | static int | 41 | static int |
| 40 | ext2_xattr_trusted_set(struct dentry *dentry, const char *name, | 42 | ext2_xattr_trusted_set(const struct xattr_handler *handler, |
| 41 | const void *value, size_t size, int flags, int type) | 43 | struct dentry *dentry, const char *name, |
| 44 | const void *value, size_t size, int flags) | ||
| 42 | { | 45 | { |
| 43 | if (strcmp(name, "") == 0) | 46 | if (strcmp(name, "") == 0) |
| 44 | return -EINVAL; | 47 | return -EINVAL; |
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index ecdc4605192c..339a49bbb8ef 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
| @@ -11,8 +11,9 @@ | |||
| 11 | #include "xattr.h" | 11 | #include "xattr.h" |
| 12 | 12 | ||
| 13 | static size_t | 13 | static size_t |
| 14 | ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, | 14 | ext2_xattr_user_list(const struct xattr_handler *handler, |
| 15 | const char *name, size_t name_len, int type) | 15 | struct dentry *dentry, char *list, size_t list_size, |
| 16 | const char *name, size_t name_len) | ||
| 16 | { | 17 | { |
| 17 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; | 18 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; |
| 18 | const size_t total_len = prefix_len + name_len + 1; | 19 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -29,8 +30,9 @@ ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | static int | 32 | static int |
| 32 | ext2_xattr_user_get(struct dentry *dentry, const char *name, | 33 | ext2_xattr_user_get(const struct xattr_handler *handler, |
| 33 | void *buffer, size_t size, int type) | 34 | struct dentry *dentry, const char *name, |
| 35 | void *buffer, size_t size) | ||
| 34 | { | 36 | { |
| 35 | if (strcmp(name, "") == 0) | 37 | if (strcmp(name, "") == 0) |
| 36 | return -EINVAL; | 38 | return -EINVAL; |
| @@ -41,8 +43,9 @@ ext2_xattr_user_get(struct dentry *dentry, const char *name, | |||
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | static int | 45 | static int |
| 44 | ext2_xattr_user_set(struct dentry *dentry, const char *name, | 46 | ext2_xattr_user_set(const struct xattr_handler *handler, |
| 45 | const void *value, size_t size, int flags, int type) | 47 | struct dentry *dentry, const char *name, |
| 48 | const void *value, size_t size, int flags) | ||
| 46 | { | 49 | { |
| 47 | if (strcmp(name, "") == 0) | 50 | if (strcmp(name, "") == 0) |
| 48 | return -EINVAL; | 51 | return -EINVAL; |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 984448c6f5f0..6b6b3e751f8c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -405,10 +405,9 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, | |||
| 405 | ext4_xattr_handler(entry->e_name_index); | 405 | ext4_xattr_handler(entry->e_name_index); |
| 406 | 406 | ||
| 407 | if (handler) { | 407 | if (handler) { |
| 408 | size_t size = handler->list(dentry, buffer, rest, | 408 | size_t size = handler->list(handler, dentry, buffer, |
| 409 | entry->e_name, | 409 | rest, entry->e_name, |
| 410 | entry->e_name_len, | 410 | entry->e_name_len); |
| 411 | handler->flags); | ||
| 412 | if (buffer) { | 411 | if (buffer) { |
| 413 | if (size > rest) | 412 | if (size > rest) |
| 414 | return -ERANGE; | 413 | return -ERANGE; |
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 95d90e0560f0..36f4c1a84c21 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c | |||
| @@ -12,8 +12,9 @@ | |||
| 12 | #include "xattr.h" | 12 | #include "xattr.h" |
| 13 | 13 | ||
| 14 | static size_t | 14 | static size_t |
| 15 | ext4_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, | 15 | ext4_xattr_security_list(const struct xattr_handler *handler, |
| 16 | const char *name, size_t name_len, int type) | 16 | struct dentry *dentry, char *list, size_t list_size, |
| 17 | const char *name, size_t name_len) | ||
| 17 | { | 18 | { |
| 18 | const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1; | 19 | const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1; |
| 19 | const size_t total_len = prefix_len + name_len + 1; | 20 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -28,8 +29,9 @@ ext4_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 28 | } | 29 | } |
| 29 | 30 | ||
| 30 | static int | 31 | static int |
| 31 | ext4_xattr_security_get(struct dentry *dentry, const char *name, | 32 | ext4_xattr_security_get(const struct xattr_handler *handler, |
| 32 | void *buffer, size_t size, int type) | 33 | struct dentry *dentry, const char *name, |
| 34 | void *buffer, size_t size) | ||
| 33 | { | 35 | { |
| 34 | if (strcmp(name, "") == 0) | 36 | if (strcmp(name, "") == 0) |
| 35 | return -EINVAL; | 37 | return -EINVAL; |
| @@ -38,8 +40,9 @@ ext4_xattr_security_get(struct dentry *dentry, const char *name, | |||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | static int | 42 | static int |
| 41 | ext4_xattr_security_set(struct dentry *dentry, const char *name, | 43 | ext4_xattr_security_set(const struct xattr_handler *handler, |
| 42 | const void *value, size_t size, int flags, int type) | 44 | struct dentry *dentry, const char *name, |
| 45 | const void *value, size_t size, int flags) | ||
| 43 | { | 46 | { |
| 44 | if (strcmp(name, "") == 0) | 47 | if (strcmp(name, "") == 0) |
| 45 | return -EINVAL; | 48 | return -EINVAL; |
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index 891ee2ddfbd6..488089053342 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c | |||
| @@ -13,8 +13,9 @@ | |||
| 13 | #include "xattr.h" | 13 | #include "xattr.h" |
| 14 | 14 | ||
| 15 | static size_t | 15 | static size_t |
| 16 | ext4_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, | 16 | ext4_xattr_trusted_list(const struct xattr_handler *handler, |
| 17 | const char *name, size_t name_len, int type) | 17 | struct dentry *dentry, char *list, size_t list_size, |
| 18 | const char *name, size_t name_len) | ||
| 18 | { | 19 | { |
| 19 | const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; | 20 | const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; |
| 20 | const size_t total_len = prefix_len + name_len + 1; | 21 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -31,8 +32,9 @@ ext4_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | static int | 34 | static int |
| 34 | ext4_xattr_trusted_get(struct dentry *dentry, const char *name, void *buffer, | 35 | ext4_xattr_trusted_get(const struct xattr_handler *handler, |
| 35 | size_t size, int type) | 36 | struct dentry *dentry, const char *name, void *buffer, |
| 37 | size_t size) | ||
| 36 | { | 38 | { |
| 37 | if (strcmp(name, "") == 0) | 39 | if (strcmp(name, "") == 0) |
| 38 | return -EINVAL; | 40 | return -EINVAL; |
| @@ -41,8 +43,9 @@ ext4_xattr_trusted_get(struct dentry *dentry, const char *name, void *buffer, | |||
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | static int | 45 | static int |
| 44 | ext4_xattr_trusted_set(struct dentry *dentry, const char *name, | 46 | ext4_xattr_trusted_set(const struct xattr_handler *handler, |
| 45 | const void *value, size_t size, int flags, int type) | 47 | struct dentry *dentry, const char *name, |
| 48 | const void *value, size_t size, int flags) | ||
| 46 | { | 49 | { |
| 47 | if (strcmp(name, "") == 0) | 50 | if (strcmp(name, "") == 0) |
| 48 | return -EINVAL; | 51 | return -EINVAL; |
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index 6ed932b3c043..d2dec3364062 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c | |||
| @@ -12,8 +12,9 @@ | |||
| 12 | #include "xattr.h" | 12 | #include "xattr.h" |
| 13 | 13 | ||
| 14 | static size_t | 14 | static size_t |
| 15 | ext4_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, | 15 | ext4_xattr_user_list(const struct xattr_handler *handler, |
| 16 | const char *name, size_t name_len, int type) | 16 | struct dentry *dentry, char *list, size_t list_size, |
| 17 | const char *name, size_t name_len) | ||
| 17 | { | 18 | { |
| 18 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; | 19 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; |
| 19 | const size_t total_len = prefix_len + name_len + 1; | 20 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -30,8 +31,9 @@ ext4_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, | |||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | static int | 33 | static int |
| 33 | ext4_xattr_user_get(struct dentry *dentry, const char *name, | 34 | ext4_xattr_user_get(const struct xattr_handler *handler, |
| 34 | void *buffer, size_t size, int type) | 35 | struct dentry *dentry, const char *name, |
| 36 | void *buffer, size_t size) | ||
| 35 | { | 37 | { |
| 36 | if (strcmp(name, "") == 0) | 38 | if (strcmp(name, "") == 0) |
| 37 | return -EINVAL; | 39 | return -EINVAL; |
| @@ -42,8 +44,9 @@ ext4_xattr_user_get(struct dentry *dentry, const char *name, | |||
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | static int | 46 | static int |
| 45 | ext4_xattr_user_set(struct dentry *dentry, const char *name, | 47 | ext4_xattr_user_set(const struct xattr_handler *handler, |
| 46 | const void *value, size_t size, int flags, int type) | 48 | struct dentry *dentry, const char *name, |
| 49 | const void *value, size_t size, int flags) | ||
| 47 | { | 50 | { |
| 48 | if (strcmp(name, "") == 0) | 51 | if (strcmp(name, "") == 0) |
| 49 | return -EINVAL; | 52 | return -EINVAL; |
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 4de2286c0e4d..862368a32e53 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c | |||
| @@ -25,49 +25,45 @@ | |||
| 25 | #include "f2fs.h" | 25 | #include "f2fs.h" |
| 26 | #include "xattr.h" | 26 | #include "xattr.h" |
| 27 | 27 | ||
| 28 | static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, | 28 | static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler, |
| 29 | size_t list_size, const char *name, size_t len, int type) | 29 | struct dentry *dentry, char *list, size_t list_size, |
| 30 | const char *name, size_t len) | ||
| 30 | { | 31 | { |
| 31 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); | 32 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); |
| 32 | int total_len, prefix_len = 0; | 33 | int total_len, prefix_len; |
| 33 | const char *prefix = NULL; | ||
| 34 | 34 | ||
| 35 | switch (type) { | 35 | switch (handler->flags) { |
| 36 | case F2FS_XATTR_INDEX_USER: | 36 | case F2FS_XATTR_INDEX_USER: |
| 37 | if (!test_opt(sbi, XATTR_USER)) | 37 | if (!test_opt(sbi, XATTR_USER)) |
| 38 | return -EOPNOTSUPP; | 38 | return -EOPNOTSUPP; |
| 39 | prefix = XATTR_USER_PREFIX; | ||
| 40 | prefix_len = XATTR_USER_PREFIX_LEN; | ||
| 41 | break; | 39 | break; |
| 42 | case F2FS_XATTR_INDEX_TRUSTED: | 40 | case F2FS_XATTR_INDEX_TRUSTED: |
| 43 | if (!capable(CAP_SYS_ADMIN)) | 41 | if (!capable(CAP_SYS_ADMIN)) |
| 44 | return -EPERM; | 42 | return -EPERM; |
| 45 | prefix = XATTR_TRUSTED_PREFIX; | ||
| 46 | prefix_len = XATTR_TRUSTED_PREFIX_LEN; | ||
| 47 | break; | 43 | break; |
| 48 | case F2FS_XATTR_INDEX_SECURITY: | 44 | case F2FS_XATTR_INDEX_SECURITY: |
| 49 | prefix = XATTR_SECURITY_PREFIX; | ||
| 50 | prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
| 51 | break; | 45 | break; |
| 52 | default: | 46 | default: |
| 53 | return -EINVAL; | 47 | return -EINVAL; |
| 54 | } | 48 | } |
| 55 | 49 | ||
| 50 | prefix_len = strlen(handler->prefix); | ||
| 56 | total_len = prefix_len + len + 1; | 51 | total_len = prefix_len + len + 1; |
| 57 | if (list && total_len <= list_size) { | 52 | if (list && total_len <= list_size) { |
| 58 | memcpy(list, prefix, prefix_len); | 53 | memcpy(list, handler->prefix, prefix_len); |
| 59 | memcpy(list + prefix_len, name, len); | 54 | memcpy(list + prefix_len, name, len); |
| 60 | list[prefix_len + len] = '\0'; | 55 | list[prefix_len + len] = '\0'; |
| 61 | } | 56 | } |
| 62 | return total_len; | 57 | return total_len; |
| 63 | } | 58 | } |
| 64 | 59 | ||
| 65 | static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, | 60 | static int f2fs_xattr_generic_get(const struct xattr_handler *handler, |
| 66 | void *buffer, size_t size, int type) | 61 | struct dentry *dentry, const char *name, void *buffer, |
| 62 | size_t size) | ||
| 67 | { | 63 | { |
| 68 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); | 64 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); |
| 69 | 65 | ||
| 70 | switch (type) { | 66 | switch (handler->flags) { |
| 71 | case F2FS_XATTR_INDEX_USER: | 67 | case F2FS_XATTR_INDEX_USER: |
| 72 | if (!test_opt(sbi, XATTR_USER)) | 68 | if (!test_opt(sbi, XATTR_USER)) |
| 73 | return -EOPNOTSUPP; | 69 | return -EOPNOTSUPP; |
| @@ -83,15 +79,17 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, | |||
| 83 | } | 79 | } |
| 84 | if (strcmp(name, "") == 0) | 80 | if (strcmp(name, "") == 0) |
| 85 | return -EINVAL; | 81 | return -EINVAL; |
| 86 | return f2fs_getxattr(d_inode(dentry), type, name, buffer, size, NULL); | 82 | return f2fs_getxattr(d_inode(dentry), handler->flags, name, |
| 83 | buffer, size, NULL); | ||
| 87 | } | 84 | } |
| 88 | 85 | ||
| 89 | static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, | 86 | static int f2fs_xattr_generic_set(const struct xattr_handler *handler, |
| 90 | const void *value, size_t size, int flags, int type) | 87 | struct dentry *dentry, const char *name, const void *value, |
| 88 | size_t size, int flags) | ||
| 91 | { | 89 | { |
| 92 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); | 90 | struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); |
| 93 | 91 | ||
| 94 | switch (type) { | 92 | switch (handler->flags) { |
| 95 | case F2FS_XATTR_INDEX_USER: | 93 | case F2FS_XATTR_INDEX_USER: |
| 96 | if (!test_opt(sbi, XATTR_USER)) | 94 | if (!test_opt(sbi, XATTR_USER)) |
| 97 | return -EOPNOTSUPP; | 95 | return -EOPNOTSUPP; |
| @@ -108,27 +106,26 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, | |||
| 108 | if (strcmp(name, "") == 0) | 106 | if (strcmp(name, "") == 0) |
| 109 | return -EINVAL; | 107 | return -EINVAL; |
| 110 | 108 | ||
| 111 | return f2fs_setxattr(d_inode(dentry), type, name, | 109 | return f2fs_setxattr(d_inode(dentry), handler->flags, name, |
| 112 | value, size, NULL, flags); | 110 | value, size, NULL, flags); |
| 113 | } | 111 | } |
| 114 | 112 | ||
| 115 | static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, | 113 | static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, |
| 116 | size_t list_size, const char *name, size_t len, int type) | 114 | struct dentry *dentry, char *list, size_t list_size, |
| 115 | const char *name, size_t len) | ||
| 117 | { | 116 | { |
| 118 | const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; | 117 | const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; |
| 119 | size_t size; | 118 | size_t size; |
| 120 | 119 | ||
| 121 | if (type != F2FS_XATTR_INDEX_ADVISE) | ||
| 122 | return 0; | ||
| 123 | |||
| 124 | size = strlen(xname) + 1; | 120 | size = strlen(xname) + 1; |
| 125 | if (list && size <= list_size) | 121 | if (list && size <= list_size) |
| 126 | memcpy(list, xname, size); | 122 | memcpy(list, xname, size); |
| 127 | return size; | 123 | return size; |
| 128 | } | 124 | } |
| 129 | 125 | ||
| 130 | static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name, | 126 | static int f2fs_xattr_advise_get(const struct xattr_handler *handler, |
| 131 | void *buffer, size_t size, int type) | 127 | struct dentry *dentry, const char *name, void *buffer, |
| 128 | size_t size) | ||
| 132 | { | 129 | { |
| 133 | struct inode *inode = d_inode(dentry); | 130 | struct inode *inode = d_inode(dentry); |
| 134 | 131 | ||
| @@ -140,8 +137,9 @@ static int f2fs_xattr_advise_get(struct dentry *dentry, const char *name, | |||
| 140 | return sizeof(char); | 137 | return sizeof(char); |
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, | 140 | static int f2fs_xattr_advise_set(const struct xattr_handler *handler, |
| 144 | const void *value, size_t size, int flags, int type) | 141 | struct dentry *dentry, const char *name, const void *value, |
| 142 | size_t size, int flags) | ||
| 145 | { | 143 | { |
| 146 | struct inode *inode = d_inode(dentry); | 144 | struct inode *inode = d_inode(dentry); |
| 147 | 145 | ||
| @@ -462,8 +460,8 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
| 462 | if (!handler) | 460 | if (!handler) |
| 463 | continue; | 461 | continue; |
| 464 | 462 | ||
| 465 | size = handler->list(dentry, buffer, rest, entry->e_name, | 463 | size = handler->list(handler, dentry, buffer, rest, |
| 466 | entry->e_name_len, handler->flags); | 464 | entry->e_name, entry->e_name_len); |
| 467 | if (buffer && size > rest) { | 465 | if (buffer && size > rest) { |
| 468 | error = -ERANGE; | 466 | error = -ERANGE; |
| 469 | goto cleanup; | 467 | goto cleanup; |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 4c096fa9e2a1..53ce76a374fe 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
| @@ -583,11 +583,13 @@ out: | |||
| 583 | * | 583 | * |
| 584 | * Returns: actual size of data on success, -errno on error | 584 | * Returns: actual size of data on success, -errno on error |
| 585 | */ | 585 | */ |
| 586 | static int gfs2_xattr_get(struct dentry *dentry, const char *name, | 586 | static int gfs2_xattr_get(const struct xattr_handler *handler, |
| 587 | void *buffer, size_t size, int type) | 587 | struct dentry *dentry, const char *name, |
| 588 | void *buffer, size_t size) | ||
| 588 | { | 589 | { |
| 589 | struct gfs2_inode *ip = GFS2_I(d_inode(dentry)); | 590 | struct gfs2_inode *ip = GFS2_I(d_inode(dentry)); |
| 590 | struct gfs2_ea_location el; | 591 | struct gfs2_ea_location el; |
| 592 | int type = handler->flags; | ||
| 591 | int error; | 593 | int error; |
| 592 | 594 | ||
| 593 | if (!ip->i_eattr) | 595 | if (!ip->i_eattr) |
| @@ -1227,11 +1229,12 @@ int __gfs2_xattr_set(struct inode *inode, const char *name, | |||
| 1227 | return error; | 1229 | return error; |
| 1228 | } | 1230 | } |
| 1229 | 1231 | ||
| 1230 | static int gfs2_xattr_set(struct dentry *dentry, const char *name, | 1232 | static int gfs2_xattr_set(const struct xattr_handler *handler, |
| 1231 | const void *value, size_t size, int flags, int type) | 1233 | struct dentry *dentry, const char *name, |
| 1234 | const void *value, size_t size, int flags) | ||
| 1232 | { | 1235 | { |
| 1233 | return __gfs2_xattr_set(d_inode(dentry), name, value, | 1236 | return __gfs2_xattr_set(d_inode(dentry), name, value, |
| 1234 | size, flags, type); | 1237 | size, flags, handler->flags); |
| 1235 | } | 1238 | } |
| 1236 | 1239 | ||
| 1237 | 1240 | ||
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c index 416b1dbafe51..e41a010cd89c 100644 --- a/fs/hfsplus/xattr.c +++ b/fs/hfsplus/xattr.c | |||
| @@ -849,8 +849,9 @@ end_removexattr: | |||
| 849 | return err; | 849 | return err; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, | 852 | static int hfsplus_osx_getxattr(const struct xattr_handler *handler, |
| 853 | void *buffer, size_t size, int type) | 853 | struct dentry *dentry, const char *name, |
| 854 | void *buffer, size_t size) | ||
| 854 | { | 855 | { |
| 855 | if (!strcmp(name, "")) | 856 | if (!strcmp(name, "")) |
| 856 | return -EINVAL; | 857 | return -EINVAL; |
| @@ -871,8 +872,9 @@ static int hfsplus_osx_getxattr(struct dentry *dentry, const char *name, | |||
| 871 | return __hfsplus_getxattr(d_inode(dentry), name, buffer, size); | 872 | return __hfsplus_getxattr(d_inode(dentry), name, buffer, size); |
| 872 | } | 873 | } |
| 873 | 874 | ||
| 874 | static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, | 875 | static int hfsplus_osx_setxattr(const struct xattr_handler *handler, |
| 875 | const void *buffer, size_t size, int flags, int type) | 876 | struct dentry *dentry, const char *name, |
| 877 | const void *buffer, size_t size, int flags) | ||
| 876 | { | 878 | { |
| 877 | if (!strcmp(name, "")) | 879 | if (!strcmp(name, "")) |
| 878 | return -EINVAL; | 880 | return -EINVAL; |
| @@ -893,19 +895,8 @@ static int hfsplus_osx_setxattr(struct dentry *dentry, const char *name, | |||
| 893 | return __hfsplus_setxattr(d_inode(dentry), name, buffer, size, flags); | 895 | return __hfsplus_setxattr(d_inode(dentry), name, buffer, size, flags); |
| 894 | } | 896 | } |
| 895 | 897 | ||
| 896 | static size_t hfsplus_osx_listxattr(struct dentry *dentry, char *list, | ||
| 897 | size_t list_size, const char *name, size_t name_len, int type) | ||
| 898 | { | ||
| 899 | /* | ||
| 900 | * This method is not used. | ||
| 901 | * It is used hfsplus_listxattr() instead of generic_listxattr(). | ||
| 902 | */ | ||
| 903 | return -EOPNOTSUPP; | ||
| 904 | } | ||
| 905 | |||
| 906 | const struct xattr_handler hfsplus_xattr_osx_handler = { | 898 | const struct xattr_handler hfsplus_xattr_osx_handler = { |
| 907 | .prefix = XATTR_MAC_OSX_PREFIX, | 899 | .prefix = XATTR_MAC_OSX_PREFIX, |
| 908 | .list = hfsplus_osx_listxattr, | ||
| 909 | .get = hfsplus_osx_getxattr, | 900 | .get = hfsplus_osx_getxattr, |
| 910 | .set = hfsplus_osx_setxattr, | 901 | .set = hfsplus_osx_setxattr, |
| 911 | }; | 902 | }; |
diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c index aacff00a9ff9..72a68a3a0c99 100644 --- a/fs/hfsplus/xattr_security.c +++ b/fs/hfsplus/xattr_security.c | |||
| @@ -13,32 +13,24 @@ | |||
| 13 | #include "xattr.h" | 13 | #include "xattr.h" |
| 14 | #include "acl.h" | 14 | #include "acl.h" |
| 15 | 15 | ||
| 16 | static int hfsplus_security_getxattr(struct dentry *dentry, const char *name, | 16 | static int hfsplus_security_getxattr(const struct xattr_handler *handler, |
| 17 | void *buffer, size_t size, int type) | 17 | struct dentry *dentry, const char *name, |
| 18 | void *buffer, size_t size) | ||
| 18 | { | 19 | { |
| 19 | return hfsplus_getxattr(dentry, name, buffer, size, | 20 | return hfsplus_getxattr(dentry, name, buffer, size, |
| 20 | XATTR_SECURITY_PREFIX, | 21 | XATTR_SECURITY_PREFIX, |
| 21 | XATTR_SECURITY_PREFIX_LEN); | 22 | XATTR_SECURITY_PREFIX_LEN); |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | static int hfsplus_security_setxattr(struct dentry *dentry, const char *name, | 25 | static int hfsplus_security_setxattr(const struct xattr_handler *handler, |
| 25 | const void *buffer, size_t size, int flags, int type) | 26 | struct dentry *dentry, const char *name, |
| 27 | const void *buffer, size_t size, int flags) | ||
| 26 | { | 28 | { |
| 27 | return hfsplus_setxattr(dentry, name, buffer, size, flags, | 29 | return hfsplus_setxattr(dentry, name, buffer, size, flags, |
| 28 | XATTR_SECURITY_PREFIX, | 30 | XATTR_SECURITY_PREFIX, |
| 29 | XATTR_SECURITY_PREFIX_LEN); | 31 | XATTR_SECURITY_PREFIX_LEN); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list, | ||
| 33 | size_t list_size, const char *name, size_t name_len, int type) | ||
| 34 | { | ||
| 35 | /* | ||
| 36 | * This method is not used. | ||
| 37 | * It is used hfsplus_listxattr() instead of generic_listxattr(). | ||
| 38 | */ | ||
| 39 | return -EOPNOTSUPP; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int hfsplus_initxattrs(struct inode *inode, | 34 | static int hfsplus_initxattrs(struct inode *inode, |
| 43 | const struct xattr *xattr_array, | 35 | const struct xattr *xattr_array, |
| 44 | void *fs_info) | 36 | void *fs_info) |
| @@ -92,7 +84,6 @@ int hfsplus_init_inode_security(struct inode *inode, | |||
| 92 | 84 | ||
| 93 | const struct xattr_handler hfsplus_xattr_security_handler = { | 85 | const struct xattr_handler hfsplus_xattr_security_handler = { |
| 94 | .prefix = XATTR_SECURITY_PREFIX, | 86 | .prefix = XATTR_SECURITY_PREFIX, |
| 95 | .list = hfsplus_security_listxattr, | ||
| 96 | .get = hfsplus_security_getxattr, | 87 | .get = hfsplus_security_getxattr, |
| 97 | .set = hfsplus_security_setxattr, | 88 | .set = hfsplus_security_setxattr, |
| 98 | }; | 89 | }; |
diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c index bcf65089b7f7..95a7704c7abb 100644 --- a/fs/hfsplus/xattr_trusted.c +++ b/fs/hfsplus/xattr_trusted.c | |||
| @@ -11,34 +11,25 @@ | |||
| 11 | #include "hfsplus_fs.h" | 11 | #include "hfsplus_fs.h" |
| 12 | #include "xattr.h" | 12 | #include "xattr.h" |
| 13 | 13 | ||
| 14 | static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name, | 14 | static int hfsplus_trusted_getxattr(const struct xattr_handler *handler, |
| 15 | void *buffer, size_t size, int type) | 15 | struct dentry *dentry, const char *name, |
| 16 | void *buffer, size_t size) | ||
| 16 | { | 17 | { |
| 17 | return hfsplus_getxattr(dentry, name, buffer, size, | 18 | return hfsplus_getxattr(dentry, name, buffer, size, |
| 18 | XATTR_TRUSTED_PREFIX, | 19 | XATTR_TRUSTED_PREFIX, |
| 19 | XATTR_TRUSTED_PREFIX_LEN); | 20 | XATTR_TRUSTED_PREFIX_LEN); |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name, | 23 | static int hfsplus_trusted_setxattr(const struct xattr_handler *handler, |
| 23 | const void *buffer, size_t size, int flags, int type) | 24 | struct dentry *dentry, const char *name, |
| 25 | const void *buffer, size_t size, int flags) | ||
| 24 | { | 26 | { |
| 25 | return hfsplus_setxattr(dentry, name, buffer, size, flags, | 27 | return hfsplus_setxattr(dentry, name, buffer, size, flags, |
| 26 | XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); | 28 | XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); |
| 27 | } | 29 | } |
| 28 | 30 | ||
| 29 | static size_t hfsplus_trusted_listxattr(struct dentry *dentry, char *list, | ||
| 30 | size_t list_size, const char *name, size_t name_len, int type) | ||
| 31 | { | ||
| 32 | /* | ||
| 33 | * This method is not used. | ||
| 34 | * It is used hfsplus_listxattr() instead of generic_listxattr(). | ||
| 35 | */ | ||
| 36 | return -EOPNOTSUPP; | ||
| 37 | } | ||
| 38 | |||
| 39 | const struct xattr_handler hfsplus_xattr_trusted_handler = { | 31 | const struct xattr_handler hfsplus_xattr_trusted_handler = { |
| 40 | .prefix = XATTR_TRUSTED_PREFIX, | 32 | .prefix = XATTR_TRUSTED_PREFIX, |
| 41 | .list = hfsplus_trusted_listxattr, | ||
| 42 | .get = hfsplus_trusted_getxattr, | 33 | .get = hfsplus_trusted_getxattr, |
| 43 | .set = hfsplus_trusted_setxattr, | 34 | .set = hfsplus_trusted_setxattr, |
| 44 | }; | 35 | }; |
diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c index 5aa0e6dc4a1e..6fc269baf959 100644 --- a/fs/hfsplus/xattr_user.c +++ b/fs/hfsplus/xattr_user.c | |||
| @@ -11,34 +11,25 @@ | |||
| 11 | #include "hfsplus_fs.h" | 11 | #include "hfsplus_fs.h" |
| 12 | #include "xattr.h" | 12 | #include "xattr.h" |
| 13 | 13 | ||
| 14 | static int hfsplus_user_getxattr(struct dentry *dentry, const char *name, | 14 | static int hfsplus_user_getxattr(const struct xattr_handler *handler, |
| 15 | void *buffer, size_t size, int type) | 15 | struct dentry *dentry, const char *name, |
| 16 | void *buffer, size_t size) | ||
| 16 | { | 17 | { |
| 17 | 18 | ||
| 18 | return hfsplus_getxattr(dentry, name, buffer, size, | 19 | return hfsplus_getxattr(dentry, name, buffer, size, |
| 19 | XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); | 20 | XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | static int hfsplus_user_setxattr(struct dentry *dentry, const char *name, | 23 | static int hfsplus_user_setxattr(const struct xattr_handler *handler, |
| 23 | const void *buffer, size_t size, int flags, int type) | 24 | struct dentry *dentry, const char *name, |
| 25 | const void *buffer, size_t size, int flags) | ||
| 24 | { | 26 | { |
| 25 | return hfsplus_setxattr(dentry, name, buffer, size, flags, | 27 | return hfsplus_setxattr(dentry, name, buffer, size, flags, |
| 26 | XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); | 28 | XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); |
| 27 | } | 29 | } |
| 28 | 30 | ||
| 29 | static size_t hfsplus_user_listxattr(struct dentry *dentry, char *list, | ||
| 30 | size_t list_size, const char *name, size_t name_len, int type) | ||
| 31 | { | ||
| 32 | /* | ||
| 33 | * This method is not used. | ||
| 34 | * It is used hfsplus_listxattr() instead of generic_listxattr(). | ||
| 35 | */ | ||
| 36 | return -EOPNOTSUPP; | ||
| 37 | } | ||
| 38 | |||
| 39 | const struct xattr_handler hfsplus_xattr_user_handler = { | 31 | const struct xattr_handler hfsplus_xattr_user_handler = { |
| 40 | .prefix = XATTR_USER_PREFIX, | 32 | .prefix = XATTR_USER_PREFIX, |
| 41 | .list = hfsplus_user_listxattr, | ||
| 42 | .get = hfsplus_user_getxattr, | 33 | .get = hfsplus_user_getxattr, |
| 43 | .set = hfsplus_user_setxattr, | 34 | .set = hfsplus_user_setxattr, |
| 44 | }; | 35 | }; |
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index d4b43fb7adb1..bf12fe5f83d7 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
| @@ -48,8 +48,9 @@ int jffs2_init_security(struct inode *inode, struct inode *dir, | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | /* ---- XATTR Handler for "security.*" ----------------- */ | 50 | /* ---- XATTR Handler for "security.*" ----------------- */ |
| 51 | static int jffs2_security_getxattr(struct dentry *dentry, const char *name, | 51 | static int jffs2_security_getxattr(const struct xattr_handler *handler, |
| 52 | void *buffer, size_t size, int type) | 52 | struct dentry *dentry, const char *name, |
| 53 | void *buffer, size_t size) | ||
| 53 | { | 54 | { |
| 54 | if (!strcmp(name, "")) | 55 | if (!strcmp(name, "")) |
| 55 | return -EINVAL; | 56 | return -EINVAL; |
| @@ -58,8 +59,9 @@ static int jffs2_security_getxattr(struct dentry *dentry, const char *name, | |||
| 58 | name, buffer, size); | 59 | name, buffer, size); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static int jffs2_security_setxattr(struct dentry *dentry, const char *name, | 62 | static int jffs2_security_setxattr(const struct xattr_handler *handler, |
| 62 | const void *buffer, size_t size, int flags, int type) | 63 | struct dentry *dentry, const char *name, |
| 64 | const void *buffer, size_t size, int flags) | ||
| 63 | { | 65 | { |
| 64 | if (!strcmp(name, "")) | 66 | if (!strcmp(name, "")) |
| 65 | return -EINVAL; | 67 | return -EINVAL; |
| @@ -68,8 +70,10 @@ static int jffs2_security_setxattr(struct dentry *dentry, const char *name, | |||
| 68 | name, buffer, size, flags); | 70 | name, buffer, size, flags); |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | static size_t jffs2_security_listxattr(struct dentry *dentry, char *list, | 73 | static size_t jffs2_security_listxattr(const struct xattr_handler *handler, |
| 72 | size_t list_size, const char *name, size_t name_len, int type) | 74 | struct dentry *dentry, char *list, |
| 75 | size_t list_size, const char *name, | ||
| 76 | size_t name_len) | ||
| 73 | { | 77 | { |
| 74 | size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1; | 78 | size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1; |
| 75 | 79 | ||
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index f092fee5be50..4c2c03663533 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
| @@ -1001,11 +1001,12 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 1001 | if (!xhandle) | 1001 | if (!xhandle) |
| 1002 | continue; | 1002 | continue; |
| 1003 | if (buffer) { | 1003 | if (buffer) { |
| 1004 | rc = xhandle->list(dentry, buffer+len, size-len, | 1004 | rc = xhandle->list(xhandle, dentry, buffer + len, |
| 1005 | xd->xname, xd->name_len, xd->flags); | 1005 | size - len, xd->xname, |
| 1006 | xd->name_len); | ||
| 1006 | } else { | 1007 | } else { |
| 1007 | rc = xhandle->list(dentry, NULL, 0, xd->xname, | 1008 | rc = xhandle->list(xhandle, dentry, NULL, 0, |
| 1008 | xd->name_len, xd->flags); | 1009 | xd->xname, xd->name_len); |
| 1009 | } | 1010 | } |
| 1010 | if (rc < 0) | 1011 | if (rc < 0) |
| 1011 | goto out; | 1012 | goto out; |
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index ceaf9c693225..a562da0d6a26 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c | |||
| @@ -16,8 +16,9 @@ | |||
| 16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
| 17 | #include "nodelist.h" | 17 | #include "nodelist.h" |
| 18 | 18 | ||
| 19 | static int jffs2_trusted_getxattr(struct dentry *dentry, const char *name, | 19 | static int jffs2_trusted_getxattr(const struct xattr_handler *handler, |
| 20 | void *buffer, size_t size, int type) | 20 | struct dentry *dentry, const char *name, |
| 21 | void *buffer, size_t size) | ||
| 21 | { | 22 | { |
| 22 | if (!strcmp(name, "")) | 23 | if (!strcmp(name, "")) |
| 23 | return -EINVAL; | 24 | return -EINVAL; |
| @@ -25,8 +26,9 @@ static int jffs2_trusted_getxattr(struct dentry *dentry, const char *name, | |||
| 25 | name, buffer, size); | 26 | name, buffer, size); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | static int jffs2_trusted_setxattr(struct dentry *dentry, const char *name, | 29 | static int jffs2_trusted_setxattr(const struct xattr_handler *handler, |
| 29 | const void *buffer, size_t size, int flags, int type) | 30 | struct dentry *dentry, const char *name, |
| 31 | const void *buffer, size_t size, int flags) | ||
| 30 | { | 32 | { |
| 31 | if (!strcmp(name, "")) | 33 | if (!strcmp(name, "")) |
| 32 | return -EINVAL; | 34 | return -EINVAL; |
| @@ -34,11 +36,16 @@ static int jffs2_trusted_setxattr(struct dentry *dentry, const char *name, | |||
| 34 | name, buffer, size, flags); | 36 | name, buffer, size, flags); |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | static size_t jffs2_trusted_listxattr(struct dentry *dentry, char *list, | 39 | static size_t jffs2_trusted_listxattr(const struct xattr_handler *handler, |
| 38 | size_t list_size, const char *name, size_t name_len, int type) | 40 | struct dentry *dentry, char *list, |
| 41 | size_t list_size, const char *name, | ||
| 42 | size_t name_len) | ||
| 39 | { | 43 | { |
| 40 | size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; | 44 | size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; |
| 41 | 45 | ||
| 46 | if (!capable(CAP_SYS_ADMIN)) | ||
| 47 | return 0; | ||
| 48 | |||
| 42 | if (list && retlen<=list_size) { | 49 | if (list && retlen<=list_size) { |
| 43 | strcpy(list, XATTR_TRUSTED_PREFIX); | 50 | strcpy(list, XATTR_TRUSTED_PREFIX); |
| 44 | strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name); | 51 | strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name); |
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index a71391eba514..cbc0472e59a8 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c | |||
| @@ -16,8 +16,9 @@ | |||
| 16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
| 17 | #include "nodelist.h" | 17 | #include "nodelist.h" |
| 18 | 18 | ||
| 19 | static int jffs2_user_getxattr(struct dentry *dentry, const char *name, | 19 | static int jffs2_user_getxattr(const struct xattr_handler *handler, |
| 20 | void *buffer, size_t size, int type) | 20 | struct dentry *dentry, const char *name, |
| 21 | void *buffer, size_t size) | ||
| 21 | { | 22 | { |
| 22 | if (!strcmp(name, "")) | 23 | if (!strcmp(name, "")) |
| 23 | return -EINVAL; | 24 | return -EINVAL; |
| @@ -25,8 +26,9 @@ static int jffs2_user_getxattr(struct dentry *dentry, const char *name, | |||
| 25 | name, buffer, size); | 26 | name, buffer, size); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | static int jffs2_user_setxattr(struct dentry *dentry, const char *name, | 29 | static int jffs2_user_setxattr(const struct xattr_handler *handler, |
| 29 | const void *buffer, size_t size, int flags, int type) | 30 | struct dentry *dentry, const char *name, |
| 31 | const void *buffer, size_t size, int flags) | ||
| 30 | { | 32 | { |
| 31 | if (!strcmp(name, "")) | 33 | if (!strcmp(name, "")) |
| 32 | return -EINVAL; | 34 | return -EINVAL; |
| @@ -34,8 +36,10 @@ static int jffs2_user_setxattr(struct dentry *dentry, const char *name, | |||
| 34 | name, buffer, size, flags); | 36 | name, buffer, size, flags); |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | static size_t jffs2_user_listxattr(struct dentry *dentry, char *list, | 39 | static size_t jffs2_user_listxattr(const struct xattr_handler *handler, |
| 38 | size_t list_size, const char *name, size_t name_len, int type) | 40 | struct dentry *dentry, char *list, |
| 41 | size_t list_size, const char *name, | ||
| 42 | size_t name_len) | ||
| 39 | { | 43 | { |
| 40 | size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1; | 44 | size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1; |
| 41 | 45 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ff5bddc49a2a..765a03559363 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -6248,9 +6248,10 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) | |||
| 6248 | 6248 | ||
| 6249 | #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" | 6249 | #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" |
| 6250 | 6250 | ||
| 6251 | static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, | 6251 | static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, |
| 6252 | struct dentry *dentry, const char *key, | ||
| 6252 | const void *buf, size_t buflen, | 6253 | const void *buf, size_t buflen, |
| 6253 | int flags, int type) | 6254 | int flags) |
| 6254 | { | 6255 | { |
| 6255 | if (strcmp(key, "") != 0) | 6256 | if (strcmp(key, "") != 0) |
| 6256 | return -EINVAL; | 6257 | return -EINVAL; |
| @@ -6258,8 +6259,9 @@ static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, | |||
| 6258 | return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); | 6259 | return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); |
| 6259 | } | 6260 | } |
| 6260 | 6261 | ||
| 6261 | static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, | 6262 | static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, |
| 6262 | void *buf, size_t buflen, int type) | 6263 | struct dentry *dentry, const char *key, |
| 6264 | void *buf, size_t buflen) | ||
| 6263 | { | 6265 | { |
| 6264 | if (strcmp(key, "") != 0) | 6266 | if (strcmp(key, "") != 0) |
| 6265 | return -EINVAL; | 6267 | return -EINVAL; |
| @@ -6267,9 +6269,10 @@ static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, | |||
| 6267 | return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); | 6269 | return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); |
| 6268 | } | 6270 | } |
| 6269 | 6271 | ||
| 6270 | static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, | 6272 | static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler, |
| 6273 | struct dentry *dentry, char *list, | ||
| 6271 | size_t list_len, const char *name, | 6274 | size_t list_len, const char *name, |
| 6272 | size_t name_len, int type) | 6275 | size_t name_len) |
| 6273 | { | 6276 | { |
| 6274 | size_t len = sizeof(XATTR_NAME_NFSV4_ACL); | 6277 | size_t len = sizeof(XATTR_NAME_NFSV4_ACL); |
| 6275 | 6278 | ||
| @@ -6287,9 +6290,10 @@ static inline int nfs4_server_supports_labels(struct nfs_server *server) | |||
| 6287 | return server->caps & NFS_CAP_SECURITY_LABEL; | 6290 | return server->caps & NFS_CAP_SECURITY_LABEL; |
| 6288 | } | 6291 | } |
| 6289 | 6292 | ||
| 6290 | static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key, | 6293 | static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler, |
| 6291 | const void *buf, size_t buflen, | 6294 | struct dentry *dentry, const char *key, |
| 6292 | int flags, int type) | 6295 | const void *buf, size_t buflen, |
| 6296 | int flags) | ||
| 6293 | { | 6297 | { |
| 6294 | if (security_ismaclabel(key)) | 6298 | if (security_ismaclabel(key)) |
| 6295 | return nfs4_set_security_label(dentry, buf, buflen); | 6299 | return nfs4_set_security_label(dentry, buf, buflen); |
| @@ -6297,17 +6301,19 @@ static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key, | |||
| 6297 | return -EOPNOTSUPP; | 6301 | return -EOPNOTSUPP; |
| 6298 | } | 6302 | } |
| 6299 | 6303 | ||
| 6300 | static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key, | 6304 | static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler, |
| 6301 | void *buf, size_t buflen, int type) | 6305 | struct dentry *dentry, const char *key, |
| 6306 | void *buf, size_t buflen) | ||
| 6302 | { | 6307 | { |
| 6303 | if (security_ismaclabel(key)) | 6308 | if (security_ismaclabel(key)) |
| 6304 | return nfs4_get_security_label(d_inode(dentry), buf, buflen); | 6309 | return nfs4_get_security_label(d_inode(dentry), buf, buflen); |
| 6305 | return -EOPNOTSUPP; | 6310 | return -EOPNOTSUPP; |
| 6306 | } | 6311 | } |
| 6307 | 6312 | ||
| 6308 | static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list, | 6313 | static size_t nfs4_xattr_list_nfs4_label(const struct xattr_handler *handler, |
| 6309 | size_t list_len, const char *name, | 6314 | struct dentry *dentry, char *list, |
| 6310 | size_t name_len, int type) | 6315 | size_t list_len, const char *name, |
| 6316 | size_t name_len) | ||
| 6311 | { | 6317 | { |
| 6312 | size_t len = 0; | 6318 | size_t len = 0; |
| 6313 | 6319 | ||
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index ebfdea78659b..e9164f09841b 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -7229,9 +7229,10 @@ leave: | |||
| 7229 | /* | 7229 | /* |
| 7230 | * 'security' attributes support | 7230 | * 'security' attributes support |
| 7231 | */ | 7231 | */ |
| 7232 | static size_t ocfs2_xattr_security_list(struct dentry *dentry, char *list, | 7232 | static size_t ocfs2_xattr_security_list(const struct xattr_handler *handler, |
| 7233 | struct dentry *dentry, char *list, | ||
| 7233 | size_t list_size, const char *name, | 7234 | size_t list_size, const char *name, |
| 7234 | size_t name_len, int type) | 7235 | size_t name_len) |
| 7235 | { | 7236 | { |
| 7236 | const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN; | 7237 | const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN; |
| 7237 | const size_t total_len = prefix_len + name_len + 1; | 7238 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -7244,8 +7245,9 @@ static size_t ocfs2_xattr_security_list(struct dentry *dentry, char *list, | |||
| 7244 | return total_len; | 7245 | return total_len; |
| 7245 | } | 7246 | } |
| 7246 | 7247 | ||
| 7247 | static int ocfs2_xattr_security_get(struct dentry *dentry, const char *name, | 7248 | static int ocfs2_xattr_security_get(const struct xattr_handler *handler, |
| 7248 | void *buffer, size_t size, int type) | 7249 | struct dentry *dentry, const char *name, |
| 7250 | void *buffer, size_t size) | ||
| 7249 | { | 7251 | { |
| 7250 | if (strcmp(name, "") == 0) | 7252 | if (strcmp(name, "") == 0) |
| 7251 | return -EINVAL; | 7253 | return -EINVAL; |
| @@ -7253,8 +7255,9 @@ static int ocfs2_xattr_security_get(struct dentry *dentry, const char *name, | |||
| 7253 | name, buffer, size); | 7255 | name, buffer, size); |
| 7254 | } | 7256 | } |
| 7255 | 7257 | ||
| 7256 | static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name, | 7258 | static int ocfs2_xattr_security_set(const struct xattr_handler *handler, |
| 7257 | const void *value, size_t size, int flags, int type) | 7259 | struct dentry *dentry, const char *name, |
| 7260 | const void *value, size_t size, int flags) | ||
| 7258 | { | 7261 | { |
| 7259 | if (strcmp(name, "") == 0) | 7262 | if (strcmp(name, "") == 0) |
| 7260 | return -EINVAL; | 7263 | return -EINVAL; |
| @@ -7319,9 +7322,10 @@ const struct xattr_handler ocfs2_xattr_security_handler = { | |||
| 7319 | /* | 7322 | /* |
| 7320 | * 'trusted' attributes support | 7323 | * 'trusted' attributes support |
| 7321 | */ | 7324 | */ |
| 7322 | static size_t ocfs2_xattr_trusted_list(struct dentry *dentry, char *list, | 7325 | static size_t ocfs2_xattr_trusted_list(const struct xattr_handler *handler, |
| 7326 | struct dentry *dentry, char *list, | ||
| 7323 | size_t list_size, const char *name, | 7327 | size_t list_size, const char *name, |
| 7324 | size_t name_len, int type) | 7328 | size_t name_len) |
| 7325 | { | 7329 | { |
| 7326 | const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; | 7330 | const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; |
| 7327 | const size_t total_len = prefix_len + name_len + 1; | 7331 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -7337,8 +7341,9 @@ static size_t ocfs2_xattr_trusted_list(struct dentry *dentry, char *list, | |||
| 7337 | return total_len; | 7341 | return total_len; |
| 7338 | } | 7342 | } |
| 7339 | 7343 | ||
| 7340 | static int ocfs2_xattr_trusted_get(struct dentry *dentry, const char *name, | 7344 | static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, |
| 7341 | void *buffer, size_t size, int type) | 7345 | struct dentry *dentry, const char *name, |
| 7346 | void *buffer, size_t size) | ||
| 7342 | { | 7347 | { |
| 7343 | if (strcmp(name, "") == 0) | 7348 | if (strcmp(name, "") == 0) |
| 7344 | return -EINVAL; | 7349 | return -EINVAL; |
| @@ -7346,8 +7351,9 @@ static int ocfs2_xattr_trusted_get(struct dentry *dentry, const char *name, | |||
| 7346 | name, buffer, size); | 7351 | name, buffer, size); |
| 7347 | } | 7352 | } |
| 7348 | 7353 | ||
| 7349 | static int ocfs2_xattr_trusted_set(struct dentry *dentry, const char *name, | 7354 | static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler, |
| 7350 | const void *value, size_t size, int flags, int type) | 7355 | struct dentry *dentry, const char *name, |
| 7356 | const void *value, size_t size, int flags) | ||
| 7351 | { | 7357 | { |
| 7352 | if (strcmp(name, "") == 0) | 7358 | if (strcmp(name, "") == 0) |
| 7353 | return -EINVAL; | 7359 | return -EINVAL; |
| @@ -7366,9 +7372,10 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = { | |||
| 7366 | /* | 7372 | /* |
| 7367 | * 'user' attributes support | 7373 | * 'user' attributes support |
| 7368 | */ | 7374 | */ |
| 7369 | static size_t ocfs2_xattr_user_list(struct dentry *dentry, char *list, | 7375 | static size_t ocfs2_xattr_user_list(const struct xattr_handler *handler, |
| 7376 | struct dentry *dentry, char *list, | ||
| 7370 | size_t list_size, const char *name, | 7377 | size_t list_size, const char *name, |
| 7371 | size_t name_len, int type) | 7378 | size_t name_len) |
| 7372 | { | 7379 | { |
| 7373 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; | 7380 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; |
| 7374 | const size_t total_len = prefix_len + name_len + 1; | 7381 | const size_t total_len = prefix_len + name_len + 1; |
| @@ -7385,8 +7392,9 @@ static size_t ocfs2_xattr_user_list(struct dentry *dentry, char *list, | |||
| 7385 | return total_len; | 7392 | return total_len; |
| 7386 | } | 7393 | } |
| 7387 | 7394 | ||
| 7388 | static int ocfs2_xattr_user_get(struct dentry *dentry, const char *name, | 7395 | static int ocfs2_xattr_user_get(const struct xattr_handler *handler, |
| 7389 | void *buffer, size_t size, int type) | 7396 | struct dentry *dentry, const char *name, |
| 7397 | void *buffer, size_t size) | ||
| 7390 | { | 7398 | { |
| 7391 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); | 7399 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); |
| 7392 | 7400 | ||
| @@ -7398,8 +7406,9 @@ static int ocfs2_xattr_user_get(struct dentry *dentry, const char *name, | |||
| 7398 | buffer, size); | 7406 | buffer, size); |
| 7399 | } | 7407 | } |
| 7400 | 7408 | ||
| 7401 | static int ocfs2_xattr_user_set(struct dentry *dentry, const char *name, | 7409 | static int ocfs2_xattr_user_set(const struct xattr_handler *handler, |
| 7402 | const void *value, size_t size, int flags, int type) | 7410 | struct dentry *dentry, const char *name, |
| 7411 | const void *value, size_t size, int flags) | ||
| 7403 | { | 7412 | { |
| 7404 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); | 7413 | struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); |
| 7405 | 7414 | ||
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17ded7d47..4adde1e2cbec 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
| @@ -762,18 +762,21 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, | |||
| 762 | EXPORT_SYMBOL (posix_acl_to_xattr); | 762 | EXPORT_SYMBOL (posix_acl_to_xattr); |
| 763 | 763 | ||
| 764 | static int | 764 | static int |
| 765 | posix_acl_xattr_get(struct dentry *dentry, const char *name, | 765 | posix_acl_xattr_get(const struct xattr_handler *handler, |
| 766 | void *value, size_t size, int type) | 766 | struct dentry *dentry, const char *name, |
| 767 | void *value, size_t size) | ||
| 767 | { | 768 | { |
| 768 | struct posix_acl *acl; | 769 | struct posix_acl *acl; |
| 769 | int error; | 770 | int error; |
| 770 | 771 | ||
| 772 | if (strcmp(name, "") != 0) | ||
| 773 | return -EINVAL; | ||
| 771 | if (!IS_POSIXACL(d_backing_inode(dentry))) | 774 | if (!IS_POSIXACL(d_backing_inode(dentry))) |
| 772 | return -EOPNOTSUPP; | 775 | return -EOPNOTSUPP; |
| 773 | if (d_is_symlink(dentry)) | 776 | if (d_is_symlink(dentry)) |
| 774 | return -EOPNOTSUPP; | 777 | return -EOPNOTSUPP; |
| 775 | 778 | ||
| 776 | acl = get_acl(d_backing_inode(dentry), type); | 779 | acl = get_acl(d_backing_inode(dentry), handler->flags); |
| 777 | if (IS_ERR(acl)) | 780 | if (IS_ERR(acl)) |
| 778 | return PTR_ERR(acl); | 781 | return PTR_ERR(acl); |
| 779 | if (acl == NULL) | 782 | if (acl == NULL) |
| @@ -786,19 +789,22 @@ posix_acl_xattr_get(struct dentry *dentry, const char *name, | |||
| 786 | } | 789 | } |
| 787 | 790 | ||
| 788 | static int | 791 | static int |
| 789 | posix_acl_xattr_set(struct dentry *dentry, const char *name, | 792 | posix_acl_xattr_set(const struct xattr_handler *handler, |
| 790 | const void *value, size_t size, int flags, int type) | 793 | struct dentry *dentry, const char *name, |
| 794 | const void *value, size_t size, int flags) | ||
| 791 | { | 795 | { |
| 792 | struct inode *inode = d_backing_inode(dentry); | 796 | struct inode *inode = d_backing_inode(dentry); |
| 793 | struct posix_acl *acl = NULL; | 797 | struct posix_acl *acl = NULL; |
| 794 | int ret; | 798 | int ret; |
| 795 | 799 | ||
| 800 | if (strcmp(name, "") != 0) | ||
| 801 | return -EINVAL; | ||
| 796 | if (!IS_POSIXACL(inode)) | 802 | if (!IS_POSIXACL(inode)) |
| 797 | return -EOPNOTSUPP; | 803 | return -EOPNOTSUPP; |
| 798 | if (!inode->i_op->set_acl) | 804 | if (!inode->i_op->set_acl) |
| 799 | return -EOPNOTSUPP; | 805 | return -EOPNOTSUPP; |
| 800 | 806 | ||
| 801 | if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) | 807 | if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) |
| 802 | return value ? -EACCES : 0; | 808 | return value ? -EACCES : 0; |
| 803 | if (!inode_owner_or_capable(inode)) | 809 | if (!inode_owner_or_capable(inode)) |
| 804 | return -EPERM; | 810 | return -EPERM; |
| @@ -815,28 +821,22 @@ posix_acl_xattr_set(struct dentry *dentry, const char *name, | |||
| 815 | } | 821 | } |
| 816 | } | 822 | } |
| 817 | 823 | ||
| 818 | ret = inode->i_op->set_acl(inode, acl, type); | 824 | ret = inode->i_op->set_acl(inode, acl, handler->flags); |
| 819 | out: | 825 | out: |
| 820 | posix_acl_release(acl); | 826 | posix_acl_release(acl); |
| 821 | return ret; | 827 | return ret; |
| 822 | } | 828 | } |
| 823 | 829 | ||
| 824 | static size_t | 830 | static size_t |
| 825 | posix_acl_xattr_list(struct dentry *dentry, char *list, size_t list_size, | 831 | posix_acl_xattr_list(const struct xattr_handler *handler, |
| 826 | const char *name, size_t name_len, int type) | 832 | struct dentry *dentry, char *list, size_t list_size, |
| 833 | const char *name, size_t name_len) | ||
| 827 | { | 834 | { |
| 828 | const char *xname; | 835 | const char *xname = handler->prefix; |
| 829 | size_t size; | 836 | size_t size; |
| 830 | 837 | ||
| 831 | if (!IS_POSIXACL(d_backing_inode(dentry))) | 838 | if (!IS_POSIXACL(d_backing_inode(dentry))) |
| 832 | return -EOPNOTSUPP; | 839 | return 0; |
| 833 | if (d_is_symlink(dentry)) | ||
| 834 | return -EOPNOTSUPP; | ||
| 835 | |||
| 836 | if (type == ACL_TYPE_ACCESS) | ||
| 837 | xname = POSIX_ACL_XATTR_ACCESS; | ||
| 838 | else | ||
| 839 | xname = POSIX_ACL_XATTR_DEFAULT; | ||
| 840 | 840 | ||
| 841 | size = strlen(xname) + 1; | 841 | size = strlen(xname) + 1; |
| 842 | if (list && size <= list_size) | 842 | if (list && size <= list_size) |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e87f9b52bf06..66b26fdfff8d 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -778,7 +778,7 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | |||
| 778 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) | 778 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) |
| 779 | return -EOPNOTSUPP; | 779 | return -EOPNOTSUPP; |
| 780 | 780 | ||
| 781 | return handler->get(dentry, name, buffer, size, handler->flags); | 781 | return handler->get(handler, dentry, name, buffer, size); |
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | /* | 784 | /* |
| @@ -797,7 +797,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
| 797 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) | 797 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) |
| 798 | return -EOPNOTSUPP; | 798 | return -EOPNOTSUPP; |
| 799 | 799 | ||
| 800 | return handler->set(dentry, name, value, size, flags, handler->flags); | 800 | return handler->set(handler, dentry, name, value, size, flags); |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | /* | 803 | /* |
| @@ -814,7 +814,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) | |||
| 814 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) | 814 | if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1) |
| 815 | return -EOPNOTSUPP; | 815 | return -EOPNOTSUPP; |
| 816 | 816 | ||
| 817 | return handler->set(dentry, name, NULL, 0, XATTR_REPLACE, handler->flags); | 817 | return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE); |
| 818 | } | 818 | } |
| 819 | 819 | ||
| 820 | struct listxattr_buf { | 820 | struct listxattr_buf { |
| @@ -842,14 +842,14 @@ static int listxattr_filler(struct dir_context *ctx, const char *name, | |||
| 842 | if (!handler) /* Unsupported xattr name */ | 842 | if (!handler) /* Unsupported xattr name */ |
| 843 | return 0; | 843 | return 0; |
| 844 | if (b->buf) { | 844 | if (b->buf) { |
| 845 | size = handler->list(b->dentry, b->buf + b->pos, | 845 | size = handler->list(handler, b->dentry, |
| 846 | b->size, name, namelen, | 846 | b->buf + b->pos, b->size, name, |
| 847 | handler->flags); | 847 | namelen); |
| 848 | if (size > b->size) | 848 | if (size > b->size) |
| 849 | return -ERANGE; | 849 | return -ERANGE; |
| 850 | } else { | 850 | } else { |
| 851 | size = handler->list(b->dentry, NULL, 0, name, | 851 | size = handler->list(handler, b->dentry, |
| 852 | namelen, handler->flags); | 852 | NULL, 0, name, namelen); |
| 853 | } | 853 | } |
| 854 | 854 | ||
| 855 | b->pos += size; | 855 | b->pos += size; |
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index 9a3b0616f283..ac659af431ae 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
| @@ -9,8 +9,8 @@ | |||
| 9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
| 10 | 10 | ||
| 11 | static int | 11 | static int |
| 12 | security_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | 12 | security_get(const struct xattr_handler *handler, struct dentry *dentry, |
| 13 | int handler_flags) | 13 | const char *name, void *buffer, size_t size) |
| 14 | { | 14 | { |
| 15 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 15 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
| 16 | return -EINVAL; | 16 | return -EINVAL; |
| @@ -22,8 +22,8 @@ security_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | |||
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static int | 24 | static int |
| 25 | security_set(struct dentry *dentry, const char *name, const void *buffer, | 25 | security_set(const struct xattr_handler *handler, struct dentry *dentry, |
| 26 | size_t size, int flags, int handler_flags) | 26 | const char *name, const void *buffer, size_t size, int flags) |
| 27 | { | 27 | { |
| 28 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 28 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
| 29 | return -EINVAL; | 29 | return -EINVAL; |
| @@ -34,8 +34,9 @@ security_set(struct dentry *dentry, const char *name, const void *buffer, | |||
| 34 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); | 34 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static size_t security_list(struct dentry *dentry, char *list, size_t list_len, | 37 | static size_t security_list(const struct xattr_handler *handler, |
| 38 | const char *name, size_t namelen, int handler_flags) | 38 | struct dentry *dentry, char *list, size_t list_len, |
| 39 | const char *name, size_t namelen) | ||
| 39 | { | 40 | { |
| 40 | const size_t len = namelen + 1; | 41 | const size_t len = namelen + 1; |
| 41 | 42 | ||
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index e4f1343714e0..a338adf1b8b4 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c | |||
| @@ -8,8 +8,8 @@ | |||
| 8 | #include <linux/uaccess.h> | 8 | #include <linux/uaccess.h> |
| 9 | 9 | ||
| 10 | static int | 10 | static int |
| 11 | trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | 11 | trusted_get(const struct xattr_handler *handler, struct dentry *dentry, |
| 12 | int handler_flags) | 12 | const char *name, void *buffer, size_t size) |
| 13 | { | 13 | { |
| 14 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | 14 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) |
| 15 | return -EINVAL; | 15 | return -EINVAL; |
| @@ -21,8 +21,8 @@ trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static int | 23 | static int |
| 24 | trusted_set(struct dentry *dentry, const char *name, const void *buffer, | 24 | trusted_set(const struct xattr_handler *handler, struct dentry *dentry, |
| 25 | size_t size, int flags, int handler_flags) | 25 | const char *name, const void *buffer, size_t size, int flags) |
| 26 | { | 26 | { |
| 27 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | 27 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) |
| 28 | return -EINVAL; | 28 | return -EINVAL; |
| @@ -33,8 +33,9 @@ trusted_set(struct dentry *dentry, const char *name, const void *buffer, | |||
| 33 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); | 33 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size, | 36 | static size_t trusted_list(const struct xattr_handler *handler, |
| 37 | const char *name, size_t name_len, int handler_flags) | 37 | struct dentry *dentry, char *list, size_t list_size, |
| 38 | const char *name, size_t name_len) | ||
| 38 | { | 39 | { |
| 39 | const size_t len = name_len + 1; | 40 | const size_t len = name_len + 1; |
| 40 | 41 | ||
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index d0b08d3e5689..39c9667191c5 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | #include <linux/uaccess.h> | 7 | #include <linux/uaccess.h> |
| 8 | 8 | ||
| 9 | static int | 9 | static int |
| 10 | user_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | 10 | user_get(const struct xattr_handler *handler, struct dentry *dentry, |
| 11 | int handler_flags) | 11 | const char *name, void *buffer, size_t size) |
| 12 | { | 12 | { |
| 13 | 13 | ||
| 14 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | 14 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) |
| @@ -19,8 +19,8 @@ user_get(struct dentry *dentry, const char *name, void *buffer, size_t size, | |||
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | static int | 21 | static int |
| 22 | user_set(struct dentry *dentry, const char *name, const void *buffer, | 22 | user_set(const struct xattr_handler *handler, struct dentry *dentry, |
| 23 | size_t size, int flags, int handler_flags) | 23 | const char *name, const void *buffer, size_t size, int flags) |
| 24 | { | 24 | { |
| 25 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | 25 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) |
| 26 | return -EINVAL; | 26 | return -EINVAL; |
| @@ -30,8 +30,9 @@ user_set(struct dentry *dentry, const char *name, const void *buffer, | |||
| 30 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); | 30 | return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | static size_t user_list(struct dentry *dentry, char *list, size_t list_size, | 33 | static size_t user_list(const struct xattr_handler *handler, |
| 34 | const char *name, size_t name_len, int handler_flags) | 34 | struct dentry *dentry, char *list, size_t list_size, |
| 35 | const char *name, size_t name_len) | ||
| 35 | { | 36 | { |
| 36 | const size_t len = name_len + 1; | 37 | const size_t len = name_len + 1; |
| 37 | 38 | ||
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index e5e0ddf5b143..6a4cc344085c 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c | |||
| @@ -68,8 +68,8 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer, | |||
| 68 | name_size = le16_to_cpu(entry.size); | 68 | name_size = le16_to_cpu(entry.size); |
| 69 | handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); | 69 | handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); |
| 70 | if (handler) | 70 | if (handler) |
| 71 | prefix_size = handler->list(d, buffer, rest, NULL, | 71 | prefix_size = handler->list(handler, d, buffer, rest, |
| 72 | name_size, handler->flags); | 72 | NULL, name_size); |
| 73 | if (prefix_size) { | 73 | if (prefix_size) { |
| 74 | if (buffer) { | 74 | if (buffer) { |
| 75 | if (prefix_size + name_size + 1 > rest) { | 75 | if (prefix_size + name_size + 1 > rest) { |
| @@ -212,88 +212,68 @@ failed: | |||
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | 214 | ||
| 215 | /* | 215 | static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler, |
| 216 | * User namespace support | 216 | struct dentry *d, char *list, |
| 217 | */ | 217 | size_t list_size, const char *name, |
| 218 | static size_t squashfs_user_list(struct dentry *d, char *list, size_t list_size, | 218 | size_t name_len) |
| 219 | const char *name, size_t name_len, int type) | ||
| 220 | { | 219 | { |
| 221 | if (list && XATTR_USER_PREFIX_LEN <= list_size) | 220 | int len = strlen(handler->prefix); |
| 222 | memcpy(list, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); | 221 | |
| 223 | return XATTR_USER_PREFIX_LEN; | 222 | if (list && len <= list_size) |
| 223 | memcpy(list, handler->prefix, len); | ||
| 224 | return len; | ||
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | static int squashfs_user_get(struct dentry *d, const char *name, void *buffer, | 227 | static int squashfs_xattr_handler_get(const struct xattr_handler *handler, |
| 227 | size_t size, int type) | 228 | struct dentry *d, const char *name, |
| 229 | void *buffer, size_t size) | ||
| 228 | { | 230 | { |
| 229 | if (name[0] == '\0') | 231 | if (name[0] == '\0') |
| 230 | return -EINVAL; | 232 | return -EINVAL; |
| 231 | 233 | ||
| 232 | return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_USER, name, | 234 | return squashfs_xattr_get(d_inode(d), handler->flags, name, |
| 233 | buffer, size); | 235 | buffer, size); |
| 234 | } | 236 | } |
| 235 | 237 | ||
| 238 | /* | ||
| 239 | * User namespace support | ||
| 240 | */ | ||
| 236 | static const struct xattr_handler squashfs_xattr_user_handler = { | 241 | static const struct xattr_handler squashfs_xattr_user_handler = { |
| 237 | .prefix = XATTR_USER_PREFIX, | 242 | .prefix = XATTR_USER_PREFIX, |
| 238 | .list = squashfs_user_list, | 243 | .flags = SQUASHFS_XATTR_USER, |
| 239 | .get = squashfs_user_get | 244 | .list = squashfs_xattr_handler_list, |
| 245 | .get = squashfs_xattr_handler_get | ||
| 240 | }; | 246 | }; |
| 241 | 247 | ||
| 242 | /* | 248 | /* |
| 243 | * Trusted namespace support | 249 | * Trusted namespace support |
| 244 | */ | 250 | */ |
| 245 | static size_t squashfs_trusted_list(struct dentry *d, char *list, | 251 | static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, |
| 246 | size_t list_size, const char *name, size_t name_len, int type) | 252 | struct dentry *d, char *list, |
| 253 | size_t list_size, const char *name, | ||
| 254 | size_t name_len) | ||
| 247 | { | 255 | { |
| 248 | if (!capable(CAP_SYS_ADMIN)) | 256 | if (!capable(CAP_SYS_ADMIN)) |
| 249 | return 0; | 257 | return 0; |
| 250 | 258 | return squashfs_xattr_handler_list(handler, d, list, list_size, name, | |
| 251 | if (list && XATTR_TRUSTED_PREFIX_LEN <= list_size) | 259 | name_len); |
| 252 | memcpy(list, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); | ||
| 253 | return XATTR_TRUSTED_PREFIX_LEN; | ||
| 254 | } | ||
| 255 | |||
| 256 | static int squashfs_trusted_get(struct dentry *d, const char *name, | ||
| 257 | void *buffer, size_t size, int type) | ||
| 258 | { | ||
| 259 | if (name[0] == '\0') | ||
| 260 | return -EINVAL; | ||
| 261 | |||
| 262 | return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_TRUSTED, name, | ||
| 263 | buffer, size); | ||
| 264 | } | 260 | } |
| 265 | 261 | ||
| 266 | static const struct xattr_handler squashfs_xattr_trusted_handler = { | 262 | static const struct xattr_handler squashfs_xattr_trusted_handler = { |
| 267 | .prefix = XATTR_TRUSTED_PREFIX, | 263 | .prefix = XATTR_TRUSTED_PREFIX, |
| 268 | .list = squashfs_trusted_list, | 264 | .flags = SQUASHFS_XATTR_TRUSTED, |
| 269 | .get = squashfs_trusted_get | 265 | .list = squashfs_trusted_xattr_handler_list, |
| 266 | .get = squashfs_xattr_handler_get | ||
| 270 | }; | 267 | }; |
| 271 | 268 | ||
| 272 | /* | 269 | /* |
| 273 | * Security namespace support | 270 | * Security namespace support |
| 274 | */ | 271 | */ |
| 275 | static size_t squashfs_security_list(struct dentry *d, char *list, | ||
| 276 | size_t list_size, const char *name, size_t name_len, int type) | ||
| 277 | { | ||
| 278 | if (list && XATTR_SECURITY_PREFIX_LEN <= list_size) | ||
| 279 | memcpy(list, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN); | ||
| 280 | return XATTR_SECURITY_PREFIX_LEN; | ||
| 281 | } | ||
| 282 | |||
| 283 | static int squashfs_security_get(struct dentry *d, const char *name, | ||
| 284 | void *buffer, size_t size, int type) | ||
| 285 | { | ||
| 286 | if (name[0] == '\0') | ||
| 287 | return -EINVAL; | ||
| 288 | |||
| 289 | return squashfs_xattr_get(d_inode(d), SQUASHFS_XATTR_SECURITY, name, | ||
| 290 | buffer, size); | ||
| 291 | } | ||
| 292 | |||
| 293 | static const struct xattr_handler squashfs_xattr_security_handler = { | 272 | static const struct xattr_handler squashfs_xattr_security_handler = { |
| 294 | .prefix = XATTR_SECURITY_PREFIX, | 273 | .prefix = XATTR_SECURITY_PREFIX, |
| 295 | .list = squashfs_security_list, | 274 | .flags = SQUASHFS_XATTR_SECURITY, |
| 296 | .get = squashfs_security_get | 275 | .list = squashfs_xattr_handler_list, |
| 276 | .get = squashfs_xattr_handler_get | ||
| 297 | }; | 277 | }; |
| 298 | 278 | ||
| 299 | static const struct xattr_handler *squashfs_xattr_handler(int type) | 279 | static const struct xattr_handler *squashfs_xattr_handler(int type) |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 8ee3133dd8e4..1fd90c079537 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -2040,7 +2040,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 2040 | if (c->max_inode_sz > MAX_LFS_FILESIZE) | 2040 | if (c->max_inode_sz > MAX_LFS_FILESIZE) |
| 2041 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; | 2041 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; |
| 2042 | sb->s_op = &ubifs_super_operations; | 2042 | sb->s_op = &ubifs_super_operations; |
| 2043 | sb->s_xattr = ubifs_xattr_handlers; | ||
| 2044 | 2043 | ||
| 2045 | mutex_lock(&c->umount_mutex); | 2044 | mutex_lock(&c->umount_mutex); |
| 2046 | err = mount_ubifs(c); | 2045 | err = mount_ubifs(c); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 01142e129d16..a5697de763f5 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -1470,7 +1470,6 @@ extern spinlock_t ubifs_infos_lock; | |||
| 1470 | extern atomic_long_t ubifs_clean_zn_cnt; | 1470 | extern atomic_long_t ubifs_clean_zn_cnt; |
| 1471 | extern struct kmem_cache *ubifs_inode_slab; | 1471 | extern struct kmem_cache *ubifs_inode_slab; |
| 1472 | extern const struct super_operations ubifs_super_operations; | 1472 | extern const struct super_operations ubifs_super_operations; |
| 1473 | extern const struct xattr_handler *ubifs_xattr_handlers[]; | ||
| 1474 | extern const struct address_space_operations ubifs_file_address_operations; | 1473 | extern const struct address_space_operations ubifs_file_address_operations; |
| 1475 | extern const struct file_operations ubifs_file_operations; | 1474 | extern const struct file_operations ubifs_file_operations; |
| 1476 | extern const struct inode_operations ubifs_file_inode_operations; | 1475 | extern const struct inode_operations ubifs_file_inode_operations; |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 259fbabf143d..e8b01b721e99 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
| @@ -588,46 +588,6 @@ out_free: | |||
| 588 | return err; | 588 | return err; |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | static size_t security_listxattr(struct dentry *d, char *list, size_t list_size, | ||
| 592 | const char *name, size_t name_len, int flags) | ||
| 593 | { | ||
| 594 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
| 595 | const size_t total_len = prefix_len + name_len + 1; | ||
| 596 | |||
| 597 | if (list && total_len <= list_size) { | ||
| 598 | memcpy(list, XATTR_SECURITY_PREFIX, prefix_len); | ||
| 599 | memcpy(list + prefix_len, name, name_len); | ||
| 600 | list[prefix_len + name_len] = '\0'; | ||
| 601 | } | ||
| 602 | |||
| 603 | return total_len; | ||
| 604 | } | ||
| 605 | |||
| 606 | static int security_getxattr(struct dentry *d, const char *name, void *buffer, | ||
| 607 | size_t size, int flags) | ||
| 608 | { | ||
| 609 | return ubifs_getxattr(d, name, buffer, size); | ||
| 610 | } | ||
| 611 | |||
| 612 | static int security_setxattr(struct dentry *d, const char *name, | ||
| 613 | const void *value, size_t size, int flags, | ||
| 614 | int handler_flags) | ||
| 615 | { | ||
| 616 | return ubifs_setxattr(d, name, value, size, flags); | ||
| 617 | } | ||
| 618 | |||
| 619 | static const struct xattr_handler ubifs_xattr_security_handler = { | ||
| 620 | .prefix = XATTR_SECURITY_PREFIX, | ||
| 621 | .list = security_listxattr, | ||
| 622 | .get = security_getxattr, | ||
| 623 | .set = security_setxattr, | ||
| 624 | }; | ||
| 625 | |||
| 626 | const struct xattr_handler *ubifs_xattr_handlers[] = { | ||
| 627 | &ubifs_xattr_security_handler, | ||
| 628 | NULL, | ||
| 629 | }; | ||
| 630 | |||
| 631 | static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, | 591 | static int init_xattrs(struct inode *inode, const struct xattr *xattr_array, |
| 632 | void *fs_info) | 592 | void *fs_info) |
| 633 | { | 593 | { |
diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1258dd..9b932b95d74e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
| @@ -720,7 +720,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s | |||
| 720 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 720 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
| 721 | if (!handler) | 721 | if (!handler) |
| 722 | return -EOPNOTSUPP; | 722 | return -EOPNOTSUPP; |
| 723 | return handler->get(dentry, name, buffer, size, handler->flags); | 723 | return handler->get(handler, dentry, name, buffer, size); |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | /* | 726 | /* |
| @@ -735,15 +735,15 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
| 735 | 735 | ||
| 736 | if (!buffer) { | 736 | if (!buffer) { |
| 737 | for_each_xattr_handler(handlers, handler) { | 737 | for_each_xattr_handler(handlers, handler) { |
| 738 | size += handler->list(dentry, NULL, 0, NULL, 0, | 738 | size += handler->list(handler, dentry, NULL, 0, |
| 739 | handler->flags); | 739 | NULL, 0); |
| 740 | } | 740 | } |
| 741 | } else { | 741 | } else { |
| 742 | char *buf = buffer; | 742 | char *buf = buffer; |
| 743 | 743 | ||
| 744 | for_each_xattr_handler(handlers, handler) { | 744 | for_each_xattr_handler(handlers, handler) { |
| 745 | size = handler->list(dentry, buf, buffer_size, | 745 | size = handler->list(handler, dentry, buf, buffer_size, |
| 746 | NULL, 0, handler->flags); | 746 | NULL, 0); |
| 747 | if (size > buffer_size) | 747 | if (size > buffer_size) |
| 748 | return -ERANGE; | 748 | return -ERANGE; |
| 749 | buf += size; | 749 | buf += size; |
| @@ -767,7 +767,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz | |||
| 767 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 767 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
| 768 | if (!handler) | 768 | if (!handler) |
| 769 | return -EOPNOTSUPP; | 769 | return -EOPNOTSUPP; |
| 770 | return handler->set(dentry, name, value, size, flags, handler->flags); | 770 | return handler->set(handler, dentry, name, value, size, flags); |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | /* | 773 | /* |
| @@ -782,8 +782,7 @@ generic_removexattr(struct dentry *dentry, const char *name) | |||
| 782 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | 782 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); |
| 783 | if (!handler) | 783 | if (!handler) |
| 784 | return -EOPNOTSUPP; | 784 | return -EOPNOTSUPP; |
| 785 | return handler->set(dentry, name, NULL, 0, | 785 | return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE); |
| 786 | XATTR_REPLACE, handler->flags); | ||
| 787 | } | 786 | } |
| 788 | 787 | ||
| 789 | EXPORT_SYMBOL(generic_getxattr); | 788 | EXPORT_SYMBOL(generic_getxattr); |
| @@ -791,6 +790,30 @@ EXPORT_SYMBOL(generic_listxattr); | |||
| 791 | EXPORT_SYMBOL(generic_setxattr); | 790 | EXPORT_SYMBOL(generic_setxattr); |
| 792 | EXPORT_SYMBOL(generic_removexattr); | 791 | EXPORT_SYMBOL(generic_removexattr); |
| 793 | 792 | ||
| 793 | /** | ||
| 794 | * xattr_full_name - Compute full attribute name from suffix | ||
| 795 | * | ||
| 796 | * @handler: handler of the xattr_handler operation | ||
| 797 | * @name: name passed to the xattr_handler operation | ||
| 798 | * | ||
| 799 | * The get and set xattr handler operations are called with the remainder of | ||
| 800 | * the attribute name after skipping the handler's prefix: for example, "foo" | ||
| 801 | * is passed to the get operation of a handler with prefix "user." to get | ||
| 802 | * attribute "user.foo". The full name is still "there" in the name though. | ||
| 803 | * | ||
| 804 | * Note: the list xattr handler operation when called from the vfs is passed a | ||
| 805 | * NULL name; some file systems use this operation internally, with varying | ||
| 806 | * semantics. | ||
| 807 | */ | ||
| 808 | const char *xattr_full_name(const struct xattr_handler *handler, | ||
| 809 | const char *name) | ||
| 810 | { | ||
| 811 | size_t prefix_len = strlen(handler->prefix); | ||
| 812 | |||
| 813 | return name - prefix_len; | ||
| 814 | } | ||
| 815 | EXPORT_SYMBOL(xattr_full_name); | ||
| 816 | |||
| 794 | /* | 817 | /* |
| 795 | * Allocate new xattr and copy in the value; but leave the name to callers. | 818 | * Allocate new xattr and copy in the value; but leave the name to callers. |
| 796 | */ | 819 | */ |
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 8294f86441bf..839b35ca21c6 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c | |||
| @@ -32,9 +32,10 @@ | |||
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | static int | 34 | static int |
| 35 | xfs_xattr_get(struct dentry *dentry, const char *name, | 35 | xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, |
| 36 | void *value, size_t size, int xflags) | 36 | const char *name, void *value, size_t size) |
| 37 | { | 37 | { |
| 38 | int xflags = handler->flags; | ||
| 38 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 39 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
| 39 | int error, asize = size; | 40 | int error, asize = size; |
| 40 | 41 | ||
| @@ -76,9 +77,10 @@ xfs_forget_acl( | |||
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | static int | 79 | static int |
| 79 | xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, | 80 | xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, |
| 80 | size_t size, int flags, int xflags) | 81 | const char *name, const void *value, size_t size, int flags) |
| 81 | { | 82 | { |
| 83 | int xflags = handler->flags; | ||
| 82 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 84 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
| 83 | int error; | 85 | int error; |
| 84 | 86 | ||
diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 91b0a68d38dc..89474b9d260c 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h | |||
| @@ -21,15 +21,19 @@ struct dentry; | |||
| 21 | 21 | ||
| 22 | struct xattr_handler { | 22 | struct xattr_handler { |
| 23 | const char *prefix; | 23 | const char *prefix; |
| 24 | int flags; /* fs private flags passed back to the handlers */ | 24 | int flags; /* fs private flags */ |
| 25 | size_t (*list)(struct dentry *dentry, char *list, size_t list_size, | 25 | size_t (*list)(const struct xattr_handler *, struct dentry *dentry, |
| 26 | const char *name, size_t name_len, int handler_flags); | 26 | char *list, size_t list_size, const char *name, |
| 27 | int (*get)(struct dentry *dentry, const char *name, void *buffer, | 27 | size_t name_len); |
| 28 | size_t size, int handler_flags); | 28 | int (*get)(const struct xattr_handler *, struct dentry *dentry, |
| 29 | int (*set)(struct dentry *dentry, const char *name, const void *buffer, | 29 | const char *name, void *buffer, size_t size); |
| 30 | size_t size, int flags, int handler_flags); | 30 | int (*set)(const struct xattr_handler *, struct dentry *dentry, |
| 31 | const char *name, const void *buffer, size_t size, | ||
| 32 | int flags); | ||
| 31 | }; | 33 | }; |
| 32 | 34 | ||
| 35 | const char *xattr_full_name(const struct xattr_handler *, const char *); | ||
| 36 | |||
| 33 | struct xattr { | 37 | struct xattr { |
| 34 | const char *name; | 38 | const char *name; |
| 35 | void *value; | 39 | void *value; |
