diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-20 08:16:43 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 23:58:18 -0500 |
commit | 996a710d46418cacb5b4a519ab9341a74066551d (patch) | |
tree | c07492fe2387367b788adfd275e391602b2d9d81 /fs/btrfs | |
parent | 37bc15392a2363ca822b2c2828e0ccafbea32f75 (diff) |
btrfs: use generic posix ACL infrastructure
Also don't bother to set up a .get_acl method for symlinks as we do not
support access control (ACLs or even mode bits) for symlinks in Linux.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/acl.c | 142 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 7 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 7 | ||||
-rw-r--r-- | fs/btrfs/xattr.c | 5 | ||||
-rw-r--r-- | fs/btrfs/xattr.h | 2 |
5 files changed, 28 insertions, 135 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index b56519d47268..ff9b3995d453 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -35,13 +35,6 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
35 | char *value = NULL; | 35 | char *value = NULL; |
36 | struct posix_acl *acl; | 36 | struct posix_acl *acl; |
37 | 37 | ||
38 | if (!IS_POSIXACL(inode)) | ||
39 | return NULL; | ||
40 | |||
41 | acl = get_cached_acl(inode, type); | ||
42 | if (acl != ACL_NOT_CACHED) | ||
43 | return acl; | ||
44 | |||
45 | switch (type) { | 38 | switch (type) { |
46 | case ACL_TYPE_ACCESS: | 39 | case ACL_TYPE_ACCESS: |
47 | name = POSIX_ACL_XATTR_ACCESS; | 40 | name = POSIX_ACL_XATTR_ACCESS; |
@@ -76,31 +69,10 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
76 | return acl; | 69 | return acl; |
77 | } | 70 | } |
78 | 71 | ||
79 | static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, | ||
80 | void *value, size_t size, int type) | ||
81 | { | ||
82 | struct posix_acl *acl; | ||
83 | int ret = 0; | ||
84 | |||
85 | if (!IS_POSIXACL(dentry->d_inode)) | ||
86 | return -EOPNOTSUPP; | ||
87 | |||
88 | acl = btrfs_get_acl(dentry->d_inode, type); | ||
89 | |||
90 | if (IS_ERR(acl)) | ||
91 | return PTR_ERR(acl); | ||
92 | if (acl == NULL) | ||
93 | return -ENODATA; | ||
94 | ret = posix_acl_to_xattr(&init_user_ns, acl, value, size); | ||
95 | posix_acl_release(acl); | ||
96 | |||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | /* | 72 | /* |
101 | * Needs to be called with fs_mutex held | 73 | * Needs to be called with fs_mutex held |
102 | */ | 74 | */ |
103 | static int btrfs_set_acl(struct btrfs_trans_handle *trans, | 75 | static int __btrfs_set_acl(struct btrfs_trans_handle *trans, |
104 | struct inode *inode, struct posix_acl *acl, int type) | 76 | struct inode *inode, struct posix_acl *acl, int type) |
105 | { | 77 | { |
106 | int ret, size = 0; | 78 | int ret, size = 0; |
@@ -158,35 +130,9 @@ out: | |||
158 | return ret; | 130 | return ret; |
159 | } | 131 | } |
160 | 132 | ||
161 | static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | 133 | int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
162 | const void *value, size_t size, int flags, int type) | ||
163 | { | 134 | { |
164 | int ret; | 135 | return __btrfs_set_acl(NULL, inode, acl, type); |
165 | struct posix_acl *acl = NULL; | ||
166 | |||
167 | if (!inode_owner_or_capable(dentry->d_inode)) | ||
168 | return -EPERM; | ||
169 | |||
170 | if (!IS_POSIXACL(dentry->d_inode)) | ||
171 | return -EOPNOTSUPP; | ||
172 | |||
173 | if (value) { | ||
174 | acl = posix_acl_from_xattr(&init_user_ns, value, size); | ||
175 | if (IS_ERR(acl)) | ||
176 | return PTR_ERR(acl); | ||
177 | |||
178 | if (acl) { | ||
179 | ret = posix_acl_valid(acl); | ||
180 | if (ret) | ||
181 | goto out; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); | ||
186 | out: | ||
187 | posix_acl_release(acl); | ||
188 | |||
189 | return ret; | ||
190 | } | 136 | } |
191 | 137 | ||
192 | /* | 138 | /* |
@@ -197,83 +143,31 @@ out: | |||
197 | int btrfs_init_acl(struct btrfs_trans_handle *trans, | 143 | int btrfs_init_acl(struct btrfs_trans_handle *trans, |
198 | struct inode *inode, struct inode *dir) | 144 | struct inode *inode, struct inode *dir) |
199 | { | 145 | { |
200 | struct posix_acl *acl = NULL; | 146 | struct posix_acl *default_acl, *acl; |
201 | int ret = 0; | 147 | int ret = 0; |
202 | 148 | ||
203 | /* this happens with subvols */ | 149 | /* this happens with subvols */ |
204 | if (!dir) | 150 | if (!dir) |
205 | return 0; | 151 | return 0; |
206 | 152 | ||
207 | if (!S_ISLNK(inode->i_mode)) { | 153 | ret = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); |
208 | if (IS_POSIXACL(dir)) { | 154 | if (ret) |
209 | acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT); | 155 | return ret; |
210 | if (IS_ERR(acl)) | ||
211 | return PTR_ERR(acl); | ||
212 | } | ||
213 | 156 | ||
214 | if (!acl) | 157 | if (default_acl) { |
215 | inode->i_mode &= ~current_umask(); | 158 | ret = __btrfs_set_acl(trans, inode, default_acl, |
159 | ACL_TYPE_DEFAULT); | ||
160 | posix_acl_release(default_acl); | ||
216 | } | 161 | } |
217 | 162 | ||
218 | if (IS_POSIXACL(dir) && acl) { | 163 | if (acl) { |
219 | if (S_ISDIR(inode->i_mode)) { | 164 | if (!ret) |
220 | ret = btrfs_set_acl(trans, inode, acl, | 165 | ret = __btrfs_set_acl(trans, inode, acl, |
221 | ACL_TYPE_DEFAULT); | 166 | ACL_TYPE_ACCESS); |
222 | if (ret) | 167 | posix_acl_release(acl); |
223 | goto failed; | ||
224 | } | ||
225 | ret = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | ||
226 | if (ret < 0) | ||
227 | return ret; | ||
228 | |||
229 | if (ret > 0) { | ||
230 | /* we need an acl */ | ||
231 | ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); | ||
232 | } else if (ret < 0) { | ||
233 | cache_no_acl(inode); | ||
234 | } | ||
235 | } else { | ||
236 | cache_no_acl(inode); | ||
237 | } | 168 | } |
238 | failed: | ||
239 | posix_acl_release(acl); | ||
240 | |||
241 | return ret; | ||
242 | } | ||
243 | 169 | ||
244 | int btrfs_acl_chmod(struct inode *inode) | 170 | if (!default_acl && !acl) |
245 | { | 171 | cache_no_acl(inode); |
246 | struct posix_acl *acl; | ||
247 | int ret = 0; | ||
248 | |||
249 | if (S_ISLNK(inode->i_mode)) | ||
250 | return -EOPNOTSUPP; | ||
251 | |||
252 | if (!IS_POSIXACL(inode)) | ||
253 | return 0; | ||
254 | |||
255 | acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); | ||
256 | if (IS_ERR_OR_NULL(acl)) | ||
257 | return PTR_ERR(acl); | ||
258 | |||
259 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | ||
260 | if (ret) | ||
261 | return ret; | ||
262 | ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS); | ||
263 | posix_acl_release(acl); | ||
264 | return ret; | 172 | return ret; |
265 | } | 173 | } |
266 | |||
267 | const struct xattr_handler btrfs_xattr_acl_default_handler = { | ||
268 | .prefix = POSIX_ACL_XATTR_DEFAULT, | ||
269 | .flags = ACL_TYPE_DEFAULT, | ||
270 | .get = btrfs_xattr_acl_get, | ||
271 | .set = btrfs_xattr_acl_set, | ||
272 | }; | ||
273 | |||
274 | const struct xattr_handler btrfs_xattr_acl_access_handler = { | ||
275 | .prefix = POSIX_ACL_XATTR_ACCESS, | ||
276 | .flags = ACL_TYPE_ACCESS, | ||
277 | .get = btrfs_xattr_acl_get, | ||
278 | .set = btrfs_xattr_acl_set, | ||
279 | }; | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 54ab86127f7a..7506825211a2 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3899,20 +3899,17 @@ do { \ | |||
3899 | /* acl.c */ | 3899 | /* acl.c */ |
3900 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 3900 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
3901 | struct posix_acl *btrfs_get_acl(struct inode *inode, int type); | 3901 | struct posix_acl *btrfs_get_acl(struct inode *inode, int type); |
3902 | int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | ||
3902 | int btrfs_init_acl(struct btrfs_trans_handle *trans, | 3903 | int btrfs_init_acl(struct btrfs_trans_handle *trans, |
3903 | struct inode *inode, struct inode *dir); | 3904 | struct inode *inode, struct inode *dir); |
3904 | int btrfs_acl_chmod(struct inode *inode); | ||
3905 | #else | 3905 | #else |
3906 | #define btrfs_get_acl NULL | 3906 | #define btrfs_get_acl NULL |
3907 | #define btrfs_set_acl NULL | ||
3907 | static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, | 3908 | static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, |
3908 | struct inode *inode, struct inode *dir) | 3909 | struct inode *inode, struct inode *dir) |
3909 | { | 3910 | { |
3910 | return 0; | 3911 | return 0; |
3911 | } | 3912 | } |
3912 | static inline int btrfs_acl_chmod(struct inode *inode) | ||
3913 | { | ||
3914 | return 0; | ||
3915 | } | ||
3916 | #endif | 3913 | #endif |
3917 | 3914 | ||
3918 | /* relocation.c */ | 3915 | /* relocation.c */ |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f1a77449d032..b1314300d9fc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4464,7 +4464,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
4464 | err = btrfs_dirty_inode(inode); | 4464 | err = btrfs_dirty_inode(inode); |
4465 | 4465 | ||
4466 | if (!err && attr->ia_valid & ATTR_MODE) | 4466 | if (!err && attr->ia_valid & ATTR_MODE) |
4467 | err = btrfs_acl_chmod(inode); | 4467 | err = posix_acl_chmod(inode, inode->i_mode); |
4468 | } | 4468 | } |
4469 | 4469 | ||
4470 | return err; | 4470 | return err; |
@@ -8649,12 +8649,14 @@ static const struct inode_operations btrfs_dir_inode_operations = { | |||
8649 | .removexattr = btrfs_removexattr, | 8649 | .removexattr = btrfs_removexattr, |
8650 | .permission = btrfs_permission, | 8650 | .permission = btrfs_permission, |
8651 | .get_acl = btrfs_get_acl, | 8651 | .get_acl = btrfs_get_acl, |
8652 | .set_acl = btrfs_set_acl, | ||
8652 | .update_time = btrfs_update_time, | 8653 | .update_time = btrfs_update_time, |
8653 | }; | 8654 | }; |
8654 | static const struct inode_operations btrfs_dir_ro_inode_operations = { | 8655 | static const struct inode_operations btrfs_dir_ro_inode_operations = { |
8655 | .lookup = btrfs_lookup, | 8656 | .lookup = btrfs_lookup, |
8656 | .permission = btrfs_permission, | 8657 | .permission = btrfs_permission, |
8657 | .get_acl = btrfs_get_acl, | 8658 | .get_acl = btrfs_get_acl, |
8659 | .set_acl = btrfs_set_acl, | ||
8658 | .update_time = btrfs_update_time, | 8660 | .update_time = btrfs_update_time, |
8659 | }; | 8661 | }; |
8660 | 8662 | ||
@@ -8724,6 +8726,7 @@ static const struct inode_operations btrfs_file_inode_operations = { | |||
8724 | .permission = btrfs_permission, | 8726 | .permission = btrfs_permission, |
8725 | .fiemap = btrfs_fiemap, | 8727 | .fiemap = btrfs_fiemap, |
8726 | .get_acl = btrfs_get_acl, | 8728 | .get_acl = btrfs_get_acl, |
8729 | .set_acl = btrfs_set_acl, | ||
8727 | .update_time = btrfs_update_time, | 8730 | .update_time = btrfs_update_time, |
8728 | }; | 8731 | }; |
8729 | static const struct inode_operations btrfs_special_inode_operations = { | 8732 | static const struct inode_operations btrfs_special_inode_operations = { |
@@ -8735,6 +8738,7 @@ static const struct inode_operations btrfs_special_inode_operations = { | |||
8735 | .listxattr = btrfs_listxattr, | 8738 | .listxattr = btrfs_listxattr, |
8736 | .removexattr = btrfs_removexattr, | 8739 | .removexattr = btrfs_removexattr, |
8737 | .get_acl = btrfs_get_acl, | 8740 | .get_acl = btrfs_get_acl, |
8741 | .set_acl = btrfs_set_acl, | ||
8738 | .update_time = btrfs_update_time, | 8742 | .update_time = btrfs_update_time, |
8739 | }; | 8743 | }; |
8740 | static const struct inode_operations btrfs_symlink_inode_operations = { | 8744 | static const struct inode_operations btrfs_symlink_inode_operations = { |
@@ -8748,7 +8752,6 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
8748 | .getxattr = btrfs_getxattr, | 8752 | .getxattr = btrfs_getxattr, |
8749 | .listxattr = btrfs_listxattr, | 8753 | .listxattr = btrfs_listxattr, |
8750 | .removexattr = btrfs_removexattr, | 8754 | .removexattr = btrfs_removexattr, |
8751 | .get_acl = btrfs_get_acl, | ||
8752 | .update_time = btrfs_update_time, | 8755 | .update_time = btrfs_update_time, |
8753 | }; | 8756 | }; |
8754 | 8757 | ||
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 05740b9789e4..3d1c301c9260 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/rwsem.h> | 22 | #include <linux/rwsem.h> |
23 | #include <linux/xattr.h> | 23 | #include <linux/xattr.h> |
24 | #include <linux/security.h> | 24 | #include <linux/security.h> |
25 | #include <linux/posix_acl_xattr.h> | ||
25 | #include "ctree.h" | 26 | #include "ctree.h" |
26 | #include "btrfs_inode.h" | 27 | #include "btrfs_inode.h" |
27 | #include "transaction.h" | 28 | #include "transaction.h" |
@@ -313,8 +314,8 @@ err: | |||
313 | */ | 314 | */ |
314 | const struct xattr_handler *btrfs_xattr_handlers[] = { | 315 | const struct xattr_handler *btrfs_xattr_handlers[] = { |
315 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 316 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
316 | &btrfs_xattr_acl_access_handler, | 317 | &posix_acl_access_xattr_handler, |
317 | &btrfs_xattr_acl_default_handler, | 318 | &posix_acl_default_xattr_handler, |
318 | #endif | 319 | #endif |
319 | NULL, | 320 | NULL, |
320 | }; | 321 | }; |
diff --git a/fs/btrfs/xattr.h b/fs/btrfs/xattr.h index b3cc8039134b..5049608d1388 100644 --- a/fs/btrfs/xattr.h +++ b/fs/btrfs/xattr.h | |||
@@ -21,8 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/xattr.h> | 22 | #include <linux/xattr.h> |
23 | 23 | ||
24 | extern const struct xattr_handler btrfs_xattr_acl_access_handler; | ||
25 | extern const struct xattr_handler btrfs_xattr_acl_default_handler; | ||
26 | extern const struct xattr_handler *btrfs_xattr_handlers[]; | 24 | extern const struct xattr_handler *btrfs_xattr_handlers[]; |
27 | 25 | ||
28 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, | 26 | extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, |