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 /fs/posix_acl.c | |
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>
Diffstat (limited to 'fs/posix_acl.c')
-rw-r--r-- | fs/posix_acl.c | 57 |
1 files changed, 53 insertions, 4 deletions
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 | */ |