+ if (bmval[0] & FATTR4_WORD0_ACL) {
+ int nace, i;
+ struct nfs4_ace ace;
+
+ READ_BUF(4); len += 4;
+ READ32(nace);
+
+ *acl = nfs4_acl_new();
+ if (*acl == NULL) {
+ status = -ENOMEM;
+ goto out_nfserr;
+ }
+ defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl);
+
+ for (i = 0; i < nace; i++) {
+ READ_BUF(16); len += 16;
+ READ32(ace.type);
+ READ32(ace.flag);
+ READ32(ace.access_mask);
+ READ32(dummy32);
+ READ_BUF(dummy32);
+ len += XDR_QUADLEN(dummy32) << 2;
+ READMEM(buf, dummy32);
+ if (check_utf8(buf, dummy32))
+ return nfserr_inval;
+ ace.whotype = nfs4_acl_get_whotype(buf, dummy32);
+ status = 0;
+ if (ace.whotype != NFS4_ACL_WHO_NAMED)
+ ace.who = 0;
+ else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP)
+ status = nfsd_map_name_to_gid(argp->rqstp,
+ buf, dummy32, &ace.who);
+ else
+ status = nfsd_map_name_to_uid(argp->rqstp,
+ buf, dummy32, &ace.who);
+ if (status)
+ goto out_nfserr;
+ if (nfs4_acl_add_ace(*acl, ace.type, ace.flag,
+ ace.access_mask, ace.whotype, ace.who) != 0) {
+ status = -ENOMEM;
+ goto out_nfserr;
+ }
+ }
+ } else
+ *acl = NULL;