diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-12-02 08:44:38 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-12-06 21:34:15 -0500 |
commit | aa7c5241c380adb7e6913549292c1b83c1469bda (patch) | |
tree | 4247a21eb6370450bfa78ea6f513e560ce334900 /mm/shmem.c | |
parent | 9172abbcd371f2f62903087bbd228f11d380b7b4 (diff) |
tmpfs: Use xattr handler infrastructure
Use the VFS xattr handler infrastructure and get rid of similar code in
the filesystem. For implementing shmem_xattr_handler_set, we need a
version of simple_xattr_set which removes the attribute when value is
NULL. Use this to implement kernfs_iop_removexattr as well.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: James Morris <james.l.morris@oracle.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 131 |
1 files changed, 42 insertions, 89 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 9187eee4128b..fdfe6c8dddfc 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2561,94 +2561,47 @@ static int shmem_initxattrs(struct inode *inode, | |||
2561 | return 0; | 2561 | return 0; |
2562 | } | 2562 | } |
2563 | 2563 | ||
2564 | static const struct xattr_handler *shmem_xattr_handlers[] = { | 2564 | static int shmem_xattr_handler_get(const struct xattr_handler *handler, |
2565 | #ifdef CONFIG_TMPFS_POSIX_ACL | 2565 | struct dentry *dentry, const char *name, |
2566 | &posix_acl_access_xattr_handler, | 2566 | void *buffer, size_t size) |
2567 | &posix_acl_default_xattr_handler, | ||
2568 | #endif | ||
2569 | NULL | ||
2570 | }; | ||
2571 | |||
2572 | static int shmem_xattr_validate(const char *name) | ||
2573 | { | ||
2574 | struct { const char *prefix; size_t len; } arr[] = { | ||
2575 | { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, | ||
2576 | { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } | ||
2577 | }; | ||
2578 | int i; | ||
2579 | |||
2580 | for (i = 0; i < ARRAY_SIZE(arr); i++) { | ||
2581 | size_t preflen = arr[i].len; | ||
2582 | if (strncmp(name, arr[i].prefix, preflen) == 0) { | ||
2583 | if (!name[preflen]) | ||
2584 | return -EINVAL; | ||
2585 | return 0; | ||
2586 | } | ||
2587 | } | ||
2588 | return -EOPNOTSUPP; | ||
2589 | } | ||
2590 | |||
2591 | static ssize_t shmem_getxattr(struct dentry *dentry, const char *name, | ||
2592 | void *buffer, size_t size) | ||
2593 | { | 2567 | { |
2594 | struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); | 2568 | struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); |
2595 | int err; | ||
2596 | |||
2597 | /* | ||
2598 | * If this is a request for a synthetic attribute in the system.* | ||
2599 | * namespace use the generic infrastructure to resolve a handler | ||
2600 | * for it via sb->s_xattr. | ||
2601 | */ | ||
2602 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
2603 | return generic_getxattr(dentry, name, buffer, size); | ||
2604 | |||
2605 | err = shmem_xattr_validate(name); | ||
2606 | if (err) | ||
2607 | return err; | ||
2608 | 2569 | ||
2570 | name = xattr_full_name(handler, name); | ||
2609 | return simple_xattr_get(&info->xattrs, name, buffer, size); | 2571 | return simple_xattr_get(&info->xattrs, name, buffer, size); |
2610 | } | 2572 | } |
2611 | 2573 | ||
2612 | static int shmem_setxattr(struct dentry *dentry, const char *name, | 2574 | static int shmem_xattr_handler_set(const struct xattr_handler *handler, |
2613 | const void *value, size_t size, int flags) | 2575 | struct dentry *dentry, const char *name, |
2576 | const void *value, size_t size, int flags) | ||
2614 | { | 2577 | { |
2615 | struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); | 2578 | struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); |
2616 | int err; | ||
2617 | |||
2618 | /* | ||
2619 | * If this is a request for a synthetic attribute in the system.* | ||
2620 | * namespace use the generic infrastructure to resolve a handler | ||
2621 | * for it via sb->s_xattr. | ||
2622 | */ | ||
2623 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
2624 | return generic_setxattr(dentry, name, value, size, flags); | ||
2625 | |||
2626 | err = shmem_xattr_validate(name); | ||
2627 | if (err) | ||
2628 | return err; | ||
2629 | 2579 | ||
2580 | name = xattr_full_name(handler, name); | ||
2630 | return simple_xattr_set(&info->xattrs, name, value, size, flags); | 2581 | return simple_xattr_set(&info->xattrs, name, value, size, flags); |
2631 | } | 2582 | } |
2632 | 2583 | ||
2633 | static int shmem_removexattr(struct dentry *dentry, const char *name) | 2584 | static const struct xattr_handler shmem_security_xattr_handler = { |
2634 | { | 2585 | .prefix = XATTR_SECURITY_PREFIX, |
2635 | struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); | 2586 | .get = shmem_xattr_handler_get, |
2636 | int err; | 2587 | .set = shmem_xattr_handler_set, |
2637 | 2588 | }; | |
2638 | /* | ||
2639 | * If this is a request for a synthetic attribute in the system.* | ||
2640 | * namespace use the generic infrastructure to resolve a handler | ||
2641 | * for it via sb->s_xattr. | ||
2642 | */ | ||
2643 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
2644 | return generic_removexattr(dentry, name); | ||
2645 | 2589 | ||
2646 | err = shmem_xattr_validate(name); | 2590 | static const struct xattr_handler shmem_trusted_xattr_handler = { |
2647 | if (err) | 2591 | .prefix = XATTR_TRUSTED_PREFIX, |
2648 | return err; | 2592 | .get = shmem_xattr_handler_get, |
2593 | .set = shmem_xattr_handler_set, | ||
2594 | }; | ||
2649 | 2595 | ||
2650 | return simple_xattr_remove(&info->xattrs, name); | 2596 | static const struct xattr_handler *shmem_xattr_handlers[] = { |
2651 | } | 2597 | #ifdef CONFIG_TMPFS_POSIX_ACL |
2598 | &posix_acl_access_xattr_handler, | ||
2599 | &posix_acl_default_xattr_handler, | ||
2600 | #endif | ||
2601 | &shmem_security_xattr_handler, | ||
2602 | &shmem_trusted_xattr_handler, | ||
2603 | NULL | ||
2604 | }; | ||
2652 | 2605 | ||
2653 | static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) | 2606 | static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) |
2654 | { | 2607 | { |
@@ -2661,10 +2614,10 @@ static const struct inode_operations shmem_short_symlink_operations = { | |||
2661 | .readlink = generic_readlink, | 2614 | .readlink = generic_readlink, |
2662 | .follow_link = simple_follow_link, | 2615 | .follow_link = simple_follow_link, |
2663 | #ifdef CONFIG_TMPFS_XATTR | 2616 | #ifdef CONFIG_TMPFS_XATTR |
2664 | .setxattr = shmem_setxattr, | 2617 | .setxattr = generic_setxattr, |
2665 | .getxattr = shmem_getxattr, | 2618 | .getxattr = generic_getxattr, |
2666 | .listxattr = shmem_listxattr, | 2619 | .listxattr = shmem_listxattr, |
2667 | .removexattr = shmem_removexattr, | 2620 | .removexattr = generic_removexattr, |
2668 | #endif | 2621 | #endif |
2669 | }; | 2622 | }; |
2670 | 2623 | ||
@@ -2673,10 +2626,10 @@ static const struct inode_operations shmem_symlink_inode_operations = { | |||
2673 | .follow_link = shmem_follow_link, | 2626 | .follow_link = shmem_follow_link, |
2674 | .put_link = shmem_put_link, | 2627 | .put_link = shmem_put_link, |
2675 | #ifdef CONFIG_TMPFS_XATTR | 2628 | #ifdef CONFIG_TMPFS_XATTR |
2676 | .setxattr = shmem_setxattr, | 2629 | .setxattr = generic_setxattr, |
2677 | .getxattr = shmem_getxattr, | 2630 | .getxattr = generic_getxattr, |
2678 | .listxattr = shmem_listxattr, | 2631 | .listxattr = shmem_listxattr, |
2679 | .removexattr = shmem_removexattr, | 2632 | .removexattr = generic_removexattr, |
2680 | #endif | 2633 | #endif |
2681 | }; | 2634 | }; |
2682 | 2635 | ||
@@ -3148,10 +3101,10 @@ static const struct inode_operations shmem_inode_operations = { | |||
3148 | .getattr = shmem_getattr, | 3101 | .getattr = shmem_getattr, |
3149 | .setattr = shmem_setattr, | 3102 | .setattr = shmem_setattr, |
3150 | #ifdef CONFIG_TMPFS_XATTR | 3103 | #ifdef CONFIG_TMPFS_XATTR |
3151 | .setxattr = shmem_setxattr, | 3104 | .setxattr = generic_setxattr, |
3152 | .getxattr = shmem_getxattr, | 3105 | .getxattr = generic_getxattr, |
3153 | .listxattr = shmem_listxattr, | 3106 | .listxattr = shmem_listxattr, |
3154 | .removexattr = shmem_removexattr, | 3107 | .removexattr = generic_removexattr, |
3155 | .set_acl = simple_set_acl, | 3108 | .set_acl = simple_set_acl, |
3156 | #endif | 3109 | #endif |
3157 | }; | 3110 | }; |
@@ -3170,10 +3123,10 @@ static const struct inode_operations shmem_dir_inode_operations = { | |||
3170 | .tmpfile = shmem_tmpfile, | 3123 | .tmpfile = shmem_tmpfile, |
3171 | #endif | 3124 | #endif |
3172 | #ifdef CONFIG_TMPFS_XATTR | 3125 | #ifdef CONFIG_TMPFS_XATTR |
3173 | .setxattr = shmem_setxattr, | 3126 | .setxattr = generic_setxattr, |
3174 | .getxattr = shmem_getxattr, | 3127 | .getxattr = generic_getxattr, |
3175 | .listxattr = shmem_listxattr, | 3128 | .listxattr = shmem_listxattr, |
3176 | .removexattr = shmem_removexattr, | 3129 | .removexattr = generic_removexattr, |
3177 | #endif | 3130 | #endif |
3178 | #ifdef CONFIG_TMPFS_POSIX_ACL | 3131 | #ifdef CONFIG_TMPFS_POSIX_ACL |
3179 | .setattr = shmem_setattr, | 3132 | .setattr = shmem_setattr, |
@@ -3183,10 +3136,10 @@ static const struct inode_operations shmem_dir_inode_operations = { | |||
3183 | 3136 | ||
3184 | static const struct inode_operations shmem_special_inode_operations = { | 3137 | static const struct inode_operations shmem_special_inode_operations = { |
3185 | #ifdef CONFIG_TMPFS_XATTR | 3138 | #ifdef CONFIG_TMPFS_XATTR |
3186 | .setxattr = shmem_setxattr, | 3139 | .setxattr = generic_setxattr, |
3187 | .getxattr = shmem_getxattr, | 3140 | .getxattr = generic_getxattr, |
3188 | .listxattr = shmem_listxattr, | 3141 | .listxattr = shmem_listxattr, |
3189 | .removexattr = shmem_removexattr, | 3142 | .removexattr = generic_removexattr, |
3190 | #endif | 3143 | #endif |
3191 | #ifdef CONFIG_TMPFS_POSIX_ACL | 3144 | #ifdef CONFIG_TMPFS_POSIX_ACL |
3192 | .setattr = shmem_setattr, | 3145 | .setattr = shmem_setattr, |