diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-12-20 08:16:42 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 23:58:18 -0500 |
commit | 37bc15392a2363ca822b2c2828e0ccafbea32f75 (patch) | |
tree | 66ed7ab55227b74ad0af9d79bde0e95bb49e13ed | |
parent | 5bf3258fd2acd8515450ab8efcd97c9d3b69f7f9 (diff) |
fs: make posix_acl_create more useful
Rename the current posix_acl_created to __posix_acl_create and add
a fully featured helper to set up the ACLs on file creation that
uses get_acl().
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/9p/acl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/acl.c | 2 | ||||
-rw-r--r-- | fs/ext2/acl.c | 2 | ||||
-rw-r--r-- | fs/ext3/acl.c | 2 | ||||
-rw-r--r-- | fs/ext4/acl.c | 2 | ||||
-rw-r--r-- | fs/f2fs/acl.c | 2 | ||||
-rw-r--r-- | fs/generic_acl.c | 2 | ||||
-rw-r--r-- | fs/gfs2/acl.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/posix_acl.c | 2 | ||||
-rw-r--r-- | fs/jffs2/acl.c | 2 | ||||
-rw-r--r-- | fs/jfs/acl.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs3acl.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/acl.c | 2 | ||||
-rw-r--r-- | fs/posix_acl.c | 57 | ||||
-rw-r--r-- | fs/reiserfs/xattr_acl.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.c | 4 | ||||
-rw-r--r-- | include/linux/posix_acl.h | 15 |
17 files changed, 81 insertions, 23 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index f5ce5c50c57e..8482f2d11606 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
@@ -200,7 +200,7 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep, | |||
200 | if (acl) { | 200 | if (acl) { |
201 | if (S_ISDIR(mode)) | 201 | if (S_ISDIR(mode)) |
202 | *dpacl = posix_acl_dup(acl); | 202 | *dpacl = posix_acl_dup(acl); |
203 | retval = posix_acl_create(&acl, GFP_NOFS, &mode); | 203 | retval = __posix_acl_create(&acl, GFP_NOFS, &mode); |
204 | if (retval < 0) | 204 | if (retval < 0) |
205 | return retval; | 205 | return retval; |
206 | if (retval > 0) | 206 | if (retval > 0) |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 1af04ff88986..b56519d47268 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -222,7 +222,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, | |||
222 | if (ret) | 222 | if (ret) |
223 | goto failed; | 223 | goto failed; |
224 | } | 224 | } |
225 | ret = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | 225 | ret = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); |
226 | if (ret < 0) | 226 | if (ret < 0) |
227 | return ret; | 227 | return ret; |
228 | 228 | ||
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 7006ced45324..6e842a764ee7 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -268,7 +268,7 @@ ext2_init_acl(struct inode *inode, struct inode *dir) | |||
268 | if (error) | 268 | if (error) |
269 | goto cleanup; | 269 | goto cleanup; |
270 | } | 270 | } |
271 | error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); | 271 | error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); |
272 | if (error < 0) | 272 | if (error < 0) |
273 | return error; | 273 | return error; |
274 | if (error > 0) { | 274 | if (error > 0) { |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 6691a6c6b211..4f3d8fa0c0a3 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -271,7 +271,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
271 | if (error) | 271 | if (error) |
272 | goto cleanup; | 272 | goto cleanup; |
273 | } | 273 | } |
274 | error = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | 274 | error = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); |
275 | if (error < 0) | 275 | if (error < 0) |
276 | return error; | 276 | return error; |
277 | 277 | ||
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 2eebe02fdf09..f827f3bb6d41 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
@@ -276,7 +276,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
276 | if (error) | 276 | if (error) |
277 | goto cleanup; | 277 | goto cleanup; |
278 | } | 278 | } |
279 | error = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | 279 | error = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); |
280 | if (error < 0) | 280 | if (error < 0) |
281 | return error; | 281 | return error; |
282 | 282 | ||
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 14c4df0ede34..45e84303c247 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c | |||
@@ -285,7 +285,7 @@ int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage) | |||
285 | if (error) | 285 | if (error) |
286 | goto cleanup; | 286 | goto cleanup; |
287 | } | 287 | } |
288 | error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); | 288 | error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); |
289 | if (error < 0) | 289 | if (error < 0) |
290 | return error; | 290 | return error; |
291 | if (error > 0) | 291 | if (error > 0) |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 46a5076e9776..4357f39c8441 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
@@ -128,7 +128,7 @@ generic_acl_init(struct inode *inode, struct inode *dir) | |||
128 | if (acl) { | 128 | if (acl) { |
129 | if (S_ISDIR(inode->i_mode)) | 129 | if (S_ISDIR(inode->i_mode)) |
130 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); | 130 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); |
131 | error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); | 131 | error = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); |
132 | if (error < 0) | 132 | if (error < 0) |
133 | return error; | 133 | return error; |
134 | if (error > 0) | 134 | if (error > 0) |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 3e200c7ca7ad..e82e4ac574a6 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -131,7 +131,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) | |||
131 | goto out; | 131 | goto out; |
132 | } | 132 | } |
133 | 133 | ||
134 | error = posix_acl_create(&acl, GFP_NOFS, &mode); | 134 | error = __posix_acl_create(&acl, GFP_NOFS, &mode); |
135 | if (error < 0) | 135 | if (error < 0) |
136 | return error; | 136 | return error; |
137 | 137 | ||
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c index cab5fd6fdb72..277942f36f80 100644 --- a/fs/hfsplus/posix_acl.c +++ b/fs/hfsplus/posix_acl.c | |||
@@ -137,7 +137,7 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir) | |||
137 | goto init_acl_cleanup; | 137 | goto init_acl_cleanup; |
138 | } | 138 | } |
139 | 139 | ||
140 | err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | 140 | err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); |
141 | if (unlikely(err < 0)) | 141 | if (unlikely(err < 0)) |
142 | return err; | 142 | return err; |
143 | 143 | ||
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 5853969a51bc..4d6e31b19816 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -295,7 +295,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode | |||
295 | if (S_ISDIR(*i_mode)) | 295 | if (S_ISDIR(*i_mode)) |
296 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); | 296 | set_cached_acl(inode, ACL_TYPE_DEFAULT, acl); |
297 | 297 | ||
298 | rc = posix_acl_create(&acl, GFP_KERNEL, i_mode); | 298 | rc = __posix_acl_create(&acl, GFP_KERNEL, i_mode); |
299 | if (rc < 0) | 299 | if (rc < 0) |
300 | return rc; | 300 | return rc; |
301 | if (rc > 0) | 301 | if (rc > 0) |
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 9c0fca8073da..28d529ae9a4a 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -132,7 +132,7 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) | |||
132 | if (rc) | 132 | if (rc) |
133 | goto cleanup; | 133 | goto cleanup; |
134 | } | 134 | } |
135 | rc = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); | 135 | rc = __posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); |
136 | if (rc < 0) | 136 | if (rc < 0) |
137 | goto cleanup; /* posix_acl_release(NULL) is no-op */ | 137 | goto cleanup; /* posix_acl_release(NULL) is no-op */ |
138 | if (rc > 0) | 138 | if (rc > 0) |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 4a1aafba6a20..e85967587d74 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -428,7 +428,7 @@ int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode, | |||
428 | if (!dfacl) | 428 | if (!dfacl) |
429 | return 0; | 429 | return 0; |
430 | acl = posix_acl_dup(dfacl); | 430 | acl = posix_acl_dup(dfacl); |
431 | error = posix_acl_create(&acl, GFP_KERNEL, &mode); | 431 | error = __posix_acl_create(&acl, GFP_KERNEL, &mode); |
432 | if (error < 0) | 432 | if (error < 0) |
433 | goto out_release_dfacl; | 433 | goto out_release_dfacl; |
434 | error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? | 434 | error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ? |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 73ccf0e22ec5..c0f9d2fe134f 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -401,7 +401,7 @@ int ocfs2_init_acl(handle_t *handle, | |||
401 | goto cleanup; | 401 | goto cleanup; |
402 | } | 402 | } |
403 | mode = inode->i_mode; | 403 | mode = inode->i_mode; |
404 | ret = posix_acl_create(&acl, GFP_NOFS, &mode); | 404 | ret = __posix_acl_create(&acl, GFP_NOFS, &mode); |
405 | if (ret < 0) | 405 | if (ret < 0) |
406 | return ret; | 406 | return ret; |
407 | 407 | ||
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 08218550b0db..8f245ab20143 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -410,7 +410,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) | |||
410 | } | 410 | } |
411 | 411 | ||
412 | int | 412 | int |
413 | posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p) | 413 | __posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p) |
414 | { | 414 | { |
415 | struct posix_acl *clone = posix_acl_clone(*acl, gfp); | 415 | struct posix_acl *clone = posix_acl_clone(*acl, gfp); |
416 | int err = -ENOMEM; | 416 | int err = -ENOMEM; |
@@ -425,7 +425,7 @@ posix_acl_create(struct posix_acl **acl, gfp_t gfp, umode_t *mode_p) | |||
425 | *acl = clone; | 425 | *acl = clone; |
426 | return err; | 426 | return err; |
427 | } | 427 | } |
428 | EXPORT_SYMBOL(posix_acl_create); | 428 | EXPORT_SYMBOL(__posix_acl_create); |
429 | 429 | ||
430 | int | 430 | int |
431 | __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) | 431 | __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) |
@@ -446,7 +446,7 @@ __posix_acl_chmod(struct posix_acl **acl, gfp_t gfp, umode_t mode) | |||
446 | EXPORT_SYMBOL(__posix_acl_chmod); | 446 | EXPORT_SYMBOL(__posix_acl_chmod); |
447 | 447 | ||
448 | int | 448 | int |
449 | posix_acl_chmod(struct inode *inode) | 449 | posix_acl_chmod(struct inode *inode, umode_t mode) |
450 | { | 450 | { |
451 | struct posix_acl *acl; | 451 | struct posix_acl *acl; |
452 | int ret = 0; | 452 | int ret = 0; |
@@ -460,7 +460,7 @@ posix_acl_chmod(struct inode *inode) | |||
460 | if (IS_ERR_OR_NULL(acl)) | 460 | if (IS_ERR_OR_NULL(acl)) |
461 | return PTR_ERR(acl); | 461 | return PTR_ERR(acl); |
462 | 462 | ||
463 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); | 463 | ret = __posix_acl_chmod(&acl, GFP_KERNEL, mode); |
464 | if (ret) | 464 | if (ret) |
465 | return ret; | 465 | return ret; |
466 | ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS); | 466 | ret = inode->i_op->set_acl(inode, acl, ACL_TYPE_ACCESS); |
@@ -469,6 +469,55 @@ posix_acl_chmod(struct inode *inode) | |||
469 | } | 469 | } |
470 | EXPORT_SYMBOL(posix_acl_chmod); | 470 | EXPORT_SYMBOL(posix_acl_chmod); |
471 | 471 | ||
472 | int | ||
473 | posix_acl_create(struct inode *dir, umode_t *mode, | ||
474 | struct posix_acl **default_acl, struct posix_acl **acl) | ||
475 | { | ||
476 | struct posix_acl *p; | ||
477 | int ret; | ||
478 | |||
479 | if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) | ||
480 | goto no_acl; | ||
481 | |||
482 | p = get_acl(dir, ACL_TYPE_DEFAULT); | ||
483 | if (IS_ERR(p)) | ||
484 | return PTR_ERR(p); | ||
485 | |||
486 | if (!p) { | ||
487 | *mode &= ~current_umask(); | ||
488 | goto no_acl; | ||
489 | } | ||
490 | |||
491 | *acl = posix_acl_clone(p, GFP_NOFS); | ||
492 | if (!*acl) | ||
493 | return -ENOMEM; | ||
494 | |||
495 | ret = posix_acl_create_masq(*acl, mode); | ||
496 | if (ret < 0) { | ||
497 | posix_acl_release(*acl); | ||
498 | return -ENOMEM; | ||
499 | } | ||
500 | |||
501 | if (ret == 0) { | ||
502 | posix_acl_release(*acl); | ||
503 | *acl = NULL; | ||
504 | } | ||
505 | |||
506 | if (!S_ISDIR(*mode)) { | ||
507 | posix_acl_release(p); | ||
508 | *default_acl = NULL; | ||
509 | } else { | ||
510 | *default_acl = p; | ||
511 | } | ||
512 | return 0; | ||
513 | |||
514 | no_acl: | ||
515 | *default_acl = NULL; | ||
516 | *acl = NULL; | ||
517 | return 0; | ||
518 | } | ||
519 | EXPORT_SYMBOL_GPL(posix_acl_create); | ||
520 | |||
472 | /* | 521 | /* |
473 | * Fix up the uids and gids in posix acl extended attributes in place. | 522 | * Fix up the uids and gids in posix acl extended attributes in place. |
474 | */ | 523 | */ |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index ea4e44351f76..d95c9592327b 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -378,7 +378,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, | |||
378 | 378 | ||
379 | /* Now we reconcile the new ACL and the mode, | 379 | /* Now we reconcile the new ACL and the mode, |
380 | potentially modifying both */ | 380 | potentially modifying both */ |
381 | err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); | 381 | err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); |
382 | if (err < 0) | 382 | if (err < 0) |
383 | return err; | 383 | return err; |
384 | 384 | ||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4eac1058b680..057ae2d502dc 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -297,12 +297,12 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *acl) | |||
297 | goto out; | 297 | goto out; |
298 | } | 298 | } |
299 | 299 | ||
300 | error = posix_acl_create(&acl, GFP_KERNEL, &mode); | 300 | error = __posix_acl_create(&acl, GFP_KERNEL, &mode); |
301 | if (error < 0) | 301 | if (error < 0) |
302 | return error; | 302 | return error; |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * If posix_acl_create returns a positive value we need to | 305 | * If __posix_acl_create returns a positive value we need to |
306 | * inherit a permission that can't be represented using the Unix | 306 | * inherit a permission that can't be represented using the Unix |
307 | * mode bits and we actually need to set an ACL. | 307 | * mode bits and we actually need to set an ACL. |
308 | */ | 308 | */ |
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 8b64e7899989..f7e6f6cb214a 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h | |||
@@ -88,14 +88,16 @@ extern int posix_acl_valid(const struct posix_acl *); | |||
88 | extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); | 88 | extern int posix_acl_permission(struct inode *, const struct posix_acl *, int); |
89 | extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); | 89 | extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t); |
90 | extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); | 90 | extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *); |
91 | extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *); | 91 | extern int __posix_acl_create(struct posix_acl **, gfp_t, umode_t *); |
92 | extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); | 92 | extern int __posix_acl_chmod(struct posix_acl **, gfp_t, umode_t); |
93 | 93 | ||
94 | extern struct posix_acl *get_posix_acl(struct inode *, int); | 94 | extern struct posix_acl *get_posix_acl(struct inode *, int); |
95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); | 95 | extern int set_posix_acl(struct inode *, int, struct posix_acl *); |
96 | 96 | ||
97 | #ifdef CONFIG_FS_POSIX_ACL | 97 | #ifdef CONFIG_FS_POSIX_ACL |
98 | extern int posix_acl_chmod(struct inode *); | 98 | extern int posix_acl_chmod(struct inode *, umode_t); |
99 | extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, | ||
100 | struct posix_acl **); | ||
99 | 101 | ||
100 | static inline struct posix_acl **acl_by_type(struct inode *inode, int type) | 102 | static inline struct posix_acl **acl_by_type(struct inode *inode, int type) |
101 | { | 103 | { |
@@ -174,7 +176,7 @@ static inline void cache_no_acl(struct inode *inode) | |||
174 | inode->i_default_acl = NULL; | 176 | inode->i_default_acl = NULL; |
175 | } | 177 | } |
176 | #else | 178 | #else |
177 | static inline int posix_acl_chmod(struct inode *inode) | 179 | static inline int posix_acl_chmod(struct inode *inode, umode_t mode) |
178 | { | 180 | { |
179 | return 0; | 181 | return 0; |
180 | } | 182 | } |
@@ -182,6 +184,13 @@ static inline int posix_acl_chmod(struct inode *inode) | |||
182 | static inline void cache_no_acl(struct inode *inode) | 184 | static inline void cache_no_acl(struct inode *inode) |
183 | { | 185 | { |
184 | } | 186 | } |
187 | |||
188 | static inline int posix_acl_create(struct inode *inode, umode_t *mode, | ||
189 | struct posix_acl **default_acl, struct posix_acl **acl) | ||
190 | { | ||
191 | *default_acl = *acl = NULL; | ||
192 | return 0; | ||
193 | } | ||
185 | #endif /* CONFIG_FS_POSIX_ACL */ | 194 | #endif /* CONFIG_FS_POSIX_ACL */ |
186 | 195 | ||
187 | struct posix_acl *get_acl(struct inode *inode, int type); | 196 | struct posix_acl *get_acl(struct inode *inode, int type); |