diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 20:11:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-10 20:11:50 -0400 |
commit | 97d2116708ca0fd6ad8b00811ee4349b7e19e96f (patch) | |
tree | 81f73fc1a6daee60737b591cf1be73cc4f79de37 /fs | |
parent | 30066ce675d3af350bc5a53858991c0b518dda00 (diff) | |
parent | fd50ecaddf8372a1d96e0daeaac0f93cf04e4d42 (diff) |
Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro:
"xattr stuff from Andreas
This completes the switch to xattr_handler ->get()/->set() from
->getxattr/->setxattr/->removexattr"
* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Remove {get,set,remove}xattr inode operations
xattr: Stop calling {get,set,remove}xattr inode operations
vfs: Check for the IOP_XATTR flag in listxattr
xattr: Add __vfs_{get,set,remove}xattr helpers
libfs: Use IOP_XATTR flag for empty directory handling
vfs: Use IOP_XATTR flag for bad-inode handling
vfs: Add IOP_XATTR inode operations flag
vfs: Move xattr_resolve_name to the front of fs/xattr.c
ecryptfs: Switch to generic xattr handlers
sockfs: Get rid of getxattr iop
sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names
kernfs: Switch to generic xattr handlers
hfs: Switch to generic xattr handlers
jffs2: Remove jffs2_{get,set,remove}xattr macros
xattr: Remove unnecessary NULL attribute name check
Diffstat (limited to 'fs')
65 files changed, 338 insertions, 545 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 0e6ad3019711..afaa4b6de801 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -967,9 +967,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { | |||
967 | .rename = v9fs_vfs_rename, | 967 | .rename = v9fs_vfs_rename, |
968 | .getattr = v9fs_vfs_getattr_dotl, | 968 | .getattr = v9fs_vfs_getattr_dotl, |
969 | .setattr = v9fs_vfs_setattr_dotl, | 969 | .setattr = v9fs_vfs_setattr_dotl, |
970 | .setxattr = generic_setxattr, | ||
971 | .getxattr = generic_getxattr, | ||
972 | .removexattr = generic_removexattr, | ||
973 | .listxattr = v9fs_listxattr, | 970 | .listxattr = v9fs_listxattr, |
974 | .get_acl = v9fs_iop_get_acl, | 971 | .get_acl = v9fs_iop_get_acl, |
975 | }; | 972 | }; |
@@ -977,9 +974,6 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { | |||
977 | const struct inode_operations v9fs_file_inode_operations_dotl = { | 974 | const struct inode_operations v9fs_file_inode_operations_dotl = { |
978 | .getattr = v9fs_vfs_getattr_dotl, | 975 | .getattr = v9fs_vfs_getattr_dotl, |
979 | .setattr = v9fs_vfs_setattr_dotl, | 976 | .setattr = v9fs_vfs_setattr_dotl, |
980 | .setxattr = generic_setxattr, | ||
981 | .getxattr = generic_getxattr, | ||
982 | .removexattr = generic_removexattr, | ||
983 | .listxattr = v9fs_listxattr, | 977 | .listxattr = v9fs_listxattr, |
984 | .get_acl = v9fs_iop_get_acl, | 978 | .get_acl = v9fs_iop_get_acl, |
985 | }; | 979 | }; |
@@ -989,8 +983,5 @@ const struct inode_operations v9fs_symlink_inode_operations_dotl = { | |||
989 | .get_link = v9fs_vfs_get_link_dotl, | 983 | .get_link = v9fs_vfs_get_link_dotl, |
990 | .getattr = v9fs_vfs_getattr_dotl, | 984 | .getattr = v9fs_vfs_getattr_dotl, |
991 | .setattr = v9fs_vfs_setattr_dotl, | 985 | .setattr = v9fs_vfs_setattr_dotl, |
992 | .setxattr = generic_setxattr, | ||
993 | .getxattr = generic_getxattr, | ||
994 | .removexattr = generic_removexattr, | ||
995 | .listxattr = v9fs_listxattr, | 986 | .listxattr = v9fs_listxattr, |
996 | }; | 987 | }; |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 3ba385eaa26e..7bb153c33459 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -100,29 +100,12 @@ static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs) | |||
100 | return -EIO; | 100 | return -EIO; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int bad_inode_setxattr(struct dentry *dentry, struct inode *inode, | ||
104 | const char *name, const void *value, size_t size, int flags) | ||
105 | { | ||
106 | return -EIO; | ||
107 | } | ||
108 | |||
109 | static ssize_t bad_inode_getxattr(struct dentry *dentry, struct inode *inode, | ||
110 | const char *name, void *buffer, size_t size) | ||
111 | { | ||
112 | return -EIO; | ||
113 | } | ||
114 | |||
115 | static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer, | 103 | static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer, |
116 | size_t buffer_size) | 104 | size_t buffer_size) |
117 | { | 105 | { |
118 | return -EIO; | 106 | return -EIO; |
119 | } | 107 | } |
120 | 108 | ||
121 | static int bad_inode_removexattr(struct dentry *dentry, const char *name) | ||
122 | { | ||
123 | return -EIO; | ||
124 | } | ||
125 | |||
126 | static const struct inode_operations bad_inode_ops = | 109 | static const struct inode_operations bad_inode_ops = |
127 | { | 110 | { |
128 | .create = bad_inode_create, | 111 | .create = bad_inode_create, |
@@ -142,10 +125,7 @@ static const struct inode_operations bad_inode_ops = | |||
142 | .permission = bad_inode_permission, | 125 | .permission = bad_inode_permission, |
143 | .getattr = bad_inode_getattr, | 126 | .getattr = bad_inode_getattr, |
144 | .setattr = bad_inode_setattr, | 127 | .setattr = bad_inode_setattr, |
145 | .setxattr = bad_inode_setxattr, | ||
146 | .getxattr = bad_inode_getxattr, | ||
147 | .listxattr = bad_inode_listxattr, | 128 | .listxattr = bad_inode_listxattr, |
148 | .removexattr = bad_inode_removexattr, | ||
149 | }; | 129 | }; |
150 | 130 | ||
151 | 131 | ||
@@ -175,6 +155,7 @@ void make_bad_inode(struct inode *inode) | |||
175 | inode->i_atime = inode->i_mtime = inode->i_ctime = | 155 | inode->i_atime = inode->i_mtime = inode->i_ctime = |
176 | current_fs_time(inode->i_sb); | 156 | current_fs_time(inode->i_sb); |
177 | inode->i_op = &bad_inode_ops; | 157 | inode->i_op = &bad_inode_ops; |
158 | inode->i_opflags &= ~IOP_XATTR; | ||
178 | inode->i_fop = &bad_file_ops; | 159 | inode->i_fop = &bad_file_ops; |
179 | } | 160 | } |
180 | EXPORT_SYMBOL(make_bad_inode); | 161 | EXPORT_SYMBOL(make_bad_inode); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index a0d3016f6c26..994fe5af160b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -10556,10 +10556,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { | |||
10556 | .symlink = btrfs_symlink, | 10556 | .symlink = btrfs_symlink, |
10557 | .setattr = btrfs_setattr, | 10557 | .setattr = btrfs_setattr, |
10558 | .mknod = btrfs_mknod, | 10558 | .mknod = btrfs_mknod, |
10559 | .setxattr = generic_setxattr, | ||
10560 | .getxattr = generic_getxattr, | ||
10561 | .listxattr = btrfs_listxattr, | 10559 | .listxattr = btrfs_listxattr, |
10562 | .removexattr = generic_removexattr, | ||
10563 | .permission = btrfs_permission, | 10560 | .permission = btrfs_permission, |
10564 | .get_acl = btrfs_get_acl, | 10561 | .get_acl = btrfs_get_acl, |
10565 | .set_acl = btrfs_set_acl, | 10562 | .set_acl = btrfs_set_acl, |
@@ -10633,10 +10630,7 @@ static const struct address_space_operations btrfs_symlink_aops = { | |||
10633 | static const struct inode_operations btrfs_file_inode_operations = { | 10630 | static const struct inode_operations btrfs_file_inode_operations = { |
10634 | .getattr = btrfs_getattr, | 10631 | .getattr = btrfs_getattr, |
10635 | .setattr = btrfs_setattr, | 10632 | .setattr = btrfs_setattr, |
10636 | .setxattr = generic_setxattr, | ||
10637 | .getxattr = generic_getxattr, | ||
10638 | .listxattr = btrfs_listxattr, | 10633 | .listxattr = btrfs_listxattr, |
10639 | .removexattr = generic_removexattr, | ||
10640 | .permission = btrfs_permission, | 10634 | .permission = btrfs_permission, |
10641 | .fiemap = btrfs_fiemap, | 10635 | .fiemap = btrfs_fiemap, |
10642 | .get_acl = btrfs_get_acl, | 10636 | .get_acl = btrfs_get_acl, |
@@ -10647,10 +10641,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
10647 | .getattr = btrfs_getattr, | 10641 | .getattr = btrfs_getattr, |
10648 | .setattr = btrfs_setattr, | 10642 | .setattr = btrfs_setattr, |
10649 | .permission = btrfs_permission, | 10643 | .permission = btrfs_permission, |
10650 | .setxattr = generic_setxattr, | ||
10651 | .getxattr = generic_getxattr, | ||
10652 | .listxattr = btrfs_listxattr, | 10644 | .listxattr = btrfs_listxattr, |
10653 | .removexattr = generic_removexattr, | ||
10654 | .get_acl = btrfs_get_acl, | 10645 | .get_acl = btrfs_get_acl, |
10655 | .set_acl = btrfs_set_acl, | 10646 | .set_acl = btrfs_set_acl, |
10656 | .update_time = btrfs_update_time, | 10647 | .update_time = btrfs_update_time, |
@@ -10661,10 +10652,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
10661 | .getattr = btrfs_getattr, | 10652 | .getattr = btrfs_getattr, |
10662 | .setattr = btrfs_setattr, | 10653 | .setattr = btrfs_setattr, |
10663 | .permission = btrfs_permission, | 10654 | .permission = btrfs_permission, |
10664 | .setxattr = generic_setxattr, | ||
10665 | .getxattr = generic_getxattr, | ||
10666 | .listxattr = btrfs_listxattr, | 10655 | .listxattr = btrfs_listxattr, |
10667 | .removexattr = generic_removexattr, | ||
10668 | .update_time = btrfs_update_time, | 10656 | .update_time = btrfs_update_time, |
10669 | }; | 10657 | }; |
10670 | 10658 | ||
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 6af790fc3df8..3ff867f87d73 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mount.h> | 20 | #include <linux/mount.h> |
21 | #include <linux/statfs.h> | 21 | #include <linux/statfs.h> |
22 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
23 | #include <linux/xattr.h> | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | 25 | ||
25 | static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches); | 26 | static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches); |
@@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) | |||
126 | if (d_is_negative(root) || | 127 | if (d_is_negative(root) || |
127 | !d_backing_inode(root)->i_op->lookup || | 128 | !d_backing_inode(root)->i_op->lookup || |
128 | !d_backing_inode(root)->i_op->mkdir || | 129 | !d_backing_inode(root)->i_op->mkdir || |
129 | !d_backing_inode(root)->i_op->setxattr || | 130 | !(d_backing_inode(root)->i_opflags & IOP_XATTR) || |
130 | !d_backing_inode(root)->i_op->getxattr || | ||
131 | !root->d_sb->s_op->statfs || | 131 | !root->d_sb->s_op->statfs || |
132 | !root->d_sb->s_op->sync_fs) | 132 | !root->d_sb->s_op->sync_fs) |
133 | goto error_unsupported; | 133 | goto error_unsupported; |
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index c6ee4b5fb7e6..339c910da916 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/namei.h> | 20 | #include <linux/namei.h> |
21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/xattr.h> | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | 25 | ||
25 | #define CACHEFILES_KEYBUF_SIZE 512 | 26 | #define CACHEFILES_KEYBUF_SIZE 512 |
@@ -799,8 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, | |||
799 | } | 800 | } |
800 | 801 | ||
801 | ret = -EPERM; | 802 | ret = -EPERM; |
802 | if (!d_backing_inode(subdir)->i_op->setxattr || | 803 | if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) || |
803 | !d_backing_inode(subdir)->i_op->getxattr || | ||
804 | !d_backing_inode(subdir)->i_op->lookup || | 804 | !d_backing_inode(subdir)->i_op->lookup || |
805 | !d_backing_inode(subdir)->i_op->mkdir || | 805 | !d_backing_inode(subdir)->i_op->mkdir || |
806 | !d_backing_inode(subdir)->i_op->create || | 806 | !d_backing_inode(subdir)->i_op->create || |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index df4b3e6fa563..e33bd0933396 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1486,10 +1486,7 @@ const struct inode_operations ceph_dir_iops = { | |||
1486 | .permission = ceph_permission, | 1486 | .permission = ceph_permission, |
1487 | .getattr = ceph_getattr, | 1487 | .getattr = ceph_getattr, |
1488 | .setattr = ceph_setattr, | 1488 | .setattr = ceph_setattr, |
1489 | .setxattr = generic_setxattr, | ||
1490 | .getxattr = generic_getxattr, | ||
1491 | .listxattr = ceph_listxattr, | 1489 | .listxattr = ceph_listxattr, |
1492 | .removexattr = generic_removexattr, | ||
1493 | .get_acl = ceph_get_acl, | 1490 | .get_acl = ceph_get_acl, |
1494 | .set_acl = ceph_set_acl, | 1491 | .set_acl = ceph_set_acl, |
1495 | .mknod = ceph_mknod, | 1492 | .mknod = ceph_mknod, |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 082e82dcbaa4..da00b11d4a7a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -94,10 +94,7 @@ const struct inode_operations ceph_file_iops = { | |||
94 | .permission = ceph_permission, | 94 | .permission = ceph_permission, |
95 | .setattr = ceph_setattr, | 95 | .setattr = ceph_setattr, |
96 | .getattr = ceph_getattr, | 96 | .getattr = ceph_getattr, |
97 | .setxattr = generic_setxattr, | ||
98 | .getxattr = generic_getxattr, | ||
99 | .listxattr = ceph_listxattr, | 97 | .listxattr = ceph_listxattr, |
100 | .removexattr = generic_removexattr, | ||
101 | .get_acl = ceph_get_acl, | 98 | .get_acl = ceph_get_acl, |
102 | .set_acl = ceph_set_acl, | 99 | .set_acl = ceph_set_acl, |
103 | }; | 100 | }; |
@@ -1885,10 +1882,7 @@ static const struct inode_operations ceph_symlink_iops = { | |||
1885 | .get_link = simple_get_link, | 1882 | .get_link = simple_get_link, |
1886 | .setattr = ceph_setattr, | 1883 | .setattr = ceph_setattr, |
1887 | .getattr = ceph_getattr, | 1884 | .getattr = ceph_getattr, |
1888 | .setxattr = generic_setxattr, | ||
1889 | .getxattr = generic_getxattr, | ||
1890 | .listxattr = ceph_listxattr, | 1885 | .listxattr = ceph_listxattr, |
1891 | .removexattr = generic_removexattr, | ||
1892 | }; | 1886 | }; |
1893 | 1887 | ||
1894 | int __ceph_setattr(struct inode *inode, struct iattr *attr) | 1888 | int __ceph_setattr(struct inode *inode, struct iattr *attr) |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 14ae4b8e1a3c..34aac1c73ee1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -901,30 +901,21 @@ const struct inode_operations cifs_dir_inode_ops = { | |||
901 | .setattr = cifs_setattr, | 901 | .setattr = cifs_setattr, |
902 | .symlink = cifs_symlink, | 902 | .symlink = cifs_symlink, |
903 | .mknod = cifs_mknod, | 903 | .mknod = cifs_mknod, |
904 | .setxattr = generic_setxattr, | ||
905 | .getxattr = generic_getxattr, | ||
906 | .listxattr = cifs_listxattr, | 904 | .listxattr = cifs_listxattr, |
907 | .removexattr = generic_removexattr, | ||
908 | }; | 905 | }; |
909 | 906 | ||
910 | const struct inode_operations cifs_file_inode_ops = { | 907 | const struct inode_operations cifs_file_inode_ops = { |
911 | .setattr = cifs_setattr, | 908 | .setattr = cifs_setattr, |
912 | .getattr = cifs_getattr, | 909 | .getattr = cifs_getattr, |
913 | .permission = cifs_permission, | 910 | .permission = cifs_permission, |
914 | .setxattr = generic_setxattr, | ||
915 | .getxattr = generic_getxattr, | ||
916 | .listxattr = cifs_listxattr, | 911 | .listxattr = cifs_listxattr, |
917 | .removexattr = generic_removexattr, | ||
918 | }; | 912 | }; |
919 | 913 | ||
920 | const struct inode_operations cifs_symlink_inode_ops = { | 914 | const struct inode_operations cifs_symlink_inode_ops = { |
921 | .readlink = generic_readlink, | 915 | .readlink = generic_readlink, |
922 | .get_link = cifs_get_link, | 916 | .get_link = cifs_get_link, |
923 | .permission = cifs_permission, | 917 | .permission = cifs_permission, |
924 | .setxattr = generic_setxattr, | ||
925 | .getxattr = generic_getxattr, | ||
926 | .listxattr = cifs_listxattr, | 918 | .listxattr = cifs_listxattr, |
927 | .removexattr = generic_removexattr, | ||
928 | }; | 919 | }; |
929 | 920 | ||
930 | static int cifs_clone_file_range(struct file *src_file, loff_t off, | 921 | static int cifs_clone_file_range(struct file *src_file, loff_t off, |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 4ba1547bb9ad..599a29237cfe 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -715,4 +715,6 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, | |||
715 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, | 715 | int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, |
716 | loff_t offset); | 716 | loff_t offset); |
717 | 717 | ||
718 | extern const struct xattr_handler *ecryptfs_xattr_handlers[]; | ||
719 | |||
718 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 720 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5ffba186f352..ddccec3124d7 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, | |||
1005 | const char *name, const void *value, | 1005 | const char *name, const void *value, |
1006 | size_t size, int flags) | 1006 | size_t size, int flags) |
1007 | { | 1007 | { |
1008 | int rc = 0; | 1008 | int rc; |
1009 | struct dentry *lower_dentry; | 1009 | struct dentry *lower_dentry; |
1010 | 1010 | ||
1011 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1011 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1012 | if (!d_inode(lower_dentry)->i_op->setxattr) { | 1012 | if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) { |
1013 | rc = -EOPNOTSUPP; | 1013 | rc = -EOPNOTSUPP; |
1014 | goto out; | 1014 | goto out; |
1015 | } | 1015 | } |
1016 | |||
1017 | rc = vfs_setxattr(lower_dentry, name, value, size, flags); | 1016 | rc = vfs_setxattr(lower_dentry, name, value, size, flags); |
1018 | if (!rc && inode) | 1017 | if (!rc && inode) |
1019 | fsstack_copy_attr_all(inode, d_inode(lower_dentry)); | 1018 | fsstack_copy_attr_all(inode, d_inode(lower_dentry)); |
@@ -1025,15 +1024,14 @@ ssize_t | |||
1025 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, | 1024 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, |
1026 | const char *name, void *value, size_t size) | 1025 | const char *name, void *value, size_t size) |
1027 | { | 1026 | { |
1028 | int rc = 0; | 1027 | int rc; |
1029 | 1028 | ||
1030 | if (!lower_inode->i_op->getxattr) { | 1029 | if (!(lower_inode->i_opflags & IOP_XATTR)) { |
1031 | rc = -EOPNOTSUPP; | 1030 | rc = -EOPNOTSUPP; |
1032 | goto out; | 1031 | goto out; |
1033 | } | 1032 | } |
1034 | inode_lock(lower_inode); | 1033 | inode_lock(lower_inode); |
1035 | rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode, | 1034 | rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size); |
1036 | name, value, size); | ||
1037 | inode_unlock(lower_inode); | 1035 | inode_unlock(lower_inode); |
1038 | out: | 1036 | out: |
1039 | return rc; | 1037 | return rc; |
@@ -1066,19 +1064,22 @@ out: | |||
1066 | return rc; | 1064 | return rc; |
1067 | } | 1065 | } |
1068 | 1066 | ||
1069 | static int ecryptfs_removexattr(struct dentry *dentry, const char *name) | 1067 | static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode, |
1068 | const char *name) | ||
1070 | { | 1069 | { |
1071 | int rc = 0; | 1070 | int rc; |
1072 | struct dentry *lower_dentry; | 1071 | struct dentry *lower_dentry; |
1072 | struct inode *lower_inode; | ||
1073 | 1073 | ||
1074 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1074 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1075 | if (!d_inode(lower_dentry)->i_op->removexattr) { | 1075 | lower_inode = ecryptfs_inode_to_lower(inode); |
1076 | if (!(lower_inode->i_opflags & IOP_XATTR)) { | ||
1076 | rc = -EOPNOTSUPP; | 1077 | rc = -EOPNOTSUPP; |
1077 | goto out; | 1078 | goto out; |
1078 | } | 1079 | } |
1079 | inode_lock(d_inode(lower_dentry)); | 1080 | inode_lock(lower_inode); |
1080 | rc = d_inode(lower_dentry)->i_op->removexattr(lower_dentry, name); | 1081 | rc = __vfs_removexattr(lower_dentry, name); |
1081 | inode_unlock(d_inode(lower_dentry)); | 1082 | inode_unlock(lower_inode); |
1082 | out: | 1083 | out: |
1083 | return rc; | 1084 | return rc; |
1084 | } | 1085 | } |
@@ -1089,10 +1090,7 @@ const struct inode_operations ecryptfs_symlink_iops = { | |||
1089 | .permission = ecryptfs_permission, | 1090 | .permission = ecryptfs_permission, |
1090 | .setattr = ecryptfs_setattr, | 1091 | .setattr = ecryptfs_setattr, |
1091 | .getattr = ecryptfs_getattr_link, | 1092 | .getattr = ecryptfs_getattr_link, |
1092 | .setxattr = ecryptfs_setxattr, | ||
1093 | .getxattr = ecryptfs_getxattr, | ||
1094 | .listxattr = ecryptfs_listxattr, | 1093 | .listxattr = ecryptfs_listxattr, |
1095 | .removexattr = ecryptfs_removexattr | ||
1096 | }; | 1094 | }; |
1097 | 1095 | ||
1098 | const struct inode_operations ecryptfs_dir_iops = { | 1096 | const struct inode_operations ecryptfs_dir_iops = { |
@@ -1107,18 +1105,43 @@ const struct inode_operations ecryptfs_dir_iops = { | |||
1107 | .rename = ecryptfs_rename, | 1105 | .rename = ecryptfs_rename, |
1108 | .permission = ecryptfs_permission, | 1106 | .permission = ecryptfs_permission, |
1109 | .setattr = ecryptfs_setattr, | 1107 | .setattr = ecryptfs_setattr, |
1110 | .setxattr = ecryptfs_setxattr, | ||
1111 | .getxattr = ecryptfs_getxattr, | ||
1112 | .listxattr = ecryptfs_listxattr, | 1108 | .listxattr = ecryptfs_listxattr, |
1113 | .removexattr = ecryptfs_removexattr | ||
1114 | }; | 1109 | }; |
1115 | 1110 | ||
1116 | const struct inode_operations ecryptfs_main_iops = { | 1111 | const struct inode_operations ecryptfs_main_iops = { |
1117 | .permission = ecryptfs_permission, | 1112 | .permission = ecryptfs_permission, |
1118 | .setattr = ecryptfs_setattr, | 1113 | .setattr = ecryptfs_setattr, |
1119 | .getattr = ecryptfs_getattr, | 1114 | .getattr = ecryptfs_getattr, |
1120 | .setxattr = ecryptfs_setxattr, | ||
1121 | .getxattr = ecryptfs_getxattr, | ||
1122 | .listxattr = ecryptfs_listxattr, | 1115 | .listxattr = ecryptfs_listxattr, |
1123 | .removexattr = ecryptfs_removexattr | 1116 | }; |
1117 | |||
1118 | static int ecryptfs_xattr_get(const struct xattr_handler *handler, | ||
1119 | struct dentry *dentry, struct inode *inode, | ||
1120 | const char *name, void *buffer, size_t size) | ||
1121 | { | ||
1122 | return ecryptfs_getxattr(dentry, inode, name, buffer, size); | ||
1123 | } | ||
1124 | |||
1125 | static int ecryptfs_xattr_set(const struct xattr_handler *handler, | ||
1126 | struct dentry *dentry, struct inode *inode, | ||
1127 | const char *name, const void *value, size_t size, | ||
1128 | int flags) | ||
1129 | { | ||
1130 | if (value) | ||
1131 | return ecryptfs_setxattr(dentry, inode, name, value, size, flags); | ||
1132 | else { | ||
1133 | BUG_ON(flags != XATTR_REPLACE); | ||
1134 | return ecryptfs_removexattr(dentry, inode, name); | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | const struct xattr_handler ecryptfs_xattr_handler = { | ||
1139 | .prefix = "", /* match anything */ | ||
1140 | .get = ecryptfs_xattr_get, | ||
1141 | .set = ecryptfs_xattr_set, | ||
1142 | }; | ||
1143 | |||
1144 | const struct xattr_handler *ecryptfs_xattr_handlers[] = { | ||
1145 | &ecryptfs_xattr_handler, | ||
1146 | NULL | ||
1124 | }; | 1147 | }; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 612004495141..151872dcc1f4 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -529,6 +529,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
529 | /* ->kill_sb() will take care of sbi after that point */ | 529 | /* ->kill_sb() will take care of sbi after that point */ |
530 | sbi = NULL; | 530 | sbi = NULL; |
531 | s->s_op = &ecryptfs_sops; | 531 | s->s_op = &ecryptfs_sops; |
532 | s->s_xattr = ecryptfs_xattr_handlers; | ||
532 | s->s_d_op = &ecryptfs_dops; | 533 | s->s_d_op = &ecryptfs_dops; |
533 | 534 | ||
534 | err = "Reading sb failed"; | 535 | err = "Reading sb failed"; |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 9c3437c8a5b1..1f0c471b4ba3 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/file.h> | 32 | #include <linux/file.h> |
33 | #include <linux/scatterlist.h> | 33 | #include <linux/scatterlist.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/xattr.h> | ||
35 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
36 | #include "ecryptfs_kernel.h" | 37 | #include "ecryptfs_kernel.h" |
37 | 38 | ||
@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) | |||
422 | struct inode *lower_inode = d_inode(lower_dentry); | 423 | struct inode *lower_inode = d_inode(lower_dentry); |
423 | int rc; | 424 | int rc; |
424 | 425 | ||
425 | if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { | 426 | if (!(lower_inode->i_opflags & IOP_XATTR)) { |
426 | printk(KERN_WARNING | 427 | printk(KERN_WARNING |
427 | "No support for setting xattr in lower filesystem\n"); | 428 | "No support for setting xattr in lower filesystem\n"); |
428 | rc = -ENOSYS; | 429 | rc = -ENOSYS; |
@@ -436,15 +437,13 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) | |||
436 | goto out; | 437 | goto out; |
437 | } | 438 | } |
438 | inode_lock(lower_inode); | 439 | inode_lock(lower_inode); |
439 | size = lower_inode->i_op->getxattr(lower_dentry, lower_inode, | 440 | size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, |
440 | ECRYPTFS_XATTR_NAME, | 441 | xattr_virt, PAGE_SIZE); |
441 | xattr_virt, PAGE_SIZE); | ||
442 | if (size < 0) | 442 | if (size < 0) |
443 | size = 8; | 443 | size = 8; |
444 | put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); | 444 | put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); |
445 | rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode, | 445 | rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, |
446 | ECRYPTFS_XATTR_NAME, | 446 | xattr_virt, size, 0); |
447 | xattr_virt, size, 0); | ||
448 | inode_unlock(lower_inode); | 447 | inode_unlock(lower_inode); |
449 | if (rc) | 448 | if (rc) |
450 | printk(KERN_ERR "Error whilst attempting to write inode size " | 449 | printk(KERN_ERR "Error whilst attempting to write inode size " |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 0ca363d1341c..a0e1478dfd04 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -241,10 +241,7 @@ const struct file_operations ext2_file_operations = { | |||
241 | 241 | ||
242 | const struct inode_operations ext2_file_inode_operations = { | 242 | const struct inode_operations ext2_file_inode_operations = { |
243 | #ifdef CONFIG_EXT2_FS_XATTR | 243 | #ifdef CONFIG_EXT2_FS_XATTR |
244 | .setxattr = generic_setxattr, | ||
245 | .getxattr = generic_getxattr, | ||
246 | .listxattr = ext2_listxattr, | 244 | .listxattr = ext2_listxattr, |
247 | .removexattr = generic_removexattr, | ||
248 | #endif | 245 | #endif |
249 | .setattr = ext2_setattr, | 246 | .setattr = ext2_setattr, |
250 | .get_acl = ext2_get_acl, | 247 | .get_acl = ext2_get_acl, |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index d446203127fc..ff32ea799496 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -428,10 +428,7 @@ const struct inode_operations ext2_dir_inode_operations = { | |||
428 | .mknod = ext2_mknod, | 428 | .mknod = ext2_mknod, |
429 | .rename = ext2_rename, | 429 | .rename = ext2_rename, |
430 | #ifdef CONFIG_EXT2_FS_XATTR | 430 | #ifdef CONFIG_EXT2_FS_XATTR |
431 | .setxattr = generic_setxattr, | ||
432 | .getxattr = generic_getxattr, | ||
433 | .listxattr = ext2_listxattr, | 431 | .listxattr = ext2_listxattr, |
434 | .removexattr = generic_removexattr, | ||
435 | #endif | 432 | #endif |
436 | .setattr = ext2_setattr, | 433 | .setattr = ext2_setattr, |
437 | .get_acl = ext2_get_acl, | 434 | .get_acl = ext2_get_acl, |
@@ -441,10 +438,7 @@ const struct inode_operations ext2_dir_inode_operations = { | |||
441 | 438 | ||
442 | const struct inode_operations ext2_special_inode_operations = { | 439 | const struct inode_operations ext2_special_inode_operations = { |
443 | #ifdef CONFIG_EXT2_FS_XATTR | 440 | #ifdef CONFIG_EXT2_FS_XATTR |
444 | .setxattr = generic_setxattr, | ||
445 | .getxattr = generic_getxattr, | ||
446 | .listxattr = ext2_listxattr, | 441 | .listxattr = ext2_listxattr, |
447 | .removexattr = generic_removexattr, | ||
448 | #endif | 442 | #endif |
449 | .setattr = ext2_setattr, | 443 | .setattr = ext2_setattr, |
450 | .get_acl = ext2_get_acl, | 444 | .get_acl = ext2_get_acl, |
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 3495d8ae4b33..8437b191bf5d 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c | |||
@@ -25,10 +25,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
25 | .get_link = page_get_link, | 25 | .get_link = page_get_link, |
26 | .setattr = ext2_setattr, | 26 | .setattr = ext2_setattr, |
27 | #ifdef CONFIG_EXT2_FS_XATTR | 27 | #ifdef CONFIG_EXT2_FS_XATTR |
28 | .setxattr = generic_setxattr, | ||
29 | .getxattr = generic_getxattr, | ||
30 | .listxattr = ext2_listxattr, | 28 | .listxattr = ext2_listxattr, |
31 | .removexattr = generic_removexattr, | ||
32 | #endif | 29 | #endif |
33 | }; | 30 | }; |
34 | 31 | ||
@@ -37,9 +34,6 @@ const struct inode_operations ext2_fast_symlink_inode_operations = { | |||
37 | .get_link = simple_get_link, | 34 | .get_link = simple_get_link, |
38 | .setattr = ext2_setattr, | 35 | .setattr = ext2_setattr, |
39 | #ifdef CONFIG_EXT2_FS_XATTR | 36 | #ifdef CONFIG_EXT2_FS_XATTR |
40 | .setxattr = generic_setxattr, | ||
41 | .getxattr = generic_getxattr, | ||
42 | .listxattr = ext2_listxattr, | 37 | .listxattr = ext2_listxattr, |
43 | .removexattr = generic_removexattr, | ||
44 | #endif | 38 | #endif |
45 | }; | 39 | }; |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 36d49cfbf2dc..2a822d30e73f 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -706,10 +706,7 @@ const struct file_operations ext4_file_operations = { | |||
706 | const struct inode_operations ext4_file_inode_operations = { | 706 | const struct inode_operations ext4_file_inode_operations = { |
707 | .setattr = ext4_setattr, | 707 | .setattr = ext4_setattr, |
708 | .getattr = ext4_getattr, | 708 | .getattr = ext4_getattr, |
709 | .setxattr = generic_setxattr, | ||
710 | .getxattr = generic_getxattr, | ||
711 | .listxattr = ext4_listxattr, | 709 | .listxattr = ext4_listxattr, |
712 | .removexattr = generic_removexattr, | ||
713 | .get_acl = ext4_get_acl, | 710 | .get_acl = ext4_get_acl, |
714 | .set_acl = ext4_set_acl, | 711 | .set_acl = ext4_set_acl, |
715 | .fiemap = ext4_fiemap, | 712 | .fiemap = ext4_fiemap, |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index c344b819cffa..a73a9196b929 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -3880,10 +3880,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
3880 | .tmpfile = ext4_tmpfile, | 3880 | .tmpfile = ext4_tmpfile, |
3881 | .rename2 = ext4_rename2, | 3881 | .rename2 = ext4_rename2, |
3882 | .setattr = ext4_setattr, | 3882 | .setattr = ext4_setattr, |
3883 | .setxattr = generic_setxattr, | ||
3884 | .getxattr = generic_getxattr, | ||
3885 | .listxattr = ext4_listxattr, | 3883 | .listxattr = ext4_listxattr, |
3886 | .removexattr = generic_removexattr, | ||
3887 | .get_acl = ext4_get_acl, | 3884 | .get_acl = ext4_get_acl, |
3888 | .set_acl = ext4_set_acl, | 3885 | .set_acl = ext4_set_acl, |
3889 | .fiemap = ext4_fiemap, | 3886 | .fiemap = ext4_fiemap, |
@@ -3891,10 +3888,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
3891 | 3888 | ||
3892 | const struct inode_operations ext4_special_inode_operations = { | 3889 | const struct inode_operations ext4_special_inode_operations = { |
3893 | .setattr = ext4_setattr, | 3890 | .setattr = ext4_setattr, |
3894 | .setxattr = generic_setxattr, | ||
3895 | .getxattr = generic_getxattr, | ||
3896 | .listxattr = ext4_listxattr, | 3891 | .listxattr = ext4_listxattr, |
3897 | .removexattr = generic_removexattr, | ||
3898 | .get_acl = ext4_get_acl, | 3892 | .get_acl = ext4_get_acl, |
3899 | .set_acl = ext4_set_acl, | 3893 | .set_acl = ext4_set_acl, |
3900 | }; | 3894 | }; |
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index fdf1c6154745..557b3b0d668c 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c | |||
@@ -86,28 +86,19 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = { | |||
86 | .readlink = generic_readlink, | 86 | .readlink = generic_readlink, |
87 | .get_link = ext4_encrypted_get_link, | 87 | .get_link = ext4_encrypted_get_link, |
88 | .setattr = ext4_setattr, | 88 | .setattr = ext4_setattr, |
89 | .setxattr = generic_setxattr, | ||
90 | .getxattr = generic_getxattr, | ||
91 | .listxattr = ext4_listxattr, | 89 | .listxattr = ext4_listxattr, |
92 | .removexattr = generic_removexattr, | ||
93 | }; | 90 | }; |
94 | 91 | ||
95 | const struct inode_operations ext4_symlink_inode_operations = { | 92 | const struct inode_operations ext4_symlink_inode_operations = { |
96 | .readlink = generic_readlink, | 93 | .readlink = generic_readlink, |
97 | .get_link = page_get_link, | 94 | .get_link = page_get_link, |
98 | .setattr = ext4_setattr, | 95 | .setattr = ext4_setattr, |
99 | .setxattr = generic_setxattr, | ||
100 | .getxattr = generic_getxattr, | ||
101 | .listxattr = ext4_listxattr, | 96 | .listxattr = ext4_listxattr, |
102 | .removexattr = generic_removexattr, | ||
103 | }; | 97 | }; |
104 | 98 | ||
105 | const struct inode_operations ext4_fast_symlink_inode_operations = { | 99 | const struct inode_operations ext4_fast_symlink_inode_operations = { |
106 | .readlink = generic_readlink, | 100 | .readlink = generic_readlink, |
107 | .get_link = simple_get_link, | 101 | .get_link = simple_get_link, |
108 | .setattr = ext4_setattr, | 102 | .setattr = ext4_setattr, |
109 | .setxattr = generic_setxattr, | ||
110 | .getxattr = generic_getxattr, | ||
111 | .listxattr = ext4_listxattr, | 103 | .listxattr = ext4_listxattr, |
112 | .removexattr = generic_removexattr, | ||
113 | }; | 104 | }; |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 90455974c2ae..acdf4b929f97 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
@@ -732,10 +732,7 @@ const struct inode_operations f2fs_file_inode_operations = { | |||
732 | .get_acl = f2fs_get_acl, | 732 | .get_acl = f2fs_get_acl, |
733 | .set_acl = f2fs_set_acl, | 733 | .set_acl = f2fs_set_acl, |
734 | #ifdef CONFIG_F2FS_FS_XATTR | 734 | #ifdef CONFIG_F2FS_FS_XATTR |
735 | .setxattr = generic_setxattr, | ||
736 | .getxattr = generic_getxattr, | ||
737 | .listxattr = f2fs_listxattr, | 735 | .listxattr = f2fs_listxattr, |
738 | .removexattr = generic_removexattr, | ||
739 | #endif | 736 | #endif |
740 | .fiemap = f2fs_fiemap, | 737 | .fiemap = f2fs_fiemap, |
741 | }; | 738 | }; |
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 5625b879c98a..e80ed0302c22 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -1080,10 +1080,7 @@ const struct inode_operations f2fs_encrypted_symlink_inode_operations = { | |||
1080 | .getattr = f2fs_getattr, | 1080 | .getattr = f2fs_getattr, |
1081 | .setattr = f2fs_setattr, | 1081 | .setattr = f2fs_setattr, |
1082 | #ifdef CONFIG_F2FS_FS_XATTR | 1082 | #ifdef CONFIG_F2FS_FS_XATTR |
1083 | .setxattr = generic_setxattr, | ||
1084 | .getxattr = generic_getxattr, | ||
1085 | .listxattr = f2fs_listxattr, | 1083 | .listxattr = f2fs_listxattr, |
1086 | .removexattr = generic_removexattr, | ||
1087 | #endif | 1084 | #endif |
1088 | }; | 1085 | }; |
1089 | 1086 | ||
@@ -1103,10 +1100,7 @@ const struct inode_operations f2fs_dir_inode_operations = { | |||
1103 | .get_acl = f2fs_get_acl, | 1100 | .get_acl = f2fs_get_acl, |
1104 | .set_acl = f2fs_set_acl, | 1101 | .set_acl = f2fs_set_acl, |
1105 | #ifdef CONFIG_F2FS_FS_XATTR | 1102 | #ifdef CONFIG_F2FS_FS_XATTR |
1106 | .setxattr = generic_setxattr, | ||
1107 | .getxattr = generic_getxattr, | ||
1108 | .listxattr = f2fs_listxattr, | 1103 | .listxattr = f2fs_listxattr, |
1109 | .removexattr = generic_removexattr, | ||
1110 | #endif | 1104 | #endif |
1111 | }; | 1105 | }; |
1112 | 1106 | ||
@@ -1116,10 +1110,7 @@ const struct inode_operations f2fs_symlink_inode_operations = { | |||
1116 | .getattr = f2fs_getattr, | 1110 | .getattr = f2fs_getattr, |
1117 | .setattr = f2fs_setattr, | 1111 | .setattr = f2fs_setattr, |
1118 | #ifdef CONFIG_F2FS_FS_XATTR | 1112 | #ifdef CONFIG_F2FS_FS_XATTR |
1119 | .setxattr = generic_setxattr, | ||
1120 | .getxattr = generic_getxattr, | ||
1121 | .listxattr = f2fs_listxattr, | 1113 | .listxattr = f2fs_listxattr, |
1122 | .removexattr = generic_removexattr, | ||
1123 | #endif | 1114 | #endif |
1124 | }; | 1115 | }; |
1125 | 1116 | ||
@@ -1129,9 +1120,6 @@ const struct inode_operations f2fs_special_inode_operations = { | |||
1129 | .get_acl = f2fs_get_acl, | 1120 | .get_acl = f2fs_get_acl, |
1130 | .set_acl = f2fs_set_acl, | 1121 | .set_acl = f2fs_set_acl, |
1131 | #ifdef CONFIG_F2FS_FS_XATTR | 1122 | #ifdef CONFIG_F2FS_FS_XATTR |
1132 | .setxattr = generic_setxattr, | ||
1133 | .getxattr = generic_getxattr, | ||
1134 | .listxattr = f2fs_listxattr, | 1123 | .listxattr = f2fs_listxattr, |
1135 | .removexattr = generic_removexattr, | ||
1136 | #endif | 1124 | #endif |
1137 | }; | 1125 | }; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index a430c19607f4..572d12410c7c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1801,10 +1801,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | |||
1801 | .mknod = fuse_mknod, | 1801 | .mknod = fuse_mknod, |
1802 | .permission = fuse_permission, | 1802 | .permission = fuse_permission, |
1803 | .getattr = fuse_getattr, | 1803 | .getattr = fuse_getattr, |
1804 | .setxattr = generic_setxattr, | ||
1805 | .getxattr = generic_getxattr, | ||
1806 | .listxattr = fuse_listxattr, | 1804 | .listxattr = fuse_listxattr, |
1807 | .removexattr = generic_removexattr, | ||
1808 | .get_acl = fuse_get_acl, | 1805 | .get_acl = fuse_get_acl, |
1809 | .set_acl = fuse_set_acl, | 1806 | .set_acl = fuse_set_acl, |
1810 | }; | 1807 | }; |
@@ -1824,10 +1821,7 @@ static const struct inode_operations fuse_common_inode_operations = { | |||
1824 | .setattr = fuse_setattr, | 1821 | .setattr = fuse_setattr, |
1825 | .permission = fuse_permission, | 1822 | .permission = fuse_permission, |
1826 | .getattr = fuse_getattr, | 1823 | .getattr = fuse_getattr, |
1827 | .setxattr = generic_setxattr, | ||
1828 | .getxattr = generic_getxattr, | ||
1829 | .listxattr = fuse_listxattr, | 1824 | .listxattr = fuse_listxattr, |
1830 | .removexattr = generic_removexattr, | ||
1831 | .get_acl = fuse_get_acl, | 1825 | .get_acl = fuse_get_acl, |
1832 | .set_acl = fuse_set_acl, | 1826 | .set_acl = fuse_set_acl, |
1833 | }; | 1827 | }; |
@@ -1837,10 +1831,7 @@ static const struct inode_operations fuse_symlink_inode_operations = { | |||
1837 | .get_link = fuse_get_link, | 1831 | .get_link = fuse_get_link, |
1838 | .readlink = generic_readlink, | 1832 | .readlink = generic_readlink, |
1839 | .getattr = fuse_getattr, | 1833 | .getattr = fuse_getattr, |
1840 | .setxattr = generic_setxattr, | ||
1841 | .getxattr = generic_getxattr, | ||
1842 | .listxattr = fuse_listxattr, | 1834 | .listxattr = fuse_listxattr, |
1843 | .removexattr = generic_removexattr, | ||
1844 | }; | 1835 | }; |
1845 | 1836 | ||
1846 | void fuse_init_common(struct inode *inode) | 1837 | void fuse_init_common(struct inode *inode) |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 7efd1d19d325..f6c4f0058899 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -2040,10 +2040,7 @@ const struct inode_operations gfs2_file_iops = { | |||
2040 | .permission = gfs2_permission, | 2040 | .permission = gfs2_permission, |
2041 | .setattr = gfs2_setattr, | 2041 | .setattr = gfs2_setattr, |
2042 | .getattr = gfs2_getattr, | 2042 | .getattr = gfs2_getattr, |
2043 | .setxattr = generic_setxattr, | ||
2044 | .getxattr = generic_getxattr, | ||
2045 | .listxattr = gfs2_listxattr, | 2043 | .listxattr = gfs2_listxattr, |
2046 | .removexattr = generic_removexattr, | ||
2047 | .fiemap = gfs2_fiemap, | 2044 | .fiemap = gfs2_fiemap, |
2048 | .get_acl = gfs2_get_acl, | 2045 | .get_acl = gfs2_get_acl, |
2049 | .set_acl = gfs2_set_acl, | 2046 | .set_acl = gfs2_set_acl, |
@@ -2062,10 +2059,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
2062 | .permission = gfs2_permission, | 2059 | .permission = gfs2_permission, |
2063 | .setattr = gfs2_setattr, | 2060 | .setattr = gfs2_setattr, |
2064 | .getattr = gfs2_getattr, | 2061 | .getattr = gfs2_getattr, |
2065 | .setxattr = generic_setxattr, | ||
2066 | .getxattr = generic_getxattr, | ||
2067 | .listxattr = gfs2_listxattr, | 2062 | .listxattr = gfs2_listxattr, |
2068 | .removexattr = generic_removexattr, | ||
2069 | .fiemap = gfs2_fiemap, | 2063 | .fiemap = gfs2_fiemap, |
2070 | .get_acl = gfs2_get_acl, | 2064 | .get_acl = gfs2_get_acl, |
2071 | .set_acl = gfs2_set_acl, | 2065 | .set_acl = gfs2_set_acl, |
@@ -2078,10 +2072,7 @@ const struct inode_operations gfs2_symlink_iops = { | |||
2078 | .permission = gfs2_permission, | 2072 | .permission = gfs2_permission, |
2079 | .setattr = gfs2_setattr, | 2073 | .setattr = gfs2_setattr, |
2080 | .getattr = gfs2_getattr, | 2074 | .getattr = gfs2_getattr, |
2081 | .setxattr = generic_setxattr, | ||
2082 | .getxattr = generic_getxattr, | ||
2083 | .listxattr = gfs2_listxattr, | 2075 | .listxattr = gfs2_listxattr, |
2084 | .removexattr = generic_removexattr, | ||
2085 | .fiemap = gfs2_fiemap, | 2076 | .fiemap = gfs2_fiemap, |
2086 | }; | 2077 | }; |
2087 | 2078 | ||
diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c index d9a86919fdf6..0933600e11c8 100644 --- a/fs/hfs/attr.c +++ b/fs/hfs/attr.c | |||
@@ -13,9 +13,13 @@ | |||
13 | #include "hfs_fs.h" | 13 | #include "hfs_fs.h" |
14 | #include "btree.h" | 14 | #include "btree.h" |
15 | 15 | ||
16 | int hfs_setxattr(struct dentry *unused, struct inode *inode, | 16 | enum hfs_xattr_type { |
17 | const char *name, const void *value, | 17 | HFS_TYPE, |
18 | size_t size, int flags) | 18 | HFS_CREATOR, |
19 | }; | ||
20 | |||
21 | static int __hfs_setxattr(struct inode *inode, enum hfs_xattr_type type, | ||
22 | const void *value, size_t size, int flags) | ||
19 | { | 23 | { |
20 | struct hfs_find_data fd; | 24 | struct hfs_find_data fd; |
21 | hfs_cat_rec rec; | 25 | hfs_cat_rec rec; |
@@ -36,18 +40,22 @@ int hfs_setxattr(struct dentry *unused, struct inode *inode, | |||
36 | sizeof(struct hfs_cat_file)); | 40 | sizeof(struct hfs_cat_file)); |
37 | file = &rec.file; | 41 | file = &rec.file; |
38 | 42 | ||
39 | if (!strcmp(name, "hfs.type")) { | 43 | switch (type) { |
44 | case HFS_TYPE: | ||
40 | if (size == 4) | 45 | if (size == 4) |
41 | memcpy(&file->UsrWds.fdType, value, 4); | 46 | memcpy(&file->UsrWds.fdType, value, 4); |
42 | else | 47 | else |
43 | res = -ERANGE; | 48 | res = -ERANGE; |
44 | } else if (!strcmp(name, "hfs.creator")) { | 49 | break; |
50 | |||
51 | case HFS_CREATOR: | ||
45 | if (size == 4) | 52 | if (size == 4) |
46 | memcpy(&file->UsrWds.fdCreator, value, 4); | 53 | memcpy(&file->UsrWds.fdCreator, value, 4); |
47 | else | 54 | else |
48 | res = -ERANGE; | 55 | res = -ERANGE; |
49 | } else | 56 | break; |
50 | res = -EOPNOTSUPP; | 57 | } |
58 | |||
51 | if (!res) | 59 | if (!res) |
52 | hfs_bnode_write(fd.bnode, &rec, fd.entryoffset, | 60 | hfs_bnode_write(fd.bnode, &rec, fd.entryoffset, |
53 | sizeof(struct hfs_cat_file)); | 61 | sizeof(struct hfs_cat_file)); |
@@ -56,8 +64,8 @@ out: | |||
56 | return res; | 64 | return res; |
57 | } | 65 | } |
58 | 66 | ||
59 | ssize_t hfs_getxattr(struct dentry *unused, struct inode *inode, | 67 | static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type, |
60 | const char *name, void *value, size_t size) | 68 | void *value, size_t size) |
61 | { | 69 | { |
62 | struct hfs_find_data fd; | 70 | struct hfs_find_data fd; |
63 | hfs_cat_rec rec; | 71 | hfs_cat_rec rec; |
@@ -80,41 +88,64 @@ ssize_t hfs_getxattr(struct dentry *unused, struct inode *inode, | |||
80 | } | 88 | } |
81 | file = &rec.file; | 89 | file = &rec.file; |
82 | 90 | ||
83 | if (!strcmp(name, "hfs.type")) { | 91 | switch (type) { |
92 | case HFS_TYPE: | ||
84 | if (size >= 4) { | 93 | if (size >= 4) { |
85 | memcpy(value, &file->UsrWds.fdType, 4); | 94 | memcpy(value, &file->UsrWds.fdType, 4); |
86 | res = 4; | 95 | res = 4; |
87 | } else | 96 | } else |
88 | res = size ? -ERANGE : 4; | 97 | res = size ? -ERANGE : 4; |
89 | } else if (!strcmp(name, "hfs.creator")) { | 98 | break; |
99 | |||
100 | case HFS_CREATOR: | ||
90 | if (size >= 4) { | 101 | if (size >= 4) { |
91 | memcpy(value, &file->UsrWds.fdCreator, 4); | 102 | memcpy(value, &file->UsrWds.fdCreator, 4); |
92 | res = 4; | 103 | res = 4; |
93 | } else | 104 | } else |
94 | res = size ? -ERANGE : 4; | 105 | res = size ? -ERANGE : 4; |
95 | } else | 106 | break; |
96 | res = -ENODATA; | 107 | } |
108 | |||
97 | out: | 109 | out: |
98 | if (size) | 110 | if (size) |
99 | hfs_find_exit(&fd); | 111 | hfs_find_exit(&fd); |
100 | return res; | 112 | return res; |
101 | } | 113 | } |
102 | 114 | ||
103 | #define HFS_ATTRLIST_SIZE (sizeof("hfs.creator")+sizeof("hfs.type")) | 115 | static int hfs_xattr_get(const struct xattr_handler *handler, |
104 | 116 | struct dentry *unused, struct inode *inode, | |
105 | ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | 117 | const char *name, void *value, size_t size) |
106 | { | 118 | { |
107 | struct inode *inode = d_inode(dentry); | 119 | return __hfs_getxattr(inode, handler->flags, value, size); |
120 | } | ||
108 | 121 | ||
109 | if (!S_ISREG(inode->i_mode) || HFS_IS_RSRC(inode)) | 122 | static int hfs_xattr_set(const struct xattr_handler *handler, |
123 | struct dentry *unused, struct inode *inode, | ||
124 | const char *name, const void *value, size_t size, | ||
125 | int flags) | ||
126 | { | ||
127 | if (!value) | ||
110 | return -EOPNOTSUPP; | 128 | return -EOPNOTSUPP; |
111 | 129 | ||
112 | if (!buffer || !size) | 130 | return __hfs_setxattr(inode, handler->flags, value, size, flags); |
113 | return HFS_ATTRLIST_SIZE; | ||
114 | if (size < HFS_ATTRLIST_SIZE) | ||
115 | return -ERANGE; | ||
116 | strcpy(buffer, "hfs.type"); | ||
117 | strcpy(buffer + sizeof("hfs.type"), "hfs.creator"); | ||
118 | |||
119 | return HFS_ATTRLIST_SIZE; | ||
120 | } | 131 | } |
132 | |||
133 | static const struct xattr_handler hfs_creator_handler = { | ||
134 | .name = "hfs.creator", | ||
135 | .flags = HFS_CREATOR, | ||
136 | .get = hfs_xattr_get, | ||
137 | .set = hfs_xattr_set, | ||
138 | }; | ||
139 | |||
140 | static const struct xattr_handler hfs_type_handler = { | ||
141 | .name = "hfs.type", | ||
142 | .flags = HFS_TYPE, | ||
143 | .get = hfs_xattr_get, | ||
144 | .set = hfs_xattr_set, | ||
145 | }; | ||
146 | |||
147 | const struct xattr_handler *hfs_xattr_handlers[] = { | ||
148 | &hfs_creator_handler, | ||
149 | &hfs_type_handler, | ||
150 | NULL | ||
151 | }; | ||
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 16f5172ee40d..4cdec5a19347 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -212,11 +212,7 @@ extern void hfs_evict_inode(struct inode *); | |||
212 | extern void hfs_delete_inode(struct inode *); | 212 | extern void hfs_delete_inode(struct inode *); |
213 | 213 | ||
214 | /* attr.c */ | 214 | /* attr.c */ |
215 | extern int hfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, | 215 | extern const struct xattr_handler *hfs_xattr_handlers[]; |
216 | const void *value, size_t size, int flags); | ||
217 | extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode, | ||
218 | const char *name, void *value, size_t size); | ||
219 | extern ssize_t hfs_listxattr(struct dentry *dentry, char *buffer, size_t size); | ||
220 | 216 | ||
221 | /* mdb.c */ | 217 | /* mdb.c */ |
222 | extern int hfs_mdb_get(struct super_block *); | 218 | extern int hfs_mdb_get(struct super_block *); |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 09cce23864da..ed373261f26d 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/mpage.h> | 15 | #include <linux/mpage.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/uio.h> | 17 | #include <linux/uio.h> |
18 | #include <linux/xattr.h> | ||
18 | 19 | ||
19 | #include "hfs_fs.h" | 20 | #include "hfs_fs.h" |
20 | #include "btree.h" | 21 | #include "btree.h" |
@@ -687,7 +688,5 @@ static const struct file_operations hfs_file_operations = { | |||
687 | static const struct inode_operations hfs_file_inode_operations = { | 688 | static const struct inode_operations hfs_file_inode_operations = { |
688 | .lookup = hfs_file_lookup, | 689 | .lookup = hfs_file_lookup, |
689 | .setattr = hfs_inode_setattr, | 690 | .setattr = hfs_inode_setattr, |
690 | .setxattr = hfs_setxattr, | 691 | .listxattr = generic_listxattr, |
691 | .getxattr = hfs_getxattr, | ||
692 | .listxattr = hfs_listxattr, | ||
693 | }; | 692 | }; |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 1ca95c232bb5..bf6304a350a6 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -406,6 +406,7 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
406 | } | 406 | } |
407 | 407 | ||
408 | sb->s_op = &hfs_super_operations; | 408 | sb->s_op = &hfs_super_operations; |
409 | sb->s_xattr = hfs_xattr_handlers; | ||
409 | sb->s_flags |= MS_NODIRATIME; | 410 | sb->s_flags |= MS_NODIRATIME; |
410 | mutex_init(&sbi->bitmap_lock); | 411 | mutex_init(&sbi->bitmap_lock); |
411 | 412 | ||
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 42e128661dc1..9cbe43075de5 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -562,10 +562,7 @@ const struct inode_operations hfsplus_dir_inode_operations = { | |||
562 | .symlink = hfsplus_symlink, | 562 | .symlink = hfsplus_symlink, |
563 | .mknod = hfsplus_mknod, | 563 | .mknod = hfsplus_mknod, |
564 | .rename = hfsplus_rename, | 564 | .rename = hfsplus_rename, |
565 | .setxattr = generic_setxattr, | ||
566 | .getxattr = generic_getxattr, | ||
567 | .listxattr = hfsplus_listxattr, | 565 | .listxattr = hfsplus_listxattr, |
568 | .removexattr = generic_removexattr, | ||
569 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | 566 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL |
570 | .get_acl = hfsplus_get_posix_acl, | 567 | .get_acl = hfsplus_get_posix_acl, |
571 | .set_acl = hfsplus_set_posix_acl, | 568 | .set_acl = hfsplus_set_posix_acl, |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index c43ef397a3aa..10827c912c4d 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -333,10 +333,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, | |||
333 | 333 | ||
334 | static const struct inode_operations hfsplus_file_inode_operations = { | 334 | static const struct inode_operations hfsplus_file_inode_operations = { |
335 | .setattr = hfsplus_setattr, | 335 | .setattr = hfsplus_setattr, |
336 | .setxattr = generic_setxattr, | ||
337 | .getxattr = generic_getxattr, | ||
338 | .listxattr = hfsplus_listxattr, | 336 | .listxattr = hfsplus_listxattr, |
339 | .removexattr = generic_removexattr, | ||
340 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL | 337 | #ifdef CONFIG_HFSPLUS_FS_POSIX_ACL |
341 | .get_acl = hfsplus_get_posix_acl, | 338 | .get_acl = hfsplus_get_posix_acl, |
342 | .set_acl = hfsplus_set_posix_acl, | 339 | .set_acl = hfsplus_set_posix_acl, |
diff --git a/fs/inode.c b/fs/inode.c index a3c7ba7f6b59..7d037591259d 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -140,6 +140,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode) | |||
140 | inode->i_fop = &no_open_fops; | 140 | inode->i_fop = &no_open_fops; |
141 | inode->__i_nlink = 1; | 141 | inode->__i_nlink = 1; |
142 | inode->i_opflags = 0; | 142 | inode->i_opflags = 0; |
143 | if (sb->s_xattr) | ||
144 | inode->i_opflags |= IOP_XATTR; | ||
143 | i_uid_write(inode, 0); | 145 | i_uid_write(inode, 0); |
144 | i_gid_write(inode, 0); | 146 | i_gid_write(inode, 0); |
145 | atomic_set(&inode->i_writecount, 0); | 147 | atomic_set(&inode->i_writecount, 0); |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 30eb33ff8189..9b242434adf2 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -61,10 +61,7 @@ const struct inode_operations jffs2_dir_inode_operations = | |||
61 | .get_acl = jffs2_get_acl, | 61 | .get_acl = jffs2_get_acl, |
62 | .set_acl = jffs2_set_acl, | 62 | .set_acl = jffs2_set_acl, |
63 | .setattr = jffs2_setattr, | 63 | .setattr = jffs2_setattr, |
64 | .setxattr = jffs2_setxattr, | ||
65 | .getxattr = jffs2_getxattr, | ||
66 | .listxattr = jffs2_listxattr, | 64 | .listxattr = jffs2_listxattr, |
67 | .removexattr = jffs2_removexattr | ||
68 | }; | 65 | }; |
69 | 66 | ||
70 | /***********************************************************************/ | 67 | /***********************************************************************/ |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 0e62dec3effc..c12476e309c6 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -66,10 +66,7 @@ const struct inode_operations jffs2_file_inode_operations = | |||
66 | .get_acl = jffs2_get_acl, | 66 | .get_acl = jffs2_get_acl, |
67 | .set_acl = jffs2_set_acl, | 67 | .set_acl = jffs2_set_acl, |
68 | .setattr = jffs2_setattr, | 68 | .setattr = jffs2_setattr, |
69 | .setxattr = jffs2_setxattr, | ||
70 | .getxattr = jffs2_getxattr, | ||
71 | .listxattr = jffs2_listxattr, | 69 | .listxattr = jffs2_listxattr, |
72 | .removexattr = jffs2_removexattr | ||
73 | }; | 70 | }; |
74 | 71 | ||
75 | const struct address_space_operations jffs2_file_address_operations = | 72 | const struct address_space_operations jffs2_file_address_operations = |
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index 2cabd649d4fb..8f3f0855fcd2 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c | |||
@@ -16,8 +16,5 @@ const struct inode_operations jffs2_symlink_inode_operations = | |||
16 | .readlink = generic_readlink, | 16 | .readlink = generic_readlink, |
17 | .get_link = simple_get_link, | 17 | .get_link = simple_get_link, |
18 | .setattr = jffs2_setattr, | 18 | .setattr = jffs2_setattr, |
19 | .setxattr = jffs2_setxattr, | ||
20 | .getxattr = jffs2_getxattr, | ||
21 | .listxattr = jffs2_listxattr, | 19 | .listxattr = jffs2_listxattr, |
22 | .removexattr = jffs2_removexattr | ||
23 | }; | 20 | }; |
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 467ff376ee26..720007b2fd65 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -99,9 +99,6 @@ extern const struct xattr_handler jffs2_user_xattr_handler; | |||
99 | extern const struct xattr_handler jffs2_trusted_xattr_handler; | 99 | extern const struct xattr_handler jffs2_trusted_xattr_handler; |
100 | 100 | ||
101 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | 101 | extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); |
102 | #define jffs2_getxattr generic_getxattr | ||
103 | #define jffs2_setxattr generic_setxattr | ||
104 | #define jffs2_removexattr generic_removexattr | ||
105 | 102 | ||
106 | #else | 103 | #else |
107 | 104 | ||
@@ -116,9 +113,6 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); | |||
116 | 113 | ||
117 | #define jffs2_xattr_handlers NULL | 114 | #define jffs2_xattr_handlers NULL |
118 | #define jffs2_listxattr NULL | 115 | #define jffs2_listxattr NULL |
119 | #define jffs2_getxattr NULL | ||
120 | #define jffs2_setxattr NULL | ||
121 | #define jffs2_removexattr NULL | ||
122 | 116 | ||
123 | #endif /* CONFIG_JFFS2_FS_XATTR */ | 117 | #endif /* CONFIG_JFFS2_FS_XATTR */ |
124 | 118 | ||
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index cf62037b8a04..739492c7a3fd 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -140,10 +140,7 @@ 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 = generic_setxattr, | ||
144 | .getxattr = generic_getxattr, | ||
145 | .listxattr = jfs_listxattr, | 143 | .listxattr = jfs_listxattr, |
146 | .removexattr = generic_removexattr, | ||
147 | .setattr = jfs_setattr, | 144 | .setattr = jfs_setattr, |
148 | #ifdef CONFIG_JFS_POSIX_ACL | 145 | #ifdef CONFIG_JFS_POSIX_ACL |
149 | .get_acl = jfs_get_acl, | 146 | .get_acl = jfs_get_acl, |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 814b0c58016c..e420c6088336 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1537,10 +1537,7 @@ 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 = generic_setxattr, | ||
1541 | .getxattr = generic_getxattr, | ||
1542 | .listxattr = jfs_listxattr, | 1540 | .listxattr = jfs_listxattr, |
1543 | .removexattr = generic_removexattr, | ||
1544 | .setattr = jfs_setattr, | 1541 | .setattr = jfs_setattr, |
1545 | #ifdef CONFIG_JFS_POSIX_ACL | 1542 | #ifdef CONFIG_JFS_POSIX_ACL |
1546 | .get_acl = jfs_get_acl, | 1543 | .get_acl = jfs_get_acl, |
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index c94c7e4a1323..c82404fee6cd 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c | |||
@@ -25,19 +25,13 @@ 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 = generic_setxattr, | ||
29 | .getxattr = generic_getxattr, | ||
30 | .listxattr = jfs_listxattr, | 28 | .listxattr = jfs_listxattr, |
31 | .removexattr = generic_removexattr, | ||
32 | }; | 29 | }; |
33 | 30 | ||
34 | const struct inode_operations jfs_symlink_inode_operations = { | 31 | const struct inode_operations jfs_symlink_inode_operations = { |
35 | .readlink = generic_readlink, | 32 | .readlink = generic_readlink, |
36 | .get_link = page_get_link, | 33 | .get_link = page_get_link, |
37 | .setattr = jfs_setattr, | 34 | .setattr = jfs_setattr, |
38 | .setxattr = generic_setxattr, | ||
39 | .getxattr = generic_getxattr, | ||
40 | .listxattr = jfs_listxattr, | 35 | .listxattr = jfs_listxattr, |
41 | .removexattr = generic_removexattr, | ||
42 | }; | 36 | }; |
43 | 37 | ||
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index e57174d43683..2b23ad91a464 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -1126,9 +1126,6 @@ const struct inode_operations kernfs_dir_iops = { | |||
1126 | .permission = kernfs_iop_permission, | 1126 | .permission = kernfs_iop_permission, |
1127 | .setattr = kernfs_iop_setattr, | 1127 | .setattr = kernfs_iop_setattr, |
1128 | .getattr = kernfs_iop_getattr, | 1128 | .getattr = kernfs_iop_getattr, |
1129 | .setxattr = kernfs_iop_setxattr, | ||
1130 | .removexattr = kernfs_iop_removexattr, | ||
1131 | .getxattr = kernfs_iop_getxattr, | ||
1132 | .listxattr = kernfs_iop_listxattr, | 1129 | .listxattr = kernfs_iop_listxattr, |
1133 | 1130 | ||
1134 | .mkdir = kernfs_iop_mkdir, | 1131 | .mkdir = kernfs_iop_mkdir, |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index df21f5b75549..102b6f0bc7af 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -28,9 +28,6 @@ static const struct inode_operations kernfs_iops = { | |||
28 | .permission = kernfs_iop_permission, | 28 | .permission = kernfs_iop_permission, |
29 | .setattr = kernfs_iop_setattr, | 29 | .setattr = kernfs_iop_setattr, |
30 | .getattr = kernfs_iop_getattr, | 30 | .getattr = kernfs_iop_getattr, |
31 | .setxattr = kernfs_iop_setxattr, | ||
32 | .removexattr = kernfs_iop_removexattr, | ||
33 | .getxattr = kernfs_iop_getxattr, | ||
34 | .listxattr = kernfs_iop_listxattr, | 31 | .listxattr = kernfs_iop_listxattr, |
35 | }; | 32 | }; |
36 | 33 | ||
@@ -138,17 +135,12 @@ out: | |||
138 | return error; | 135 | return error; |
139 | } | 136 | } |
140 | 137 | ||
141 | static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, | 138 | static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, |
142 | u32 *secdata_len) | 139 | u32 *secdata_len) |
143 | { | 140 | { |
144 | struct kernfs_iattrs *attrs; | ||
145 | void *old_secdata; | 141 | void *old_secdata; |
146 | size_t old_secdata_len; | 142 | size_t old_secdata_len; |
147 | 143 | ||
148 | attrs = kernfs_iattrs(kn); | ||
149 | if (!attrs) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | old_secdata = attrs->ia_secdata; | 144 | old_secdata = attrs->ia_secdata; |
153 | old_secdata_len = attrs->ia_secdata_len; | 145 | old_secdata_len = attrs->ia_secdata_len; |
154 | 146 | ||
@@ -160,71 +152,6 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata, | |||
160 | return 0; | 152 | return 0; |
161 | } | 153 | } |
162 | 154 | ||
163 | int kernfs_iop_setxattr(struct dentry *unused, struct inode *inode, | ||
164 | const char *name, const void *value, | ||
165 | size_t size, int flags) | ||
166 | { | ||
167 | struct kernfs_node *kn = inode->i_private; | ||
168 | struct kernfs_iattrs *attrs; | ||
169 | void *secdata; | ||
170 | int error; | ||
171 | u32 secdata_len = 0; | ||
172 | |||
173 | attrs = kernfs_iattrs(kn); | ||
174 | if (!attrs) | ||
175 | return -ENOMEM; | ||
176 | |||
177 | if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) { | ||
178 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | ||
179 | error = security_inode_setsecurity(inode, suffix, | ||
180 | value, size, flags); | ||
181 | if (error) | ||
182 | return error; | ||
183 | error = security_inode_getsecctx(inode, | ||
184 | &secdata, &secdata_len); | ||
185 | if (error) | ||
186 | return error; | ||
187 | |||
188 | mutex_lock(&kernfs_mutex); | ||
189 | error = kernfs_node_setsecdata(kn, &secdata, &secdata_len); | ||
190 | mutex_unlock(&kernfs_mutex); | ||
191 | |||
192 | if (secdata) | ||
193 | security_release_secctx(secdata, secdata_len); | ||
194 | return error; | ||
195 | } else if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { | ||
196 | return simple_xattr_set(&attrs->xattrs, name, value, size, | ||
197 | flags); | ||
198 | } | ||
199 | |||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | int kernfs_iop_removexattr(struct dentry *dentry, const char *name) | ||
204 | { | ||
205 | struct kernfs_node *kn = dentry->d_fsdata; | ||
206 | struct kernfs_iattrs *attrs; | ||
207 | |||
208 | attrs = kernfs_iattrs(kn); | ||
209 | if (!attrs) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | return simple_xattr_set(&attrs->xattrs, name, NULL, 0, XATTR_REPLACE); | ||
213 | } | ||
214 | |||
215 | ssize_t kernfs_iop_getxattr(struct dentry *unused, struct inode *inode, | ||
216 | const char *name, void *buf, size_t size) | ||
217 | { | ||
218 | struct kernfs_node *kn = inode->i_private; | ||
219 | struct kernfs_iattrs *attrs; | ||
220 | |||
221 | attrs = kernfs_iattrs(kn); | ||
222 | if (!attrs) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | return simple_xattr_get(&attrs->xattrs, name, buf, size); | ||
226 | } | ||
227 | |||
228 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) | 155 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) |
229 | { | 156 | { |
230 | struct kernfs_node *kn = dentry->d_fsdata; | 157 | struct kernfs_node *kn = dentry->d_fsdata; |
@@ -376,3 +303,83 @@ int kernfs_iop_permission(struct inode *inode, int mask) | |||
376 | 303 | ||
377 | return generic_permission(inode, mask); | 304 | return generic_permission(inode, mask); |
378 | } | 305 | } |
306 | |||
307 | static int kernfs_xattr_get(const struct xattr_handler *handler, | ||
308 | struct dentry *unused, struct inode *inode, | ||
309 | const char *suffix, void *value, size_t size) | ||
310 | { | ||
311 | const char *name = xattr_full_name(handler, suffix); | ||
312 | struct kernfs_node *kn = inode->i_private; | ||
313 | struct kernfs_iattrs *attrs; | ||
314 | |||
315 | attrs = kernfs_iattrs(kn); | ||
316 | if (!attrs) | ||
317 | return -ENOMEM; | ||
318 | |||
319 | return simple_xattr_get(&attrs->xattrs, name, value, size); | ||
320 | } | ||
321 | |||
322 | static int kernfs_xattr_set(const struct xattr_handler *handler, | ||
323 | struct dentry *unused, struct inode *inode, | ||
324 | const char *suffix, const void *value, | ||
325 | size_t size, int flags) | ||
326 | { | ||
327 | const char *name = xattr_full_name(handler, suffix); | ||
328 | struct kernfs_node *kn = inode->i_private; | ||
329 | struct kernfs_iattrs *attrs; | ||
330 | |||
331 | attrs = kernfs_iattrs(kn); | ||
332 | if (!attrs) | ||
333 | return -ENOMEM; | ||
334 | |||
335 | return simple_xattr_set(&attrs->xattrs, name, value, size, flags); | ||
336 | } | ||
337 | |||
338 | const struct xattr_handler kernfs_trusted_xattr_handler = { | ||
339 | .prefix = XATTR_TRUSTED_PREFIX, | ||
340 | .get = kernfs_xattr_get, | ||
341 | .set = kernfs_xattr_set, | ||
342 | }; | ||
343 | |||
344 | static int kernfs_security_xattr_set(const struct xattr_handler *handler, | ||
345 | struct dentry *unused, struct inode *inode, | ||
346 | const char *suffix, const void *value, | ||
347 | size_t size, int flags) | ||
348 | { | ||
349 | struct kernfs_node *kn = inode->i_private; | ||
350 | struct kernfs_iattrs *attrs; | ||
351 | void *secdata; | ||
352 | u32 secdata_len = 0; | ||
353 | int error; | ||
354 | |||
355 | attrs = kernfs_iattrs(kn); | ||
356 | if (!attrs) | ||
357 | return -ENOMEM; | ||
358 | |||
359 | error = security_inode_setsecurity(inode, suffix, value, size, flags); | ||
360 | if (error) | ||
361 | return error; | ||
362 | error = security_inode_getsecctx(inode, &secdata, &secdata_len); | ||
363 | if (error) | ||
364 | return error; | ||
365 | |||
366 | mutex_lock(&kernfs_mutex); | ||
367 | error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); | ||
368 | mutex_unlock(&kernfs_mutex); | ||
369 | |||
370 | if (secdata) | ||
371 | security_release_secctx(secdata, secdata_len); | ||
372 | return error; | ||
373 | } | ||
374 | |||
375 | const struct xattr_handler kernfs_security_xattr_handler = { | ||
376 | .prefix = XATTR_SECURITY_PREFIX, | ||
377 | .get = kernfs_xattr_get, | ||
378 | .set = kernfs_security_xattr_set, | ||
379 | }; | ||
380 | |||
381 | const struct xattr_handler *kernfs_xattr_handlers[] = { | ||
382 | &kernfs_trusted_xattr_handler, | ||
383 | &kernfs_security_xattr_handler, | ||
384 | NULL | ||
385 | }; | ||
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 37159235ac10..bfd551bbf231 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h | |||
@@ -76,17 +76,12 @@ extern struct kmem_cache *kernfs_node_cache; | |||
76 | /* | 76 | /* |
77 | * inode.c | 77 | * inode.c |
78 | */ | 78 | */ |
79 | extern const struct xattr_handler *kernfs_xattr_handlers[]; | ||
79 | void kernfs_evict_inode(struct inode *inode); | 80 | void kernfs_evict_inode(struct inode *inode); |
80 | int kernfs_iop_permission(struct inode *inode, int mask); | 81 | int kernfs_iop_permission(struct inode *inode, int mask); |
81 | int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); | 82 | int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); |
82 | int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, | 83 | int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry, |
83 | struct kstat *stat); | 84 | struct kstat *stat); |
84 | int kernfs_iop_setxattr(struct dentry *dentry, struct inode *inode, | ||
85 | const char *name, const void *value, | ||
86 | size_t size, int flags); | ||
87 | int kernfs_iop_removexattr(struct dentry *dentry, const char *name); | ||
88 | ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode, | ||
89 | const char *name, void *buf, size_t size); | ||
90 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); | 85 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); |
91 | 86 | ||
92 | /* | 87 | /* |
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index b3d73ad52b22..d5b149a45be1 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c | |||
@@ -158,6 +158,7 @@ static int kernfs_fill_super(struct super_block *sb, unsigned long magic) | |||
158 | sb->s_blocksize_bits = PAGE_SHIFT; | 158 | sb->s_blocksize_bits = PAGE_SHIFT; |
159 | sb->s_magic = magic; | 159 | sb->s_magic = magic; |
160 | sb->s_op = &kernfs_sops; | 160 | sb->s_op = &kernfs_sops; |
161 | sb->s_xattr = kernfs_xattr_handlers; | ||
161 | sb->s_time_gran = 1; | 162 | sb->s_time_gran = 1; |
162 | 163 | ||
163 | /* get root inode, initialize and unlock it */ | 164 | /* get root inode, initialize and unlock it */ |
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 117b8b3416f9..9b43ca02b7ab 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c | |||
@@ -134,9 +134,6 @@ static const char *kernfs_iop_get_link(struct dentry *dentry, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | const struct inode_operations kernfs_symlink_iops = { | 136 | const struct inode_operations kernfs_symlink_iops = { |
137 | .setxattr = kernfs_iop_setxattr, | ||
138 | .removexattr = kernfs_iop_removexattr, | ||
139 | .getxattr = kernfs_iop_getxattr, | ||
140 | .listxattr = kernfs_iop_listxattr, | 137 | .listxattr = kernfs_iop_listxattr, |
141 | .readlink = generic_readlink, | 138 | .readlink = generic_readlink, |
142 | .get_link = kernfs_iop_get_link, | 139 | .get_link = kernfs_iop_get_link, |
diff --git a/fs/libfs.c b/fs/libfs.c index 2b3c3ae70153..a6d89f151771 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -236,8 +236,8 @@ static const struct super_operations simple_super_operations = { | |||
236 | * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that | 236 | * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that |
237 | * will never be mountable) | 237 | * will never be mountable) |
238 | */ | 238 | */ |
239 | struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, | 239 | struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name, |
240 | const struct super_operations *ops, | 240 | const struct super_operations *ops, const struct xattr_handler **xattr, |
241 | const struct dentry_operations *dops, unsigned long magic) | 241 | const struct dentry_operations *dops, unsigned long magic) |
242 | { | 242 | { |
243 | struct super_block *s; | 243 | struct super_block *s; |
@@ -254,6 +254,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, | |||
254 | s->s_blocksize_bits = PAGE_SHIFT; | 254 | s->s_blocksize_bits = PAGE_SHIFT; |
255 | s->s_magic = magic; | 255 | s->s_magic = magic; |
256 | s->s_op = ops ? ops : &simple_super_operations; | 256 | s->s_op = ops ? ops : &simple_super_operations; |
257 | s->s_xattr = xattr; | ||
257 | s->s_time_gran = 1; | 258 | s->s_time_gran = 1; |
258 | root = new_inode(s); | 259 | root = new_inode(s); |
259 | if (!root) | 260 | if (!root) |
@@ -281,7 +282,7 @@ Enomem: | |||
281 | deactivate_locked_super(s); | 282 | deactivate_locked_super(s); |
282 | return ERR_PTR(-ENOMEM); | 283 | return ERR_PTR(-ENOMEM); |
283 | } | 284 | } |
284 | EXPORT_SYMBOL(mount_pseudo); | 285 | EXPORT_SYMBOL(mount_pseudo_xattr); |
285 | 286 | ||
286 | int simple_open(struct inode *inode, struct file *file) | 287 | int simple_open(struct inode *inode, struct file *file) |
287 | { | 288 | { |
@@ -1149,24 +1150,6 @@ static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr) | |||
1149 | return -EPERM; | 1150 | return -EPERM; |
1150 | } | 1151 | } |
1151 | 1152 | ||
1152 | static int empty_dir_setxattr(struct dentry *dentry, struct inode *inode, | ||
1153 | const char *name, const void *value, | ||
1154 | size_t size, int flags) | ||
1155 | { | ||
1156 | return -EOPNOTSUPP; | ||
1157 | } | ||
1158 | |||
1159 | static ssize_t empty_dir_getxattr(struct dentry *dentry, struct inode *inode, | ||
1160 | const char *name, void *value, size_t size) | ||
1161 | { | ||
1162 | return -EOPNOTSUPP; | ||
1163 | } | ||
1164 | |||
1165 | static int empty_dir_removexattr(struct dentry *dentry, const char *name) | ||
1166 | { | ||
1167 | return -EOPNOTSUPP; | ||
1168 | } | ||
1169 | |||
1170 | static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size) | 1153 | static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size) |
1171 | { | 1154 | { |
1172 | return -EOPNOTSUPP; | 1155 | return -EOPNOTSUPP; |
@@ -1177,9 +1160,6 @@ static const struct inode_operations empty_dir_inode_operations = { | |||
1177 | .permission = generic_permission, | 1160 | .permission = generic_permission, |
1178 | .setattr = empty_dir_setattr, | 1161 | .setattr = empty_dir_setattr, |
1179 | .getattr = empty_dir_getattr, | 1162 | .getattr = empty_dir_getattr, |
1180 | .setxattr = empty_dir_setxattr, | ||
1181 | .getxattr = empty_dir_getxattr, | ||
1182 | .removexattr = empty_dir_removexattr, | ||
1183 | .listxattr = empty_dir_listxattr, | 1163 | .listxattr = empty_dir_listxattr, |
1184 | }; | 1164 | }; |
1185 | 1165 | ||
@@ -1215,6 +1195,7 @@ void make_empty_dir_inode(struct inode *inode) | |||
1215 | inode->i_blocks = 0; | 1195 | inode->i_blocks = 0; |
1216 | 1196 | ||
1217 | inode->i_op = &empty_dir_inode_operations; | 1197 | inode->i_op = &empty_dir_inode_operations; |
1198 | inode->i_opflags &= ~IOP_XATTR; | ||
1218 | inode->i_fop = &empty_dir_operations; | 1199 | inode->i_fop = &empty_dir_operations; |
1219 | } | 1200 | } |
1220 | 1201 | ||
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 698be9361280..dc925b531f32 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -899,9 +899,6 @@ static const struct inode_operations nfs3_dir_inode_operations = { | |||
899 | .setattr = nfs_setattr, | 899 | .setattr = nfs_setattr, |
900 | #ifdef CONFIG_NFS_V3_ACL | 900 | #ifdef CONFIG_NFS_V3_ACL |
901 | .listxattr = nfs3_listxattr, | 901 | .listxattr = nfs3_listxattr, |
902 | .getxattr = generic_getxattr, | ||
903 | .setxattr = generic_setxattr, | ||
904 | .removexattr = generic_removexattr, | ||
905 | .get_acl = nfs3_get_acl, | 902 | .get_acl = nfs3_get_acl, |
906 | .set_acl = nfs3_set_acl, | 903 | .set_acl = nfs3_set_acl, |
907 | #endif | 904 | #endif |
@@ -913,9 +910,6 @@ static const struct inode_operations nfs3_file_inode_operations = { | |||
913 | .setattr = nfs_setattr, | 910 | .setattr = nfs_setattr, |
914 | #ifdef CONFIG_NFS_V3_ACL | 911 | #ifdef CONFIG_NFS_V3_ACL |
915 | .listxattr = nfs3_listxattr, | 912 | .listxattr = nfs3_listxattr, |
916 | .getxattr = generic_getxattr, | ||
917 | .setxattr = generic_setxattr, | ||
918 | .removexattr = generic_removexattr, | ||
919 | .get_acl = nfs3_get_acl, | 913 | .get_acl = nfs3_get_acl, |
920 | .set_acl = nfs3_set_acl, | 914 | .set_acl = nfs3_set_acl, |
921 | #endif | 915 | #endif |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a9dec32ba9ba..0e327528a3ce 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -8941,20 +8941,14 @@ static const struct inode_operations nfs4_dir_inode_operations = { | |||
8941 | .permission = nfs_permission, | 8941 | .permission = nfs_permission, |
8942 | .getattr = nfs_getattr, | 8942 | .getattr = nfs_getattr, |
8943 | .setattr = nfs_setattr, | 8943 | .setattr = nfs_setattr, |
8944 | .getxattr = generic_getxattr, | ||
8945 | .setxattr = generic_setxattr, | ||
8946 | .listxattr = nfs4_listxattr, | 8944 | .listxattr = nfs4_listxattr, |
8947 | .removexattr = generic_removexattr, | ||
8948 | }; | 8945 | }; |
8949 | 8946 | ||
8950 | static const struct inode_operations nfs4_file_inode_operations = { | 8947 | static const struct inode_operations nfs4_file_inode_operations = { |
8951 | .permission = nfs_permission, | 8948 | .permission = nfs_permission, |
8952 | .getattr = nfs_getattr, | 8949 | .getattr = nfs_getattr, |
8953 | .setattr = nfs_setattr, | 8950 | .setattr = nfs_setattr, |
8954 | .getxattr = generic_getxattr, | ||
8955 | .setxattr = generic_setxattr, | ||
8956 | .listxattr = nfs4_listxattr, | 8951 | .listxattr = nfs4_listxattr, |
8957 | .removexattr = generic_removexattr, | ||
8958 | }; | 8952 | }; |
8959 | 8953 | ||
8960 | const struct nfs_rpc_ops nfs_v4_clientops = { | 8954 | const struct nfs_rpc_ops nfs_v4_clientops = { |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 5e1901546868..ba5c177d0ed6 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2444,10 +2444,7 @@ const struct inode_operations ocfs2_file_iops = { | |||
2444 | .setattr = ocfs2_setattr, | 2444 | .setattr = ocfs2_setattr, |
2445 | .getattr = ocfs2_getattr, | 2445 | .getattr = ocfs2_getattr, |
2446 | .permission = ocfs2_permission, | 2446 | .permission = ocfs2_permission, |
2447 | .setxattr = generic_setxattr, | ||
2448 | .getxattr = generic_getxattr, | ||
2449 | .listxattr = ocfs2_listxattr, | 2447 | .listxattr = ocfs2_listxattr, |
2450 | .removexattr = generic_removexattr, | ||
2451 | .fiemap = ocfs2_fiemap, | 2448 | .fiemap = ocfs2_fiemap, |
2452 | .get_acl = ocfs2_iop_get_acl, | 2449 | .get_acl = ocfs2_iop_get_acl, |
2453 | .set_acl = ocfs2_iop_set_acl, | 2450 | .set_acl = ocfs2_iop_set_acl, |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a8f1225e6d9b..6cc043ebb9fa 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -2913,10 +2913,7 @@ const struct inode_operations ocfs2_dir_iops = { | |||
2913 | .setattr = ocfs2_setattr, | 2913 | .setattr = ocfs2_setattr, |
2914 | .getattr = ocfs2_getattr, | 2914 | .getattr = ocfs2_getattr, |
2915 | .permission = ocfs2_permission, | 2915 | .permission = ocfs2_permission, |
2916 | .setxattr = generic_setxattr, | ||
2917 | .getxattr = generic_getxattr, | ||
2918 | .listxattr = ocfs2_listxattr, | 2916 | .listxattr = ocfs2_listxattr, |
2919 | .removexattr = generic_removexattr, | ||
2920 | .fiemap = ocfs2_fiemap, | 2917 | .fiemap = ocfs2_fiemap, |
2921 | .get_acl = ocfs2_iop_get_acl, | 2918 | .get_acl = ocfs2_iop_get_acl, |
2922 | .set_acl = ocfs2_iop_set_acl, | 2919 | .set_acl = ocfs2_iop_set_acl, |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 6c2a3e3c521c..6ad8eecefe21 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -91,9 +91,6 @@ const struct inode_operations ocfs2_symlink_inode_operations = { | |||
91 | .get_link = page_get_link, | 91 | .get_link = page_get_link, |
92 | .getattr = ocfs2_getattr, | 92 | .getattr = ocfs2_getattr, |
93 | .setattr = ocfs2_setattr, | 93 | .setattr = ocfs2_setattr, |
94 | .setxattr = generic_setxattr, | ||
95 | .getxattr = generic_getxattr, | ||
96 | .listxattr = ocfs2_listxattr, | 94 | .listxattr = ocfs2_listxattr, |
97 | .removexattr = generic_removexattr, | ||
98 | .fiemap = ocfs2_fiemap, | 95 | .fiemap = ocfs2_fiemap, |
99 | }; | 96 | }; |
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index c83846fb9b14..0e3bd7e07f88 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c | |||
@@ -296,10 +296,7 @@ const struct inode_operations orangefs_file_inode_operations = { | |||
296 | .set_acl = orangefs_set_acl, | 296 | .set_acl = orangefs_set_acl, |
297 | .setattr = orangefs_setattr, | 297 | .setattr = orangefs_setattr, |
298 | .getattr = orangefs_getattr, | 298 | .getattr = orangefs_getattr, |
299 | .setxattr = generic_setxattr, | ||
300 | .getxattr = generic_getxattr, | ||
301 | .listxattr = orangefs_listxattr, | 299 | .listxattr = orangefs_listxattr, |
302 | .removexattr = generic_removexattr, | ||
303 | .permission = orangefs_permission, | 300 | .permission = orangefs_permission, |
304 | }; | 301 | }; |
305 | 302 | ||
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 0e34fcfa4d51..4d5576a21c82 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c | |||
@@ -462,9 +462,6 @@ const struct inode_operations orangefs_dir_inode_operations = { | |||
462 | .rename = orangefs_rename, | 462 | .rename = orangefs_rename, |
463 | .setattr = orangefs_setattr, | 463 | .setattr = orangefs_setattr, |
464 | .getattr = orangefs_getattr, | 464 | .getattr = orangefs_getattr, |
465 | .setxattr = generic_setxattr, | ||
466 | .getxattr = generic_getxattr, | ||
467 | .removexattr = generic_removexattr, | ||
468 | .listxattr = orangefs_listxattr, | 465 | .listxattr = orangefs_listxattr, |
469 | .permission = orangefs_permission, | 466 | .permission = orangefs_permission, |
470 | }; | 467 | }; |
diff --git a/fs/orangefs/symlink.c b/fs/orangefs/symlink.c index 8fecf823f5ba..10b0b06e075e 100644 --- a/fs/orangefs/symlink.c +++ b/fs/orangefs/symlink.c | |||
@@ -14,6 +14,5 @@ const struct inode_operations orangefs_symlink_inode_operations = { | |||
14 | .setattr = orangefs_setattr, | 14 | .setattr = orangefs_setattr, |
15 | .getattr = orangefs_getattr, | 15 | .getattr = orangefs_getattr, |
16 | .listxattr = orangefs_listxattr, | 16 | .listxattr = orangefs_listxattr, |
17 | .setxattr = generic_setxattr, | ||
18 | .permission = orangefs_permission, | 17 | .permission = orangefs_permission, |
19 | }; | 18 | }; |
diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index 2a9f07f06d10..74a81b1daaac 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c | |||
@@ -73,6 +73,9 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, | |||
73 | "%s: name %s, buffer_size %zd\n", | 73 | "%s: name %s, buffer_size %zd\n", |
74 | __func__, name, size); | 74 | __func__, name, size); |
75 | 75 | ||
76 | if (S_ISLNK(inode->i_mode)) | ||
77 | return -EOPNOTSUPP; | ||
78 | |||
76 | if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { | 79 | if (strlen(name) >= ORANGEFS_MAX_XATTR_NAMELEN) { |
77 | gossip_err("Invalid key length (%d)\n", | 80 | gossip_err("Invalid key length (%d)\n", |
78 | (int)strlen(name)); | 81 | (int)strlen(name)); |
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index db37a0e02d32..3f803b3a1f82 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c | |||
@@ -58,8 +58,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) | |||
58 | char *buf, *name, *value = NULL; | 58 | char *buf, *name, *value = NULL; |
59 | int uninitialized_var(error); | 59 | int uninitialized_var(error); |
60 | 60 | ||
61 | if (!old->d_inode->i_op->getxattr || | 61 | if (!(old->d_inode->i_opflags & IOP_XATTR) || |
62 | !new->d_inode->i_op->getxattr) | 62 | !(new->d_inode->i_opflags & IOP_XATTR)) |
63 | return 0; | 63 | return 0; |
64 | 64 | ||
65 | list_size = vfs_listxattr(old, NULL, 0); | 65 | list_size = vfs_listxattr(old, NULL, 0); |
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index b0ffa1d1677e..3a60e68ec965 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
@@ -1013,10 +1013,7 @@ const struct inode_operations ovl_dir_inode_operations = { | |||
1013 | .mknod = ovl_mknod, | 1013 | .mknod = ovl_mknod, |
1014 | .permission = ovl_permission, | 1014 | .permission = ovl_permission, |
1015 | .getattr = ovl_dir_getattr, | 1015 | .getattr = ovl_dir_getattr, |
1016 | .setxattr = generic_setxattr, | ||
1017 | .getxattr = generic_getxattr, | ||
1018 | .listxattr = ovl_listxattr, | 1016 | .listxattr = ovl_listxattr, |
1019 | .removexattr = generic_removexattr, | ||
1020 | .get_acl = ovl_get_acl, | 1017 | .get_acl = ovl_get_acl, |
1021 | .update_time = ovl_update_time, | 1018 | .update_time = ovl_update_time, |
1022 | }; | 1019 | }; |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 251e5253f2c1..c18d6a4ff456 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -367,10 +367,7 @@ static const struct inode_operations ovl_file_inode_operations = { | |||
367 | .setattr = ovl_setattr, | 367 | .setattr = ovl_setattr, |
368 | .permission = ovl_permission, | 368 | .permission = ovl_permission, |
369 | .getattr = ovl_getattr, | 369 | .getattr = ovl_getattr, |
370 | .setxattr = generic_setxattr, | ||
371 | .getxattr = generic_getxattr, | ||
372 | .listxattr = ovl_listxattr, | 370 | .listxattr = ovl_listxattr, |
373 | .removexattr = generic_removexattr, | ||
374 | .get_acl = ovl_get_acl, | 371 | .get_acl = ovl_get_acl, |
375 | .update_time = ovl_update_time, | 372 | .update_time = ovl_update_time, |
376 | }; | 373 | }; |
@@ -380,10 +377,7 @@ static const struct inode_operations ovl_symlink_inode_operations = { | |||
380 | .get_link = ovl_get_link, | 377 | .get_link = ovl_get_link, |
381 | .readlink = ovl_readlink, | 378 | .readlink = ovl_readlink, |
382 | .getattr = ovl_getattr, | 379 | .getattr = ovl_getattr, |
383 | .setxattr = generic_setxattr, | ||
384 | .getxattr = generic_getxattr, | ||
385 | .listxattr = ovl_listxattr, | 380 | .listxattr = ovl_listxattr, |
386 | .removexattr = generic_removexattr, | ||
387 | .update_time = ovl_update_time, | 381 | .update_time = ovl_update_time, |
388 | }; | 382 | }; |
389 | 383 | ||
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 3d0b9dee2b76..7e3f0127fc1a 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -275,10 +275,10 @@ static bool ovl_is_opaquedir(struct dentry *dentry) | |||
275 | char val; | 275 | char val; |
276 | struct inode *inode = dentry->d_inode; | 276 | struct inode *inode = dentry->d_inode; |
277 | 277 | ||
278 | if (!S_ISDIR(inode->i_mode) || !inode->i_op->getxattr) | 278 | if (!S_ISDIR(inode->i_mode) || !(inode->i_opflags & IOP_XATTR)) |
279 | return false; | 279 | return false; |
280 | 280 | ||
281 | res = inode->i_op->getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1); | 281 | res = __vfs_getxattr(dentry, inode, OVL_XATTR_OPAQUE, &val, 1); |
282 | if (res == 1 && val == 'y') | 282 | if (res == 1 && val == 'y') |
283 | return true; | 283 | return true; |
284 | 284 | ||
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 90f815bdfa8a..2f8c5c9bdaf6 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -260,10 +260,7 @@ const struct file_operations reiserfs_file_operations = { | |||
260 | 260 | ||
261 | const struct inode_operations reiserfs_file_inode_operations = { | 261 | const struct inode_operations reiserfs_file_inode_operations = { |
262 | .setattr = reiserfs_setattr, | 262 | .setattr = reiserfs_setattr, |
263 | .setxattr = generic_setxattr, | ||
264 | .getxattr = generic_getxattr, | ||
265 | .listxattr = reiserfs_listxattr, | 263 | .listxattr = reiserfs_listxattr, |
266 | .removexattr = generic_removexattr, | ||
267 | .permission = reiserfs_permission, | 264 | .permission = reiserfs_permission, |
268 | .get_acl = reiserfs_get_acl, | 265 | .get_acl = reiserfs_get_acl, |
269 | .set_acl = reiserfs_set_acl, | 266 | .set_acl = reiserfs_set_acl, |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 8a36696d6df9..fd7d0606aa96 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -1650,10 +1650,7 @@ const struct inode_operations reiserfs_dir_inode_operations = { | |||
1650 | .mknod = reiserfs_mknod, | 1650 | .mknod = reiserfs_mknod, |
1651 | .rename = reiserfs_rename, | 1651 | .rename = reiserfs_rename, |
1652 | .setattr = reiserfs_setattr, | 1652 | .setattr = reiserfs_setattr, |
1653 | .setxattr = generic_setxattr, | ||
1654 | .getxattr = generic_getxattr, | ||
1655 | .listxattr = reiserfs_listxattr, | 1653 | .listxattr = reiserfs_listxattr, |
1656 | .removexattr = generic_removexattr, | ||
1657 | .permission = reiserfs_permission, | 1654 | .permission = reiserfs_permission, |
1658 | .get_acl = reiserfs_get_acl, | 1655 | .get_acl = reiserfs_get_acl, |
1659 | .set_acl = reiserfs_set_acl, | 1656 | .set_acl = reiserfs_set_acl, |
@@ -1667,10 +1664,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = { | |||
1667 | .readlink = generic_readlink, | 1664 | .readlink = generic_readlink, |
1668 | .get_link = page_get_link, | 1665 | .get_link = page_get_link, |
1669 | .setattr = reiserfs_setattr, | 1666 | .setattr = reiserfs_setattr, |
1670 | .setxattr = generic_setxattr, | ||
1671 | .getxattr = generic_getxattr, | ||
1672 | .listxattr = reiserfs_listxattr, | 1667 | .listxattr = reiserfs_listxattr, |
1673 | .removexattr = generic_removexattr, | ||
1674 | .permission = reiserfs_permission, | 1668 | .permission = reiserfs_permission, |
1675 | }; | 1669 | }; |
1676 | 1670 | ||
@@ -1679,10 +1673,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = { | |||
1679 | */ | 1673 | */ |
1680 | const struct inode_operations reiserfs_special_inode_operations = { | 1674 | const struct inode_operations reiserfs_special_inode_operations = { |
1681 | .setattr = reiserfs_setattr, | 1675 | .setattr = reiserfs_setattr, |
1682 | .setxattr = generic_setxattr, | ||
1683 | .getxattr = generic_getxattr, | ||
1684 | .listxattr = reiserfs_listxattr, | 1676 | .listxattr = reiserfs_listxattr, |
1685 | .removexattr = generic_removexattr, | ||
1686 | .permission = reiserfs_permission, | 1677 | .permission = reiserfs_permission, |
1687 | .get_acl = reiserfs_get_acl, | 1678 | .get_acl = reiserfs_get_acl, |
1688 | .set_acl = reiserfs_set_acl, | 1679 | .set_acl = reiserfs_set_acl, |
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 0927b1e80ab6..e9793b1e49a5 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c | |||
@@ -425,7 +425,6 @@ failed_read: | |||
425 | 425 | ||
426 | 426 | ||
427 | const struct inode_operations squashfs_inode_ops = { | 427 | const struct inode_operations squashfs_inode_ops = { |
428 | .getxattr = generic_getxattr, | ||
429 | .listxattr = squashfs_listxattr | 428 | .listxattr = squashfs_listxattr |
430 | }; | 429 | }; |
431 | 430 | ||
diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c index 67cad77fefb4..40c10d9974c9 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c | |||
@@ -247,6 +247,5 @@ failed: | |||
247 | 247 | ||
248 | const struct inode_operations squashfs_dir_inode_ops = { | 248 | const struct inode_operations squashfs_dir_inode_ops = { |
249 | .lookup = squashfs_lookup, | 249 | .lookup = squashfs_lookup, |
250 | .getxattr = generic_getxattr, | ||
251 | .listxattr = squashfs_listxattr | 250 | .listxattr = squashfs_listxattr |
252 | }; | 251 | }; |
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c index d688ef42a6a1..79b9c31a0c8f 100644 --- a/fs/squashfs/symlink.c +++ b/fs/squashfs/symlink.c | |||
@@ -120,7 +120,6 @@ const struct address_space_operations squashfs_symlink_aops = { | |||
120 | const struct inode_operations squashfs_symlink_inode_ops = { | 120 | const struct inode_operations squashfs_symlink_inode_ops = { |
121 | .readlink = generic_readlink, | 121 | .readlink = generic_readlink, |
122 | .get_link = page_get_link, | 122 | .get_link = page_get_link, |
123 | .getxattr = generic_getxattr, | ||
124 | .listxattr = squashfs_listxattr | 123 | .listxattr = squashfs_listxattr |
125 | }; | 124 | }; |
126 | 125 | ||
diff --git a/fs/squashfs/xattr.h b/fs/squashfs/xattr.h index c83f5d9ec125..afe70f815e3d 100644 --- a/fs/squashfs/xattr.h +++ b/fs/squashfs/xattr.h | |||
@@ -42,6 +42,5 @@ static inline int squashfs_xattr_lookup(struct super_block *sb, | |||
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | #define squashfs_listxattr NULL | 44 | #define squashfs_listxattr NULL |
45 | #define generic_getxattr NULL | ||
46 | #define squashfs_xattr_handlers NULL | 45 | #define squashfs_xattr_handlers NULL |
47 | #endif | 46 | #endif |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 4b86d3a738e1..1d55aeaebf23 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -1182,10 +1182,7 @@ const struct inode_operations ubifs_dir_inode_operations = { | |||
1182 | .rename = ubifs_rename, | 1182 | .rename = ubifs_rename, |
1183 | .setattr = ubifs_setattr, | 1183 | .setattr = ubifs_setattr, |
1184 | .getattr = ubifs_getattr, | 1184 | .getattr = ubifs_getattr, |
1185 | .setxattr = generic_setxattr, | ||
1186 | .getxattr = generic_getxattr, | ||
1187 | .listxattr = ubifs_listxattr, | 1185 | .listxattr = ubifs_listxattr, |
1188 | .removexattr = generic_removexattr, | ||
1189 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | 1186 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT |
1190 | .update_time = ubifs_update_time, | 1187 | .update_time = ubifs_update_time, |
1191 | #endif | 1188 | #endif |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index b0a6a53263f3..a746982fbcda 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -1621,10 +1621,7 @@ const struct address_space_operations ubifs_file_address_operations = { | |||
1621 | const struct inode_operations ubifs_file_inode_operations = { | 1621 | const struct inode_operations ubifs_file_inode_operations = { |
1622 | .setattr = ubifs_setattr, | 1622 | .setattr = ubifs_setattr, |
1623 | .getattr = ubifs_getattr, | 1623 | .getattr = ubifs_getattr, |
1624 | .setxattr = generic_setxattr, | ||
1625 | .getxattr = generic_getxattr, | ||
1626 | .listxattr = ubifs_listxattr, | 1624 | .listxattr = ubifs_listxattr, |
1627 | .removexattr = generic_removexattr, | ||
1628 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | 1625 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT |
1629 | .update_time = ubifs_update_time, | 1626 | .update_time = ubifs_update_time, |
1630 | #endif | 1627 | #endif |
@@ -1635,10 +1632,7 @@ const struct inode_operations ubifs_symlink_inode_operations = { | |||
1635 | .get_link = simple_get_link, | 1632 | .get_link = simple_get_link, |
1636 | .setattr = ubifs_setattr, | 1633 | .setattr = ubifs_setattr, |
1637 | .getattr = ubifs_getattr, | 1634 | .getattr = ubifs_getattr, |
1638 | .setxattr = generic_setxattr, | ||
1639 | .getxattr = generic_getxattr, | ||
1640 | .listxattr = ubifs_listxattr, | 1635 | .listxattr = ubifs_listxattr, |
1641 | .removexattr = generic_removexattr, | ||
1642 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT | 1636 | #ifdef CONFIG_UBIFS_ATIME_SUPPORT |
1643 | .update_time = ubifs_update_time, | 1637 | .update_time = ubifs_update_time, |
1644 | #endif | 1638 | #endif |
diff --git a/fs/xattr.c b/fs/xattr.c index c243905835ab..3368659c471e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -24,6 +24,59 @@ | |||
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | 26 | ||
27 | static const char * | ||
28 | strcmp_prefix(const char *a, const char *a_prefix) | ||
29 | { | ||
30 | while (*a_prefix && *a == *a_prefix) { | ||
31 | a++; | ||
32 | a_prefix++; | ||
33 | } | ||
34 | return *a_prefix ? NULL : a; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * In order to implement different sets of xattr operations for each xattr | ||
39 | * prefix, a filesystem should create a null-terminated array of struct | ||
40 | * xattr_handler (one for each prefix) and hang a pointer to it off of the | ||
41 | * s_xattr field of the superblock. | ||
42 | */ | ||
43 | #define for_each_xattr_handler(handlers, handler) \ | ||
44 | if (handlers) \ | ||
45 | for ((handler) = *(handlers)++; \ | ||
46 | (handler) != NULL; \ | ||
47 | (handler) = *(handlers)++) | ||
48 | |||
49 | /* | ||
50 | * Find the xattr_handler with the matching prefix. | ||
51 | */ | ||
52 | static const struct xattr_handler * | ||
53 | xattr_resolve_name(struct inode *inode, const char **name) | ||
54 | { | ||
55 | const struct xattr_handler **handlers = inode->i_sb->s_xattr; | ||
56 | const struct xattr_handler *handler; | ||
57 | |||
58 | if (!(inode->i_opflags & IOP_XATTR)) { | ||
59 | if (unlikely(is_bad_inode(inode))) | ||
60 | return ERR_PTR(-EIO); | ||
61 | return ERR_PTR(-EOPNOTSUPP); | ||
62 | } | ||
63 | for_each_xattr_handler(handlers, handler) { | ||
64 | const char *n; | ||
65 | |||
66 | n = strcmp_prefix(*name, xattr_prefix(handler)); | ||
67 | if (n) { | ||
68 | if (!handler->prefix ^ !*n) { | ||
69 | if (*n) | ||
70 | continue; | ||
71 | return ERR_PTR(-EINVAL); | ||
72 | } | ||
73 | *name = n; | ||
74 | return handler; | ||
75 | } | ||
76 | } | ||
77 | return ERR_PTR(-EOPNOTSUPP); | ||
78 | } | ||
79 | |||
27 | /* | 80 | /* |
28 | * Check permissions for extended attribute access. This is a bit complicated | 81 | * Check permissions for extended attribute access. This is a bit complicated |
29 | * because different namespaces have very different rules. | 82 | * because different namespaces have very different rules. |
@@ -80,6 +133,23 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
80 | return inode_permission(inode, mask); | 133 | return inode_permission(inode, mask); |
81 | } | 134 | } |
82 | 135 | ||
136 | int | ||
137 | __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, | ||
138 | const void *value, size_t size, int flags) | ||
139 | { | ||
140 | const struct xattr_handler *handler; | ||
141 | |||
142 | handler = xattr_resolve_name(inode, &name); | ||
143 | if (IS_ERR(handler)) | ||
144 | return PTR_ERR(handler); | ||
145 | if (!handler->set) | ||
146 | return -EOPNOTSUPP; | ||
147 | if (size == 0) | ||
148 | value = ""; /* empty EA, do not remove */ | ||
149 | return handler->set(handler, dentry, inode, name, value, size, flags); | ||
150 | } | ||
151 | EXPORT_SYMBOL(__vfs_setxattr); | ||
152 | |||
83 | /** | 153 | /** |
84 | * __vfs_setxattr_noperm - perform setxattr operation without performing | 154 | * __vfs_setxattr_noperm - perform setxattr operation without performing |
85 | * permission checks. | 155 | * permission checks. |
@@ -106,8 +176,8 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
106 | 176 | ||
107 | if (issec) | 177 | if (issec) |
108 | inode->i_flags &= ~S_NOSEC; | 178 | inode->i_flags &= ~S_NOSEC; |
109 | if (inode->i_op->setxattr) { | 179 | if (inode->i_opflags & IOP_XATTR) { |
110 | error = inode->i_op->setxattr(dentry, inode, name, value, size, flags); | 180 | error = __vfs_setxattr(dentry, inode, name, value, size, flags); |
111 | if (!error) { | 181 | if (!error) { |
112 | fsnotify_xattr(dentry); | 182 | fsnotify_xattr(dentry); |
113 | security_inode_post_setxattr(dentry, name, value, | 183 | security_inode_post_setxattr(dentry, name, value, |
@@ -115,6 +185,9 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
115 | } | 185 | } |
116 | } else if (issec) { | 186 | } else if (issec) { |
117 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | 187 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; |
188 | |||
189 | if (unlikely(is_bad_inode(inode))) | ||
190 | return -EIO; | ||
118 | error = security_inode_setsecurity(inode, suffix, value, | 191 | error = security_inode_setsecurity(inode, suffix, value, |
119 | size, flags); | 192 | size, flags); |
120 | if (!error) | 193 | if (!error) |
@@ -188,6 +261,7 @@ ssize_t | |||
188 | vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, | 261 | vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, |
189 | size_t xattr_size, gfp_t flags) | 262 | size_t xattr_size, gfp_t flags) |
190 | { | 263 | { |
264 | const struct xattr_handler *handler; | ||
191 | struct inode *inode = dentry->d_inode; | 265 | struct inode *inode = dentry->d_inode; |
192 | char *value = *xattr_value; | 266 | char *value = *xattr_value; |
193 | int error; | 267 | int error; |
@@ -196,10 +270,12 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, | |||
196 | if (error) | 270 | if (error) |
197 | return error; | 271 | return error; |
198 | 272 | ||
199 | if (!inode->i_op->getxattr) | 273 | handler = xattr_resolve_name(inode, &name); |
274 | if (IS_ERR(handler)) | ||
275 | return PTR_ERR(handler); | ||
276 | if (!handler->get) | ||
200 | return -EOPNOTSUPP; | 277 | return -EOPNOTSUPP; |
201 | 278 | error = handler->get(handler, dentry, inode, name, NULL, 0); | |
202 | error = inode->i_op->getxattr(dentry, inode, name, NULL, 0); | ||
203 | if (error < 0) | 279 | if (error < 0) |
204 | return error; | 280 | return error; |
205 | 281 | ||
@@ -210,12 +286,27 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, | |||
210 | memset(value, 0, error + 1); | 286 | memset(value, 0, error + 1); |
211 | } | 287 | } |
212 | 288 | ||
213 | error = inode->i_op->getxattr(dentry, inode, name, value, error); | 289 | error = handler->get(handler, dentry, inode, name, value, error); |
214 | *xattr_value = value; | 290 | *xattr_value = value; |
215 | return error; | 291 | return error; |
216 | } | 292 | } |
217 | 293 | ||
218 | ssize_t | 294 | ssize_t |
295 | __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, | ||
296 | void *value, size_t size) | ||
297 | { | ||
298 | const struct xattr_handler *handler; | ||
299 | |||
300 | handler = xattr_resolve_name(inode, &name); | ||
301 | if (IS_ERR(handler)) | ||
302 | return PTR_ERR(handler); | ||
303 | if (!handler->get) | ||
304 | return -EOPNOTSUPP; | ||
305 | return handler->get(handler, dentry, inode, name, value, size); | ||
306 | } | ||
307 | EXPORT_SYMBOL(__vfs_getxattr); | ||
308 | |||
309 | ssize_t | ||
219 | vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) | 310 | vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) |
220 | { | 311 | { |
221 | struct inode *inode = dentry->d_inode; | 312 | struct inode *inode = dentry->d_inode; |
@@ -242,28 +333,24 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) | |||
242 | return ret; | 333 | return ret; |
243 | } | 334 | } |
244 | nolsm: | 335 | nolsm: |
245 | if (inode->i_op->getxattr) | 336 | return __vfs_getxattr(dentry, inode, name, value, size); |
246 | error = inode->i_op->getxattr(dentry, inode, name, value, size); | ||
247 | else | ||
248 | error = -EOPNOTSUPP; | ||
249 | |||
250 | return error; | ||
251 | } | 337 | } |
252 | EXPORT_SYMBOL_GPL(vfs_getxattr); | 338 | EXPORT_SYMBOL_GPL(vfs_getxattr); |
253 | 339 | ||
254 | ssize_t | 340 | ssize_t |
255 | vfs_listxattr(struct dentry *d, char *list, size_t size) | 341 | vfs_listxattr(struct dentry *dentry, char *list, size_t size) |
256 | { | 342 | { |
343 | struct inode *inode = d_inode(dentry); | ||
257 | ssize_t error; | 344 | ssize_t error; |
258 | 345 | ||
259 | error = security_inode_listxattr(d); | 346 | error = security_inode_listxattr(dentry); |
260 | if (error) | 347 | if (error) |
261 | return error; | 348 | return error; |
262 | error = -EOPNOTSUPP; | 349 | if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) { |
263 | if (d->d_inode->i_op->listxattr) { | 350 | error = -EOPNOTSUPP; |
264 | error = d->d_inode->i_op->listxattr(d, list, size); | 351 | error = inode->i_op->listxattr(dentry, list, size); |
265 | } else { | 352 | } else { |
266 | error = security_inode_listsecurity(d->d_inode, list, size); | 353 | error = security_inode_listsecurity(inode, list, size); |
267 | if (size && error > size) | 354 | if (size && error > size) |
268 | error = -ERANGE; | 355 | error = -ERANGE; |
269 | } | 356 | } |
@@ -272,14 +359,26 @@ vfs_listxattr(struct dentry *d, char *list, size_t size) | |||
272 | EXPORT_SYMBOL_GPL(vfs_listxattr); | 359 | EXPORT_SYMBOL_GPL(vfs_listxattr); |
273 | 360 | ||
274 | int | 361 | int |
362 | __vfs_removexattr(struct dentry *dentry, const char *name) | ||
363 | { | ||
364 | struct inode *inode = d_inode(dentry); | ||
365 | const struct xattr_handler *handler; | ||
366 | |||
367 | handler = xattr_resolve_name(inode, &name); | ||
368 | if (IS_ERR(handler)) | ||
369 | return PTR_ERR(handler); | ||
370 | if (!handler->set) | ||
371 | return -EOPNOTSUPP; | ||
372 | return handler->set(handler, dentry, inode, name, NULL, 0, XATTR_REPLACE); | ||
373 | } | ||
374 | EXPORT_SYMBOL(__vfs_removexattr); | ||
375 | |||
376 | int | ||
275 | vfs_removexattr(struct dentry *dentry, const char *name) | 377 | vfs_removexattr(struct dentry *dentry, const char *name) |
276 | { | 378 | { |
277 | struct inode *inode = dentry->d_inode; | 379 | struct inode *inode = dentry->d_inode; |
278 | int error; | 380 | int error; |
279 | 381 | ||
280 | if (!inode->i_op->removexattr) | ||
281 | return -EOPNOTSUPP; | ||
282 | |||
283 | error = xattr_permission(inode, name, MAY_WRITE); | 382 | error = xattr_permission(inode, name, MAY_WRITE); |
284 | if (error) | 383 | if (error) |
285 | return error; | 384 | return error; |
@@ -289,7 +388,7 @@ vfs_removexattr(struct dentry *dentry, const char *name) | |||
289 | if (error) | 388 | if (error) |
290 | goto out; | 389 | goto out; |
291 | 390 | ||
292 | error = inode->i_op->removexattr(dentry, name); | 391 | error = __vfs_removexattr(dentry, name); |
293 | 392 | ||
294 | if (!error) { | 393 | if (!error) { |
295 | fsnotify_xattr(dentry); | 394 | fsnotify_xattr(dentry); |
@@ -641,76 +740,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | |||
641 | return error; | 740 | return error; |
642 | } | 741 | } |
643 | 742 | ||
644 | |||
645 | static const char * | ||
646 | strcmp_prefix(const char *a, const char *a_prefix) | ||
647 | { | ||
648 | while (*a_prefix && *a == *a_prefix) { | ||
649 | a++; | ||
650 | a_prefix++; | ||
651 | } | ||
652 | return *a_prefix ? NULL : a; | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * In order to implement different sets of xattr operations for each xattr | ||
657 | * prefix with the generic xattr API, a filesystem should create a | ||
658 | * null-terminated array of struct xattr_handler (one for each prefix) and | ||
659 | * hang a pointer to it off of the s_xattr field of the superblock. | ||
660 | * | ||
661 | * The generic_fooxattr() functions will use this list to dispatch xattr | ||
662 | * operations to the correct xattr_handler. | ||
663 | */ | ||
664 | #define for_each_xattr_handler(handlers, handler) \ | ||
665 | if (handlers) \ | ||
666 | for ((handler) = *(handlers)++; \ | ||
667 | (handler) != NULL; \ | ||
668 | (handler) = *(handlers)++) | ||
669 | |||
670 | /* | ||
671 | * Find the xattr_handler with the matching prefix. | ||
672 | */ | ||
673 | static const struct xattr_handler * | ||
674 | xattr_resolve_name(const struct xattr_handler **handlers, const char **name) | ||
675 | { | ||
676 | const struct xattr_handler *handler; | ||
677 | |||
678 | if (!*name) | ||
679 | return ERR_PTR(-EINVAL); | ||
680 | |||
681 | for_each_xattr_handler(handlers, handler) { | ||
682 | const char *n; | ||
683 | |||
684 | n = strcmp_prefix(*name, xattr_prefix(handler)); | ||
685 | if (n) { | ||
686 | if (!handler->prefix ^ !*n) { | ||
687 | if (*n) | ||
688 | continue; | ||
689 | return ERR_PTR(-EINVAL); | ||
690 | } | ||
691 | *name = n; | ||
692 | return handler; | ||
693 | } | ||
694 | } | ||
695 | return ERR_PTR(-EOPNOTSUPP); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Find the handler for the prefix and dispatch its get() operation. | ||
700 | */ | ||
701 | ssize_t | ||
702 | generic_getxattr(struct dentry *dentry, struct inode *inode, | ||
703 | const char *name, void *buffer, size_t size) | ||
704 | { | ||
705 | const struct xattr_handler *handler; | ||
706 | |||
707 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | ||
708 | if (IS_ERR(handler)) | ||
709 | return PTR_ERR(handler); | ||
710 | return handler->get(handler, dentry, inode, | ||
711 | name, buffer, size); | ||
712 | } | ||
713 | |||
714 | /* | 743 | /* |
715 | * Combine the results of the list() operation from every xattr_handler in the | 744 | * Combine the results of the list() operation from every xattr_handler in the |
716 | * list. | 745 | * list. |
@@ -747,44 +776,7 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
747 | } | 776 | } |
748 | return size; | 777 | return size; |
749 | } | 778 | } |
750 | |||
751 | /* | ||
752 | * Find the handler for the prefix and dispatch its set() operation. | ||
753 | */ | ||
754 | int | ||
755 | generic_setxattr(struct dentry *dentry, struct inode *inode, const char *name, | ||
756 | const void *value, size_t size, int flags) | ||
757 | { | ||
758 | const struct xattr_handler *handler; | ||
759 | |||
760 | if (size == 0) | ||
761 | value = ""; /* empty EA, do not remove */ | ||
762 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | ||
763 | if (IS_ERR(handler)) | ||
764 | return PTR_ERR(handler); | ||
765 | return handler->set(handler, dentry, inode, name, value, size, flags); | ||
766 | } | ||
767 | |||
768 | /* | ||
769 | * Find the handler for the prefix and dispatch its set() operation to remove | ||
770 | * any associated extended attribute. | ||
771 | */ | ||
772 | int | ||
773 | generic_removexattr(struct dentry *dentry, const char *name) | ||
774 | { | ||
775 | const struct xattr_handler *handler; | ||
776 | |||
777 | handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name); | ||
778 | if (IS_ERR(handler)) | ||
779 | return PTR_ERR(handler); | ||
780 | return handler->set(handler, dentry, d_inode(dentry), name, NULL, | ||
781 | 0, XATTR_REPLACE); | ||
782 | } | ||
783 | |||
784 | EXPORT_SYMBOL(generic_getxattr); | ||
785 | EXPORT_SYMBOL(generic_listxattr); | 779 | EXPORT_SYMBOL(generic_listxattr); |
786 | EXPORT_SYMBOL(generic_setxattr); | ||
787 | EXPORT_SYMBOL(generic_removexattr); | ||
788 | 780 | ||
789 | /** | 781 | /** |
790 | * xattr_full_name - Compute full attribute name from suffix | 782 | * xattr_full_name - Compute full attribute name from suffix |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index ba99803eba98..a7404c5aafe2 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -1066,9 +1066,6 @@ static const struct inode_operations xfs_inode_operations = { | |||
1066 | .set_acl = xfs_set_acl, | 1066 | .set_acl = xfs_set_acl, |
1067 | .getattr = xfs_vn_getattr, | 1067 | .getattr = xfs_vn_getattr, |
1068 | .setattr = xfs_vn_setattr, | 1068 | .setattr = xfs_vn_setattr, |
1069 | .setxattr = generic_setxattr, | ||
1070 | .getxattr = generic_getxattr, | ||
1071 | .removexattr = generic_removexattr, | ||
1072 | .listxattr = xfs_vn_listxattr, | 1069 | .listxattr = xfs_vn_listxattr, |
1073 | .fiemap = xfs_vn_fiemap, | 1070 | .fiemap = xfs_vn_fiemap, |
1074 | .update_time = xfs_vn_update_time, | 1071 | .update_time = xfs_vn_update_time, |
@@ -1094,9 +1091,6 @@ static const struct inode_operations xfs_dir_inode_operations = { | |||
1094 | .set_acl = xfs_set_acl, | 1091 | .set_acl = xfs_set_acl, |
1095 | .getattr = xfs_vn_getattr, | 1092 | .getattr = xfs_vn_getattr, |
1096 | .setattr = xfs_vn_setattr, | 1093 | .setattr = xfs_vn_setattr, |
1097 | .setxattr = generic_setxattr, | ||
1098 | .getxattr = generic_getxattr, | ||
1099 | .removexattr = generic_removexattr, | ||
1100 | .listxattr = xfs_vn_listxattr, | 1094 | .listxattr = xfs_vn_listxattr, |
1101 | .update_time = xfs_vn_update_time, | 1095 | .update_time = xfs_vn_update_time, |
1102 | .tmpfile = xfs_vn_tmpfile, | 1096 | .tmpfile = xfs_vn_tmpfile, |
@@ -1122,9 +1116,6 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { | |||
1122 | .set_acl = xfs_set_acl, | 1116 | .set_acl = xfs_set_acl, |
1123 | .getattr = xfs_vn_getattr, | 1117 | .getattr = xfs_vn_getattr, |
1124 | .setattr = xfs_vn_setattr, | 1118 | .setattr = xfs_vn_setattr, |
1125 | .setxattr = generic_setxattr, | ||
1126 | .getxattr = generic_getxattr, | ||
1127 | .removexattr = generic_removexattr, | ||
1128 | .listxattr = xfs_vn_listxattr, | 1119 | .listxattr = xfs_vn_listxattr, |
1129 | .update_time = xfs_vn_update_time, | 1120 | .update_time = xfs_vn_update_time, |
1130 | .tmpfile = xfs_vn_tmpfile, | 1121 | .tmpfile = xfs_vn_tmpfile, |
@@ -1135,9 +1126,6 @@ static const struct inode_operations xfs_symlink_inode_operations = { | |||
1135 | .get_link = xfs_vn_get_link, | 1126 | .get_link = xfs_vn_get_link, |
1136 | .getattr = xfs_vn_getattr, | 1127 | .getattr = xfs_vn_getattr, |
1137 | .setattr = xfs_vn_setattr, | 1128 | .setattr = xfs_vn_setattr, |
1138 | .setxattr = generic_setxattr, | ||
1139 | .getxattr = generic_getxattr, | ||
1140 | .removexattr = generic_removexattr, | ||
1141 | .listxattr = xfs_vn_listxattr, | 1129 | .listxattr = xfs_vn_listxattr, |
1142 | .update_time = xfs_vn_update_time, | 1130 | .update_time = xfs_vn_update_time, |
1143 | }; | 1131 | }; |
@@ -1147,9 +1135,6 @@ static const struct inode_operations xfs_inline_symlink_inode_operations = { | |||
1147 | .get_link = xfs_vn_get_link_inline, | 1135 | .get_link = xfs_vn_get_link_inline, |
1148 | .getattr = xfs_vn_getattr, | 1136 | .getattr = xfs_vn_getattr, |
1149 | .setattr = xfs_vn_setattr, | 1137 | .setattr = xfs_vn_setattr, |
1150 | .setxattr = generic_setxattr, | ||
1151 | .getxattr = generic_getxattr, | ||
1152 | .removexattr = generic_removexattr, | ||
1153 | .listxattr = xfs_vn_listxattr, | 1138 | .listxattr = xfs_vn_listxattr, |
1154 | .update_time = xfs_vn_update_time, | 1139 | .update_time = xfs_vn_update_time, |
1155 | }; | 1140 | }; |