diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-04-22 08:43:49 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 22:29:18 -0400 |
commit | c8b6056a504fa384f36e7577fc5a1c1684fcf18a (patch) | |
tree | 9ef7ab6b2ed44a97438d941e576daf7293f4edce | |
parent | 6c8f980c75185f8ba897814363d21882f7453f53 (diff) |
jfs: Switch to generic xattr handlers
This is mostly the same as on other filesystems except for attribute
names with an "os2." prefix: for those, the prefix is not stored on
disk, and on-attribute names without a prefix have "os2." added.
As on several other filesystems, the underlying function for
setting/removing xattrs (__jfs_setxattr) removes attributes when the
value is NULL, so the set xattr handlers will work as expected.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/jfs/file.c | 6 | ||||
-rw-r--r-- | fs/jfs/jfs_xattr.h | 6 | ||||
-rw-r--r-- | fs/jfs/namei.c | 6 | ||||
-rw-r--r-- | fs/jfs/symlink.c | 12 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 170 |
5 files changed, 84 insertions, 116 deletions
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 4ce7735dd042..7f1a585a0a94 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -140,10 +140,10 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | const struct inode_operations jfs_file_inode_operations = { | 142 | const struct inode_operations jfs_file_inode_operations = { |
143 | .setxattr = jfs_setxattr, | 143 | .setxattr = generic_setxattr, |
144 | .getxattr = jfs_getxattr, | 144 | .getxattr = generic_getxattr, |
145 | .listxattr = jfs_listxattr, | 145 | .listxattr = jfs_listxattr, |
146 | .removexattr = jfs_removexattr, | 146 | .removexattr = generic_removexattr, |
147 | .setattr = jfs_setattr, | 147 | .setattr = jfs_setattr, |
148 | #ifdef CONFIG_JFS_POSIX_ACL | 148 | #ifdef CONFIG_JFS_POSIX_ACL |
149 | .get_acl = jfs_get_acl, | 149 | .get_acl = jfs_get_acl, |
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index e69e14f3777b..561f6af46288 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef H_JFS_XATTR | 19 | #ifndef H_JFS_XATTR |
20 | #define H_JFS_XATTR | 20 | #define H_JFS_XATTR |
21 | 21 | ||
22 | #include <linux/xattr.h> | ||
23 | |||
22 | /* | 24 | /* |
23 | * jfs_ea_list describe the on-disk format of the extended attributes. | 25 | * jfs_ea_list describe the on-disk format of the extended attributes. |
24 | * I know the null-terminator is redundant since namelen is stored, but | 26 | * I know the null-terminator is redundant since namelen is stored, but |
@@ -54,12 +56,8 @@ struct jfs_ea_list { | |||
54 | 56 | ||
55 | extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *, | 57 | extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *, |
56 | size_t, int); | 58 | size_t, int); |
57 | extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, | ||
58 | int); | ||
59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); | 59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); |
60 | extern ssize_t jfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); | ||
61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); | 60 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); |
62 | extern int jfs_removexattr(struct dentry *, const char *); | ||
63 | 61 | ||
64 | extern const struct xattr_handler *jfs_xattr_handlers[]; | 62 | extern const struct xattr_handler *jfs_xattr_handlers[]; |
65 | 63 | ||
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 8a40941ac9a6..7040062cb050 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1537,10 +1537,10 @@ const struct inode_operations jfs_dir_inode_operations = { | |||
1537 | .rmdir = jfs_rmdir, | 1537 | .rmdir = jfs_rmdir, |
1538 | .mknod = jfs_mknod, | 1538 | .mknod = jfs_mknod, |
1539 | .rename = jfs_rename, | 1539 | .rename = jfs_rename, |
1540 | .setxattr = jfs_setxattr, | 1540 | .setxattr = generic_setxattr, |
1541 | .getxattr = jfs_getxattr, | 1541 | .getxattr = generic_getxattr, |
1542 | .listxattr = jfs_listxattr, | 1542 | .listxattr = jfs_listxattr, |
1543 | .removexattr = jfs_removexattr, | 1543 | .removexattr = generic_removexattr, |
1544 | .setattr = jfs_setattr, | 1544 | .setattr = jfs_setattr, |
1545 | #ifdef CONFIG_JFS_POSIX_ACL | 1545 | #ifdef CONFIG_JFS_POSIX_ACL |
1546 | .get_acl = jfs_get_acl, | 1546 | .get_acl = jfs_get_acl, |
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index f8db4fde0b0b..c94c7e4a1323 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c | |||
@@ -25,19 +25,19 @@ const struct inode_operations jfs_fast_symlink_inode_operations = { | |||
25 | .readlink = generic_readlink, | 25 | .readlink = generic_readlink, |
26 | .get_link = simple_get_link, | 26 | .get_link = simple_get_link, |
27 | .setattr = jfs_setattr, | 27 | .setattr = jfs_setattr, |
28 | .setxattr = jfs_setxattr, | 28 | .setxattr = generic_setxattr, |
29 | .getxattr = jfs_getxattr, | 29 | .getxattr = generic_getxattr, |
30 | .listxattr = jfs_listxattr, | 30 | .listxattr = jfs_listxattr, |
31 | .removexattr = jfs_removexattr, | 31 | .removexattr = generic_removexattr, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | const struct inode_operations jfs_symlink_inode_operations = { | 34 | const struct inode_operations jfs_symlink_inode_operations = { |
35 | .readlink = generic_readlink, | 35 | .readlink = generic_readlink, |
36 | .get_link = page_get_link, | 36 | .get_link = page_get_link, |
37 | .setattr = jfs_setattr, | 37 | .setattr = jfs_setattr, |
38 | .setxattr = jfs_setxattr, | 38 | .setxattr = generic_setxattr, |
39 | .getxattr = jfs_getxattr, | 39 | .getxattr = generic_getxattr, |
40 | .listxattr = jfs_listxattr, | 40 | .listxattr = jfs_listxattr, |
41 | .removexattr = jfs_removexattr, | 41 | .removexattr = generic_removexattr, |
42 | }; | 42 | }; |
43 | 43 | ||
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 9cdf7dc4d5cb..beb182b503b3 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -663,30 +663,6 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, | |||
663 | return 0; | 663 | return 0; |
664 | } | 664 | } |
665 | 665 | ||
666 | /* | ||
667 | * Most of the permission checking is done by xattr_permission in the vfs. | ||
668 | * We also need to verify that this is a namespace that we recognize. | ||
669 | */ | ||
670 | static bool map_name_to_disk(const char **name) | ||
671 | { | ||
672 | if (!strncmp(*name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { | ||
673 | /* | ||
674 | * This makes sure that we aren't trying to set an | ||
675 | * attribute in a different namespace by prefixing it | ||
676 | * with "os2." | ||
677 | */ | ||
678 | if (is_known_namespace(*name + XATTR_OS2_PREFIX_LEN)) | ||
679 | return false; | ||
680 | *name += XATTR_OS2_PREFIX_LEN; | ||
681 | return true; | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * Don't allow setting an attribute in an unknown namespace. | ||
686 | */ | ||
687 | return is_known_namespace(*name); | ||
688 | } | ||
689 | |||
690 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | 666 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, |
691 | const void *value, size_t value_len, int flags) | 667 | const void *value, size_t value_len, int flags) |
692 | { | 668 | { |
@@ -826,42 +802,6 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, | |||
826 | return rc; | 802 | return rc; |
827 | } | 803 | } |
828 | 804 | ||
829 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
830 | size_t value_len, int flags) | ||
831 | { | ||
832 | struct inode *inode = d_inode(dentry); | ||
833 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
834 | int rc; | ||
835 | tid_t tid; | ||
836 | |||
837 | /* | ||
838 | * If this is a request for a synthetic attribute in the system.* | ||
839 | * namespace use the generic infrastructure to resolve a handler | ||
840 | * for it via sb->s_xattr. | ||
841 | */ | ||
842 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
843 | return generic_setxattr(dentry, name, value, value_len, flags); | ||
844 | |||
845 | if (!map_name_to_disk(&name)) | ||
846 | return -EOPNOTSUPP; | ||
847 | |||
848 | if (value == NULL) { /* empty EA, do not remove */ | ||
849 | value = ""; | ||
850 | value_len = 0; | ||
851 | } | ||
852 | |||
853 | tid = txBegin(inode->i_sb, 0); | ||
854 | mutex_lock(&ji->commit_mutex); | ||
855 | rc = __jfs_setxattr(tid, d_inode(dentry), name, value, value_len, | ||
856 | flags); | ||
857 | if (!rc) | ||
858 | rc = txCommit(tid, 1, &inode, 0); | ||
859 | txEnd(tid); | ||
860 | mutex_unlock(&ji->commit_mutex); | ||
861 | |||
862 | return rc; | ||
863 | } | ||
864 | |||
865 | ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, | 805 | ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, |
866 | size_t buf_size) | 806 | size_t buf_size) |
867 | { | 807 | { |
@@ -913,27 +853,6 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, | |||
913 | return size; | 853 | return size; |
914 | } | 854 | } |
915 | 855 | ||
916 | ssize_t jfs_getxattr(struct dentry *dentry, struct inode *inode, | ||
917 | const char *name, void *data, size_t buf_size) | ||
918 | { | ||
919 | int err; | ||
920 | |||
921 | /* | ||
922 | * If this is a request for a synthetic attribute in the system.* | ||
923 | * namespace use the generic infrastructure to resolve a handler | ||
924 | * for it via sb->s_xattr. | ||
925 | */ | ||
926 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
927 | return generic_getxattr(dentry, inode, name, data, buf_size); | ||
928 | |||
929 | if (!map_name_to_disk(&name)) | ||
930 | return -EOPNOTSUPP; | ||
931 | |||
932 | err = __jfs_getxattr(inode, name, data, buf_size); | ||
933 | |||
934 | return err; | ||
935 | } | ||
936 | |||
937 | /* | 856 | /* |
938 | * No special permissions are needed to list attributes except for trusted.* | 857 | * No special permissions are needed to list attributes except for trusted.* |
939 | */ | 858 | */ |
@@ -997,27 +916,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) | |||
997 | return size; | 916 | return size; |
998 | } | 917 | } |
999 | 918 | ||
1000 | int jfs_removexattr(struct dentry *dentry, const char *name) | 919 | static int __jfs_xattr_set(struct inode *inode, const char *name, |
920 | const void *value, size_t size, int flags) | ||
1001 | { | 921 | { |
1002 | struct inode *inode = d_inode(dentry); | ||
1003 | struct jfs_inode_info *ji = JFS_IP(inode); | 922 | struct jfs_inode_info *ji = JFS_IP(inode); |
1004 | int rc; | ||
1005 | tid_t tid; | 923 | tid_t tid; |
1006 | 924 | int rc; | |
1007 | /* | ||
1008 | * If this is a request for a synthetic attribute in the system.* | ||
1009 | * namespace use the generic infrastructure to resolve a handler | ||
1010 | * for it via sb->s_xattr. | ||
1011 | */ | ||
1012 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
1013 | return generic_removexattr(dentry, name); | ||
1014 | |||
1015 | if (!map_name_to_disk(&name)) | ||
1016 | return -EOPNOTSUPP; | ||
1017 | 925 | ||
1018 | tid = txBegin(inode->i_sb, 0); | 926 | tid = txBegin(inode->i_sb, 0); |
1019 | mutex_lock(&ji->commit_mutex); | 927 | mutex_lock(&ji->commit_mutex); |
1020 | rc = __jfs_setxattr(tid, d_inode(dentry), name, NULL, 0, XATTR_REPLACE); | 928 | rc = __jfs_setxattr(tid, inode, name, value, size, flags); |
1021 | if (!rc) | 929 | if (!rc) |
1022 | rc = txCommit(tid, 1, &inode, 0); | 930 | rc = txCommit(tid, 1, &inode, 0); |
1023 | txEnd(tid); | 931 | txEnd(tid); |
@@ -1026,15 +934,77 @@ int jfs_removexattr(struct dentry *dentry, const char *name) | |||
1026 | return rc; | 934 | return rc; |
1027 | } | 935 | } |
1028 | 936 | ||
1029 | /* | 937 | static int jfs_xattr_get(const struct xattr_handler *handler, |
1030 | * List of handlers for synthetic system.* attributes. All real ondisk | 938 | struct dentry *unused, struct inode *inode, |
1031 | * attributes are handled directly. | 939 | const char *name, void *value, size_t size) |
1032 | */ | 940 | { |
941 | name = xattr_full_name(handler, name); | ||
942 | return __jfs_getxattr(inode, name, value, size); | ||
943 | } | ||
944 | |||
945 | static int jfs_xattr_set(const struct xattr_handler *handler, | ||
946 | struct dentry *dentry, const char *name, | ||
947 | const void *value, size_t size, int flags) | ||
948 | { | ||
949 | struct inode *inode = d_inode(dentry); | ||
950 | |||
951 | name = xattr_full_name(handler, name); | ||
952 | return __jfs_xattr_set(inode, name, value, size, flags); | ||
953 | } | ||
954 | |||
955 | static int jfs_xattr_get_os2(const struct xattr_handler *handler, | ||
956 | struct dentry *unused, struct inode *inode, | ||
957 | const char *name, void *value, size_t size) | ||
958 | { | ||
959 | if (is_known_namespace(name)) | ||
960 | return -EOPNOTSUPP; | ||
961 | return __jfs_getxattr(inode, name, value, size); | ||
962 | } | ||
963 | |||
964 | static int jfs_xattr_set_os2(const struct xattr_handler *handler, | ||
965 | struct dentry *dentry, const char *name, | ||
966 | const void *value, size_t size, int flags) | ||
967 | { | ||
968 | struct inode *inode = d_inode(dentry); | ||
969 | |||
970 | if (is_known_namespace(name)) | ||
971 | return -EOPNOTSUPP; | ||
972 | return __jfs_xattr_set(inode, name, value, size, flags); | ||
973 | } | ||
974 | |||
975 | static const struct xattr_handler jfs_user_xattr_handler = { | ||
976 | .prefix = XATTR_USER_PREFIX, | ||
977 | .get = jfs_xattr_get, | ||
978 | .set = jfs_xattr_set, | ||
979 | }; | ||
980 | |||
981 | static const struct xattr_handler jfs_os2_xattr_handler = { | ||
982 | .prefix = XATTR_OS2_PREFIX, | ||
983 | .get = jfs_xattr_get_os2, | ||
984 | .set = jfs_xattr_set_os2, | ||
985 | }; | ||
986 | |||
987 | static const struct xattr_handler jfs_security_xattr_handler = { | ||
988 | .prefix = XATTR_SECURITY_PREFIX, | ||
989 | .get = jfs_xattr_get, | ||
990 | .set = jfs_xattr_set, | ||
991 | }; | ||
992 | |||
993 | static const struct xattr_handler jfs_trusted_xattr_handler = { | ||
994 | .prefix = XATTR_TRUSTED_PREFIX, | ||
995 | .get = jfs_xattr_get, | ||
996 | .set = jfs_xattr_set, | ||
997 | }; | ||
998 | |||
1033 | const struct xattr_handler *jfs_xattr_handlers[] = { | 999 | const struct xattr_handler *jfs_xattr_handlers[] = { |
1034 | #ifdef CONFIG_JFS_POSIX_ACL | 1000 | #ifdef CONFIG_JFS_POSIX_ACL |
1035 | &posix_acl_access_xattr_handler, | 1001 | &posix_acl_access_xattr_handler, |
1036 | &posix_acl_default_xattr_handler, | 1002 | &posix_acl_default_xattr_handler, |
1037 | #endif | 1003 | #endif |
1004 | &jfs_os2_xattr_handler, | ||
1005 | &jfs_user_xattr_handler, | ||
1006 | &jfs_security_xattr_handler, | ||
1007 | &jfs_trusted_xattr_handler, | ||
1038 | NULL, | 1008 | NULL, |
1039 | }; | 1009 | }; |
1040 | 1010 | ||