aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4acl.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 0a69cce33efe..832673b14587 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -416,6 +416,7 @@ struct posix_ace_state_array {
416 * calculated so far: */ 416 * calculated so far: */
417 417
418struct posix_acl_state { 418struct posix_acl_state {
419 int empty;
419 struct posix_ace_state owner; 420 struct posix_ace_state owner;
420 struct posix_ace_state group; 421 struct posix_ace_state group;
421 struct posix_ace_state other; 422 struct posix_ace_state other;
@@ -431,6 +432,7 @@ init_state(struct posix_acl_state *state, int cnt)
431 int alloc; 432 int alloc;
432 433
433 memset(state, 0, sizeof(struct posix_acl_state)); 434 memset(state, 0, sizeof(struct posix_acl_state));
435 state->empty = 1;
434 /* 436 /*
435 * In the worst case, each individual acl could be for a distinct 437 * In the worst case, each individual acl could be for a distinct
436 * named user or group, but we don't no which, so we allocate 438 * named user or group, but we don't no which, so we allocate
@@ -498,6 +500,20 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
498 int nace; 500 int nace;
499 int i, error = 0; 501 int i, error = 0;
500 502
503 /*
504 * ACLs with no ACEs are treated differently in the inheritable
505 * and effective cases: when there are no inheritable ACEs, we
506 * set a zero-length default posix acl:
507 */
508 if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) {
509 pacl = posix_acl_alloc(0, GFP_KERNEL);
510 return pacl ? pacl : ERR_PTR(-ENOMEM);
511 }
512 /*
513 * When there are no effective ACEs, the following will end
514 * up setting a 3-element effective posix ACL with all
515 * permissions zero.
516 */
501 nace = 4 + state->users->n + state->groups->n; 517 nace = 4 + state->users->n + state->groups->n;
502 pacl = posix_acl_alloc(nace, GFP_KERNEL); 518 pacl = posix_acl_alloc(nace, GFP_KERNEL);
503 if (!pacl) 519 if (!pacl)
@@ -613,6 +629,8 @@ static void process_one_v4_ace(struct posix_acl_state *state,
613 u32 mask = ace->access_mask; 629 u32 mask = ace->access_mask;
614 int i; 630 int i;
615 631
632 state->empty = 0;
633
616 switch (ace2type(ace)) { 634 switch (ace2type(ace)) {
617 case ACL_USER_OBJ: 635 case ACL_USER_OBJ:
618 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 636 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
@@ -717,7 +735,8 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
717 ret = PTR_ERR(*pacl); 735 ret = PTR_ERR(*pacl);
718 goto out_dstate; 736 goto out_dstate;
719 } 737 }
720 *dpacl = posix_state_to_acl(&default_acl_state, flags); 738 *dpacl = posix_state_to_acl(&default_acl_state,
739 flags | NFS4_ACL_TYPE_DEFAULT);
721 if (IS_ERR(*dpacl)) { 740 if (IS_ERR(*dpacl)) {
722 ret = PTR_ERR(*dpacl); 741 ret = PTR_ERR(*dpacl);
723 posix_acl_release(*pacl); 742 posix_acl_release(*pacl);