diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-12-02 08:44:37 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-12-06 21:34:14 -0500 |
commit | 9172abbcd371f2f62903087bbd228f11d380b7b4 (patch) | |
tree | c9842dcce82d638b06ccdf7d0bb1e7dda17d54b5 | |
parent | 98e9cb5711c68223f0e4d5201b9a6add255ec550 (diff) |
btrfs: Use xattr handler infrastructure
Use the VFS xattr handler infrastructure and get rid of similar code in
the filesystem.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/btrfs/inode.c | 8 | ||||
-rw-r--r-- | fs/btrfs/xattr.c | 166 | ||||
-rw-r--r-- | fs/btrfs/xattr.h | 2 |
3 files changed, 63 insertions, 113 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d540fd70f6c6..4fb8d6e28b21 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -9994,7 +9994,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { | |||
9994 | .setattr = btrfs_setattr, | 9994 | .setattr = btrfs_setattr, |
9995 | .mknod = btrfs_mknod, | 9995 | .mknod = btrfs_mknod, |
9996 | .setxattr = btrfs_setxattr, | 9996 | .setxattr = btrfs_setxattr, |
9997 | .getxattr = btrfs_getxattr, | 9997 | .getxattr = generic_getxattr, |
9998 | .listxattr = btrfs_listxattr, | 9998 | .listxattr = btrfs_listxattr, |
9999 | .removexattr = btrfs_removexattr, | 9999 | .removexattr = btrfs_removexattr, |
10000 | .permission = btrfs_permission, | 10000 | .permission = btrfs_permission, |
@@ -10071,7 +10071,7 @@ static const struct inode_operations btrfs_file_inode_operations = { | |||
10071 | .getattr = btrfs_getattr, | 10071 | .getattr = btrfs_getattr, |
10072 | .setattr = btrfs_setattr, | 10072 | .setattr = btrfs_setattr, |
10073 | .setxattr = btrfs_setxattr, | 10073 | .setxattr = btrfs_setxattr, |
10074 | .getxattr = btrfs_getxattr, | 10074 | .getxattr = generic_getxattr, |
10075 | .listxattr = btrfs_listxattr, | 10075 | .listxattr = btrfs_listxattr, |
10076 | .removexattr = btrfs_removexattr, | 10076 | .removexattr = btrfs_removexattr, |
10077 | .permission = btrfs_permission, | 10077 | .permission = btrfs_permission, |
@@ -10085,7 +10085,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
10085 | .setattr = btrfs_setattr, | 10085 | .setattr = btrfs_setattr, |
10086 | .permission = btrfs_permission, | 10086 | .permission = btrfs_permission, |
10087 | .setxattr = btrfs_setxattr, | 10087 | .setxattr = btrfs_setxattr, |
10088 | .getxattr = btrfs_getxattr, | 10088 | .getxattr = generic_getxattr, |
10089 | .listxattr = btrfs_listxattr, | 10089 | .listxattr = btrfs_listxattr, |
10090 | .removexattr = btrfs_removexattr, | 10090 | .removexattr = btrfs_removexattr, |
10091 | .get_acl = btrfs_get_acl, | 10091 | .get_acl = btrfs_get_acl, |
@@ -10100,7 +10100,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
10100 | .setattr = btrfs_setattr, | 10100 | .setattr = btrfs_setattr, |
10101 | .permission = btrfs_permission, | 10101 | .permission = btrfs_permission, |
10102 | .setxattr = btrfs_setxattr, | 10102 | .setxattr = btrfs_setxattr, |
10103 | .getxattr = btrfs_getxattr, | 10103 | .getxattr = generic_getxattr, |
10104 | .listxattr = btrfs_listxattr, | 10104 | .listxattr = btrfs_listxattr, |
10105 | .removexattr = btrfs_removexattr, | 10105 | .removexattr = btrfs_removexattr, |
10106 | .update_time = btrfs_update_time, | 10106 | .update_time = btrfs_update_time, |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 1fcd7b6e7564..7cbef1a14fe1 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -351,137 +351,89 @@ err: | |||
351 | return ret; | 351 | return ret; |
352 | } | 352 | } |
353 | 353 | ||
354 | /* | 354 | static int btrfs_xattr_handler_get(const struct xattr_handler *handler, |
355 | * List of handlers for synthetic system.* attributes. All real ondisk | 355 | struct dentry *dentry, const char *name, |
356 | * attributes are handled directly. | 356 | void *buffer, size_t size) |
357 | */ | ||
358 | const struct xattr_handler *btrfs_xattr_handlers[] = { | ||
359 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | ||
360 | &posix_acl_access_xattr_handler, | ||
361 | &posix_acl_default_xattr_handler, | ||
362 | #endif | ||
363 | NULL, | ||
364 | }; | ||
365 | |||
366 | /* | ||
367 | * Check if the attribute is in a supported namespace. | ||
368 | * | ||
369 | * This is applied after the check for the synthetic attributes in the system | ||
370 | * namespace. | ||
371 | */ | ||
372 | static int btrfs_is_valid_xattr(const char *name) | ||
373 | { | 357 | { |
374 | int len = strlen(name); | 358 | struct inode *inode = d_inode(dentry); |
375 | int prefixlen = 0; | ||
376 | |||
377 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | ||
378 | XATTR_SECURITY_PREFIX_LEN)) | ||
379 | prefixlen = XATTR_SECURITY_PREFIX_LEN; | ||
380 | else if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
381 | prefixlen = XATTR_SYSTEM_PREFIX_LEN; | ||
382 | else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | ||
383 | prefixlen = XATTR_TRUSTED_PREFIX_LEN; | ||
384 | else if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) | ||
385 | prefixlen = XATTR_USER_PREFIX_LEN; | ||
386 | else if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN)) | ||
387 | prefixlen = XATTR_BTRFS_PREFIX_LEN; | ||
388 | else | ||
389 | return -EOPNOTSUPP; | ||
390 | |||
391 | /* | ||
392 | * The name cannot consist of just prefix | ||
393 | */ | ||
394 | if (len <= prefixlen) | ||
395 | return -EINVAL; | ||
396 | 359 | ||
397 | return 0; | 360 | name = xattr_full_name(handler, name); |
361 | return __btrfs_getxattr(inode, name, buffer, size); | ||
398 | } | 362 | } |
399 | 363 | ||
400 | ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, | 364 | static int btrfs_xattr_handler_set(const struct xattr_handler *handler, |
401 | void *buffer, size_t size) | 365 | struct dentry *dentry, const char *name, |
366 | const void *buffer, size_t size, | ||
367 | int flags) | ||
402 | { | 368 | { |
403 | int ret; | 369 | struct inode *inode = d_inode(dentry); |
404 | 370 | ||
405 | /* | 371 | name = xattr_full_name(handler, name); |
406 | * If this is a request for a synthetic attribute in the system.* | 372 | return __btrfs_setxattr(NULL, inode, name, buffer, size, flags); |
407 | * namespace use the generic infrastructure to resolve a handler | 373 | } |
408 | * for it via sb->s_xattr. | ||
409 | */ | ||
410 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
411 | return generic_getxattr(dentry, name, buffer, size); | ||
412 | 374 | ||
413 | ret = btrfs_is_valid_xattr(name); | 375 | static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler, |
414 | if (ret) | 376 | struct dentry *dentry, |
415 | return ret; | 377 | const char *name, const void *value, |
416 | return __btrfs_getxattr(d_inode(dentry), name, buffer, size); | 378 | size_t size, int flags) |
379 | { | ||
380 | name = xattr_full_name(handler, name); | ||
381 | return btrfs_set_prop(d_inode(dentry), name, value, size, flags); | ||
417 | } | 382 | } |
418 | 383 | ||
384 | static const struct xattr_handler btrfs_security_xattr_handler = { | ||
385 | .prefix = XATTR_SECURITY_PREFIX, | ||
386 | .get = btrfs_xattr_handler_get, | ||
387 | .set = btrfs_xattr_handler_set, | ||
388 | }; | ||
389 | |||
390 | static const struct xattr_handler btrfs_trusted_xattr_handler = { | ||
391 | .prefix = XATTR_TRUSTED_PREFIX, | ||
392 | .get = btrfs_xattr_handler_get, | ||
393 | .set = btrfs_xattr_handler_set, | ||
394 | }; | ||
395 | |||
396 | static const struct xattr_handler btrfs_user_xattr_handler = { | ||
397 | .prefix = XATTR_USER_PREFIX, | ||
398 | .get = btrfs_xattr_handler_get, | ||
399 | .set = btrfs_xattr_handler_set, | ||
400 | }; | ||
401 | |||
402 | static const struct xattr_handler btrfs_btrfs_xattr_handler = { | ||
403 | .prefix = XATTR_BTRFS_PREFIX, | ||
404 | .get = btrfs_xattr_handler_get, | ||
405 | .set = btrfs_xattr_handler_set_prop, | ||
406 | }; | ||
407 | |||
408 | const struct xattr_handler *btrfs_xattr_handlers[] = { | ||
409 | &btrfs_security_xattr_handler, | ||
410 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | ||
411 | &posix_acl_access_xattr_handler, | ||
412 | &posix_acl_default_xattr_handler, | ||
413 | #endif | ||
414 | &btrfs_trusted_xattr_handler, | ||
415 | &btrfs_user_xattr_handler, | ||
416 | &btrfs_btrfs_xattr_handler, | ||
417 | NULL, | ||
418 | }; | ||
419 | |||
419 | int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 420 | int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
420 | size_t size, int flags) | 421 | size_t size, int flags) |
421 | { | 422 | { |
422 | struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; | 423 | struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; |
423 | int ret; | ||
424 | 424 | ||
425 | /* | ||
426 | * The permission on security.* and system.* is not checked | ||
427 | * in permission(). | ||
428 | */ | ||
429 | if (btrfs_root_readonly(root)) | 425 | if (btrfs_root_readonly(root)) |
430 | return -EROFS; | 426 | return -EROFS; |
431 | 427 | return generic_setxattr(dentry, name, value, size, flags); | |
432 | /* | ||
433 | * If this is a request for a synthetic attribute in the system.* | ||
434 | * namespace use the generic infrastructure to resolve a handler | ||
435 | * for it via sb->s_xattr. | ||
436 | */ | ||
437 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
438 | return generic_setxattr(dentry, name, value, size, flags); | ||
439 | |||
440 | ret = btrfs_is_valid_xattr(name); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | |||
444 | if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN)) | ||
445 | return btrfs_set_prop(d_inode(dentry), name, | ||
446 | value, size, flags); | ||
447 | |||
448 | if (size == 0) | ||
449 | value = ""; /* empty EA, do not remove */ | ||
450 | |||
451 | return __btrfs_setxattr(NULL, d_inode(dentry), name, value, size, | ||
452 | flags); | ||
453 | } | 428 | } |
454 | 429 | ||
455 | int btrfs_removexattr(struct dentry *dentry, const char *name) | 430 | int btrfs_removexattr(struct dentry *dentry, const char *name) |
456 | { | 431 | { |
457 | struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; | 432 | struct btrfs_root *root = BTRFS_I(d_inode(dentry))->root; |
458 | int ret; | ||
459 | 433 | ||
460 | /* | ||
461 | * The permission on security.* and system.* is not checked | ||
462 | * in permission(). | ||
463 | */ | ||
464 | if (btrfs_root_readonly(root)) | 434 | if (btrfs_root_readonly(root)) |
465 | return -EROFS; | 435 | return -EROFS; |
466 | 436 | return generic_removexattr(dentry, name); | |
467 | /* | ||
468 | * If this is a request for a synthetic attribute in the system.* | ||
469 | * namespace use the generic infrastructure to resolve a handler | ||
470 | * for it via sb->s_xattr. | ||
471 | */ | ||
472 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
473 | return generic_removexattr(dentry, name); | ||
474 | |||
475 | ret = btrfs_is_valid_xattr(name); | ||
476 | if (ret) | ||
477 | return ret; | ||
478 | |||
479 | if (!strncmp(name, XATTR_BTRFS_PREFIX, XATTR_BTRFS_PREFIX_LEN)) | ||
480 | return btrfs_set_prop(d_inode(dentry), name, | ||
481 | NULL, 0, XATTR_REPLACE); | ||
482 | |||
483 | return __btrfs_setxattr(NULL, d_inode(dentry), name, NULL, 0, | ||
484 | XATTR_REPLACE); | ||
485 | } | 437 | } |
486 | 438 | ||
487 | static int btrfs_initxattrs(struct inode *inode, | 439 | static int btrfs_initxattrs(struct inode *inode, |
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index 5049608d1388..96807b3d22f5 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h | |||
@@ -28,8 +28,6 @@ extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | |||
28 | extern int __btrfs_setxattr(struct btrfs_trans_handle *trans, | 28 | extern int __btrfs_setxattr(struct btrfs_trans_handle *trans, |
29 | struct inode *inode, const char *name, | 29 | struct inode *inode, const char *name, |
30 | const void *value, size_t size, int flags); | 30 | const void *value, size_t size, int flags); |
31 | extern ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, | ||
32 | void *buffer, size_t size); | ||
33 | extern int btrfs_setxattr(struct dentry *dentry, const char *name, | 31 | extern int btrfs_setxattr(struct dentry *dentry, const char *name, |
34 | const void *value, size_t size, int flags); | 32 | const void *value, size_t size, int flags); |
35 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); | 33 | extern int btrfs_removexattr(struct dentry *dentry, const char *name); |