diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 15:53:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 15:53:15 -0400 |
commit | 0003230e8200699860f0b10af524dc47bf8aecad (patch) | |
tree | 8addb0c889b32111d6973c46cd3d0a5b5c17606c /fs/ext4/acl.c | |
parent | 4b478cedcdc1b2d131170f22bd3f916e53472f52 (diff) | |
parent | 4e34e719e457f2e031297175410fc0bd4016a085 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
fs: take the ACL checks to common code
bury posix_acl_..._masq() variants
kill boilerplates around posix_acl_create_masq()
generic_acl: no need to clone acl just to push it to set_cached_acl()
kill boilerplate around posix_acl_chmod_masq()
reiserfs: cache negative ACLs for v1 stat format
xfs: cache negative ACLs if there is no attribute fork
9p: do no return 0 from ->check_acl without actually checking
vfs: move ACL cache lookup into generic code
CIFS: Fix oops while mounting with prefixpath
xfs: Fix wrong return value of xfs_file_aio_write
fix devtmpfs race
caam: don't pass bogus S_IFCHR to debugfs_create_...()
get rid of create_proc_entry() abuses - proc_mkdir() is there for purpose
asus-wmi: ->is_visible() can't return negative
fix jffs2 ACLs on big-endian with 16bit mode_t
9p: close ACL leaks
ocfs2_init_acl(): fix a leak
VFS : mount lock scalability for internal mounts
Diffstat (limited to 'fs/ext4/acl.c')
-rw-r--r-- | fs/ext4/acl.c | 95 |
1 files changed, 30 insertions, 65 deletions
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 60d900fcc3db..dca2d1ded931 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
@@ -131,7 +131,7 @@ fail: | |||
131 | * | 131 | * |
132 | * inode->i_mutex: don't care | 132 | * inode->i_mutex: don't care |
133 | */ | 133 | */ |
134 | static struct posix_acl * | 134 | struct posix_acl * |
135 | ext4_get_acl(struct inode *inode, int type) | 135 | ext4_get_acl(struct inode *inode, int type) |
136 | { | 136 | { |
137 | int name_index; | 137 | int name_index; |
@@ -237,29 +237,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type, | |||
237 | return error; | 237 | return error; |
238 | } | 238 | } |
239 | 239 | ||
240 | int | ||
241 | ext4_check_acl(struct inode *inode, int mask) | ||
242 | { | ||
243 | struct posix_acl *acl; | ||
244 | |||
245 | if (mask & MAY_NOT_BLOCK) { | ||
246 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) | ||
247 | return -ECHILD; | ||
248 | return -EAGAIN; | ||
249 | } | ||
250 | |||
251 | acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); | ||
252 | if (IS_ERR(acl)) | ||
253 | return PTR_ERR(acl); | ||
254 | if (acl) { | ||
255 | int error = posix_acl_permission(inode, acl, mask); | ||
256 | posix_acl_release(acl); | ||
257 | return error; | ||
258 | } | ||
259 | |||
260 | return -EAGAIN; | ||
261 | } | ||
262 | |||
263 | /* | 240 | /* |
264 | * Initialize the ACLs of a new inode. Called from ext4_new_inode. | 241 | * Initialize the ACLs of a new inode. Called from ext4_new_inode. |
265 | * | 242 | * |
@@ -282,8 +259,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
282 | inode->i_mode &= ~current_umask(); | 259 | inode->i_mode &= ~current_umask(); |
283 | } | 260 | } |
284 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 261 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
285 | struct posix_acl *clone; | 262 | mode_t mode = inode->i_mode; |
286 | mode_t mode; | ||
287 | 263 | ||
288 | if (S_ISDIR(inode->i_mode)) { | 264 | if (S_ISDIR(inode->i_mode)) { |
289 | error = ext4_set_acl(handle, inode, | 265 | error = ext4_set_acl(handle, inode, |
@@ -291,22 +267,15 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
291 | if (error) | 267 | if (error) |
292 | goto cleanup; | 268 | goto cleanup; |
293 | } | 269 | } |
294 | clone = posix_acl_clone(acl, GFP_NOFS); | 270 | error = posix_acl_create(&acl, GFP_NOFS, &mode); |
295 | error = -ENOMEM; | 271 | if (error < 0) |
296 | if (!clone) | 272 | return error; |
297 | goto cleanup; | 273 | |
298 | 274 | inode->i_mode = mode; | |
299 | mode = inode->i_mode; | 275 | if (error > 0) { |
300 | error = posix_acl_create_masq(clone, &mode); | 276 | /* This is an extended ACL */ |
301 | if (error >= 0) { | 277 | error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); |
302 | inode->i_mode = mode; | ||
303 | if (error > 0) { | ||
304 | /* This is an extended ACL */ | ||
305 | error = ext4_set_acl(handle, inode, | ||
306 | ACL_TYPE_ACCESS, clone); | ||
307 | } | ||
308 | } | 278 | } |
309 | posix_acl_release(clone); | ||
310 | } | 279 | } |
311 | cleanup: | 280 | cleanup: |
312 | posix_acl_release(acl); | 281 | posix_acl_release(acl); |
@@ -330,9 +299,12 @@ cleanup: | |||
330 | int | 299 | int |
331 | ext4_acl_chmod(struct inode *inode) | 300 | ext4_acl_chmod(struct inode *inode) |
332 | { | 301 | { |
333 | struct posix_acl *acl, *clone; | 302 | struct posix_acl *acl; |
303 | handle_t *handle; | ||
304 | int retries = 0; | ||
334 | int error; | 305 | int error; |
335 | 306 | ||
307 | |||
336 | if (S_ISLNK(inode->i_mode)) | 308 | if (S_ISLNK(inode->i_mode)) |
337 | return -EOPNOTSUPP; | 309 | return -EOPNOTSUPP; |
338 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 310 | if (!test_opt(inode->i_sb, POSIX_ACL)) |
@@ -340,31 +312,24 @@ ext4_acl_chmod(struct inode *inode) | |||
340 | acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); | 312 | acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); |
341 | if (IS_ERR(acl) || !acl) | 313 | if (IS_ERR(acl) || !acl) |
342 | return PTR_ERR(acl); | 314 | return PTR_ERR(acl); |
343 | clone = posix_acl_clone(acl, GFP_KERNEL); | 315 | error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); |
344 | posix_acl_release(acl); | 316 | if (error) |
345 | if (!clone) | 317 | return error; |
346 | return -ENOMEM; | 318 | retry: |
347 | error = posix_acl_chmod_masq(clone, inode->i_mode); | 319 | handle = ext4_journal_start(inode, |
348 | if (!error) { | 320 | EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); |
349 | handle_t *handle; | 321 | if (IS_ERR(handle)) { |
350 | int retries = 0; | 322 | error = PTR_ERR(handle); |
351 | 323 | ext4_std_error(inode->i_sb, error); | |
352 | retry: | 324 | goto out; |
353 | handle = ext4_journal_start(inode, | ||
354 | EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); | ||
355 | if (IS_ERR(handle)) { | ||
356 | error = PTR_ERR(handle); | ||
357 | ext4_std_error(inode->i_sb, error); | ||
358 | goto out; | ||
359 | } | ||
360 | error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); | ||
361 | ext4_journal_stop(handle); | ||
362 | if (error == -ENOSPC && | ||
363 | ext4_should_retry_alloc(inode->i_sb, &retries)) | ||
364 | goto retry; | ||
365 | } | 325 | } |
326 | error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); | ||
327 | ext4_journal_stop(handle); | ||
328 | if (error == -ENOSPC && | ||
329 | ext4_should_retry_alloc(inode->i_sb, &retries)) | ||
330 | goto retry; | ||
366 | out: | 331 | out: |
367 | posix_acl_release(clone); | 332 | posix_acl_release(acl); |
368 | return error; | 333 | return error; |
369 | } | 334 | } |
370 | 335 | ||