NLM: Remove "proto" argument from lockd_up()
[safe/jmp/linux-2.6] / fs / nfsd / nfs4acl.c
index 0a69cce..54b8b41 100644 (file)
@@ -137,7 +137,6 @@ struct ace_container {
 static short ace2type(struct nfs4_ace *);
 static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *,
                                unsigned int);
-void nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t);
 
 struct nfs4_acl *
 nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl,
@@ -184,8 +183,13 @@ static void
 summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas)
 {
        struct posix_acl_entry *pa, *pe;
-       pas->users = 0;
-       pas->groups = 0;
+
+       /*
+        * Only pas.users and pas.groups need initialization; previous
+        * posix_acl_valid() calls ensure that the other fields will be
+        * initialized in the following loop.  But, just to placate gcc:
+        */
+       memset(pas, 0, sizeof(*pas));
        pas->mask = 07;
 
        pe = acl->a_entries + acl->a_count;
@@ -228,7 +232,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
        struct posix_acl_summary pas;
        unsigned short deny;
        int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
-                                       NFS4_INHERITANCE_FLAGS : 0);
+               NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0);
 
        BUG_ON(pacl->a_count < 3);
        summarize_posix_acl(pacl, &pas);
@@ -416,6 +420,7 @@ struct posix_ace_state_array {
  * calculated so far: */
 
 struct posix_acl_state {
+       int empty;
        struct posix_ace_state owner;
        struct posix_ace_state group;
        struct posix_ace_state other;
@@ -431,13 +436,14 @@ init_state(struct posix_acl_state *state, int cnt)
        int alloc;
 
        memset(state, 0, sizeof(struct posix_acl_state));
+       state->empty = 1;
        /*
         * In the worst case, each individual acl could be for a distinct
         * named user or group, but we don't no which, so we allocate
         * enough space for either:
         */
        alloc = sizeof(struct posix_ace_state_array)
-               + cnt*sizeof(struct posix_ace_state);
+               + cnt*sizeof(struct posix_user_ace_state);
        state->users = kzalloc(alloc, GFP_KERNEL);
        if (!state->users)
                return -ENOMEM;
@@ -498,6 +504,20 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
        int nace;
        int i, error = 0;
 
+       /*
+        * ACLs with no ACEs are treated differently in the inheritable
+        * and effective cases: when there are no inheritable ACEs, we
+        * set a zero-length default posix acl:
+        */
+       if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) {
+               pacl = posix_acl_alloc(0, GFP_KERNEL);
+               return pacl ? pacl : ERR_PTR(-ENOMEM);
+       }
+       /*
+        * When there are no effective ACEs, the following will end
+        * up setting a 3-element effective posix ACL with all
+        * permissions zero.
+        */
        nace = 4 + state->users->n + state->groups->n;
        pacl = posix_acl_alloc(nace, GFP_KERNEL);
        if (!pacl)
@@ -613,6 +633,8 @@ static void process_one_v4_ace(struct posix_acl_state *state,
        u32 mask = ace->access_mask;
        int i;
 
+       state->empty = 0;
+
        switch (ace2type(ace)) {
        case ACL_USER_OBJ:
                if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
@@ -715,12 +737,16 @@ int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
        *pacl = posix_state_to_acl(&effective_acl_state, flags);
        if (IS_ERR(*pacl)) {
                ret = PTR_ERR(*pacl);
+               *pacl = NULL;
                goto out_dstate;
        }
-       *dpacl = posix_state_to_acl(&default_acl_state, flags);
+       *dpacl = posix_state_to_acl(&default_acl_state,
+                                               flags | NFS4_ACL_TYPE_DEFAULT);
        if (IS_ERR(*dpacl)) {
                ret = PTR_ERR(*dpacl);
+               *dpacl = NULL;
                posix_acl_release(*pacl);
+               *pacl = NULL;
                goto out_dstate;
        }
        sort_pacl(*pacl);
@@ -766,21 +792,6 @@ nfs4_acl_new(int n)
        return acl;
 }
 
-void
-nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask,
-               int whotype, uid_t who)
-{
-       struct nfs4_ace *ace = acl->aces + acl->naces;
-
-       ace->type = type;
-       ace->flag = flag;
-       ace->access_mask = access_mask;
-       ace->whotype = whotype;
-       ace->who = who;
-
-       acl->naces++;
-}
-
 static struct {
        char *string;
        int   stringlen;
@@ -832,6 +843,5 @@ nfs4_acl_write_who(int who, char *p)
 }
 
 EXPORT_SYMBOL(nfs4_acl_new);
-EXPORT_SYMBOL(nfs4_acl_add_ace);
 EXPORT_SYMBOL(nfs4_acl_get_whotype);
 EXPORT_SYMBOL(nfs4_acl_write_who);