diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-20 08:16:51 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 23:58:22 -0500 |
commit | 2cc6a5a01cdbeb0e46f3aa144819d5d7cee458a1 (patch) | |
tree | d97137eadb3a11dfd12c7bc7bb552ce21e8e4688 /fs/jfs/xattr.c | |
parent | 2401dc2975fc5a33021dc8347ea82984c4707a08 (diff) |
jfs: use generic posix ACL infrastructure
Copy the scheme I introduced to btrfs many years ago to only use the
xattr handler for ACLs, but pass plain attrs straight through.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/jfs/xattr.c')
-rw-r--r-- | fs/jfs/xattr.c | 108 |
1 files changed, 38 insertions, 70 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index d3472f4cd530..5324e4e2b992 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -666,81 +666,12 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, | |||
666 | } | 666 | } |
667 | 667 | ||
668 | /* | 668 | /* |
669 | * can_set_system_xattr | ||
670 | * | ||
671 | * This code is specific to the system.* namespace. It contains policy | ||
672 | * which doesn't belong in the main xattr codepath. | ||
673 | */ | ||
674 | static int can_set_system_xattr(struct inode *inode, const char *name, | ||
675 | const void *value, size_t value_len) | ||
676 | { | ||
677 | #ifdef CONFIG_JFS_POSIX_ACL | ||
678 | struct posix_acl *acl; | ||
679 | int rc; | ||
680 | |||
681 | if (!inode_owner_or_capable(inode)) | ||
682 | return -EPERM; | ||
683 | |||
684 | /* | ||
685 | * POSIX_ACL_XATTR_ACCESS is tied to i_mode | ||
686 | */ | ||
687 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { | ||
688 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); | ||
689 | if (IS_ERR(acl)) { | ||
690 | rc = PTR_ERR(acl); | ||
691 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | ||
692 | rc); | ||
693 | return rc; | ||
694 | } | ||
695 | if (acl) { | ||
696 | rc = posix_acl_equiv_mode(acl, &inode->i_mode); | ||
697 | posix_acl_release(acl); | ||
698 | if (rc < 0) { | ||
699 | printk(KERN_ERR | ||
700 | "posix_acl_equiv_mode returned %d\n", | ||
701 | rc); | ||
702 | return rc; | ||
703 | } | ||
704 | mark_inode_dirty(inode); | ||
705 | } | ||
706 | /* | ||
707 | * We're changing the ACL. Get rid of the cached one | ||
708 | */ | ||
709 | forget_cached_acl(inode, ACL_TYPE_ACCESS); | ||
710 | |||
711 | return 0; | ||
712 | } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { | ||
713 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); | ||
714 | if (IS_ERR(acl)) { | ||
715 | rc = PTR_ERR(acl); | ||
716 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | ||
717 | rc); | ||
718 | return rc; | ||
719 | } | ||
720 | posix_acl_release(acl); | ||
721 | |||
722 | /* | ||
723 | * We're changing the default ACL. Get rid of the cached one | ||
724 | */ | ||
725 | forget_cached_acl(inode, ACL_TYPE_DEFAULT); | ||
726 | |||
727 | return 0; | ||
728 | } | ||
729 | #endif /* CONFIG_JFS_POSIX_ACL */ | ||
730 | return -EOPNOTSUPP; | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * Most of the permission checking is done by xattr_permission in the vfs. | 669 | * Most of the permission checking is done by xattr_permission in the vfs. |
735 | * The local file system is responsible for handling the system.* namespace. | ||
736 | * We also need to verify that this is a namespace that we recognize. | 670 | * We also need to verify that this is a namespace that we recognize. |
737 | */ | 671 | */ |
738 | static int can_set_xattr(struct inode *inode, const char *name, | 672 | static int can_set_xattr(struct inode *inode, const char *name, |
739 | const void *value, size_t value_len) | 673 | const void *value, size_t value_len) |
740 | { | 674 | { |
741 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
742 | return can_set_system_xattr(inode, name, value, value_len); | ||
743 | |||
744 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { | 675 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { |
745 | /* | 676 | /* |
746 | * This makes sure that we aren't trying to set an | 677 | * This makes sure that we aren't trying to set an |
@@ -748,7 +679,7 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
748 | * with "os2." | 679 | * with "os2." |
749 | */ | 680 | */ |
750 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) | 681 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) |
751 | return -EOPNOTSUPP; | 682 | return -EOPNOTSUPP; |
752 | return 0; | 683 | return 0; |
753 | } | 684 | } |
754 | 685 | ||
@@ -913,6 +844,14 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
913 | if ((rc = can_set_xattr(inode, name, value, value_len))) | 844 | if ((rc = can_set_xattr(inode, name, value, value_len))) |
914 | return rc; | 845 | return rc; |
915 | 846 | ||
847 | /* | ||
848 | * If this is a request for a synthetic attribute in the system.* | ||
849 | * namespace use the generic infrastructure to resolve a handler | ||
850 | * for it via sb->s_xattr. | ||
851 | */ | ||
852 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
853 | return generic_setxattr(dentry, name, value, value_len, flags); | ||
854 | |||
916 | if (value == NULL) { /* empty EA, do not remove */ | 855 | if (value == NULL) { /* empty EA, do not remove */ |
917 | value = ""; | 856 | value = ""; |
918 | value_len = 0; | 857 | value_len = 0; |
@@ -986,6 +925,14 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data, | |||
986 | { | 925 | { |
987 | int err; | 926 | int err; |
988 | 927 | ||
928 | /* | ||
929 | * If this is a request for a synthetic attribute in the system.* | ||
930 | * namespace use the generic infrastructure to resolve a handler | ||
931 | * for it via sb->s_xattr. | ||
932 | */ | ||
933 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
934 | return generic_getxattr(dentry, name, data, buf_size); | ||
935 | |||
989 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | 936 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { |
990 | /* | 937 | /* |
991 | * skip past "os2." prefix | 938 | * skip past "os2." prefix |
@@ -1077,6 +1024,14 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1077 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | 1024 | if ((rc = can_set_xattr(inode, name, NULL, 0))) |
1078 | return rc; | 1025 | return rc; |
1079 | 1026 | ||
1027 | /* | ||
1028 | * If this is a request for a synthetic attribute in the system.* | ||
1029 | * namespace use the generic infrastructure to resolve a handler | ||
1030 | * for it via sb->s_xattr. | ||
1031 | */ | ||
1032 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
1033 | return generic_removexattr(dentry, name); | ||
1034 | |||
1080 | tid = txBegin(inode->i_sb, 0); | 1035 | tid = txBegin(inode->i_sb, 0); |
1081 | mutex_lock(&ji->commit_mutex); | 1036 | mutex_lock(&ji->commit_mutex); |
1082 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 1037 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); |
@@ -1088,6 +1043,19 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1088 | return rc; | 1043 | return rc; |
1089 | } | 1044 | } |
1090 | 1045 | ||
1046 | /* | ||
1047 | * List of handlers for synthetic system.* attributes. All real ondisk | ||
1048 | * attributes are handled directly. | ||
1049 | */ | ||
1050 | const struct xattr_handler *jfs_xattr_handlers[] = { | ||
1051 | #ifdef JFS_POSIX_ACL | ||
1052 | &posix_acl_access_xattr_handler, | ||
1053 | &posix_acl_default_xattr_handler, | ||
1054 | #endif | ||
1055 | NULL, | ||
1056 | }; | ||
1057 | |||
1058 | |||
1091 | #ifdef CONFIG_JFS_SECURITY | 1059 | #ifdef CONFIG_JFS_SECURITY |
1092 | static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, | 1060 | static int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array, |
1093 | void *fs_info) | 1061 | void *fs_info) |