aboutsummaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c65
1 files changed, 33 insertions, 32 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 18aa9440df1..5d090f11f2b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -199,24 +199,22 @@ defer_free(struct nfsd4_compoundargs *argp,
static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
{
- void *new = NULL;
if (p == argp->tmp) {
- new = kmalloc(nbytes, GFP_KERNEL);
- if (!new) return NULL;
- p = new;
+ p = kmalloc(nbytes, GFP_KERNEL);
+ if (!p)
+ return NULL;
memcpy(p, argp->tmp, nbytes);
} else {
BUG_ON(p != argp->tmpp);
argp->tmpp = NULL;
}
if (defer_free(argp, kfree, p)) {
- kfree(new);
+ kfree(p);
return NULL;
} else
return (char *)p;
}
-
static __be32
nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
{
@@ -255,7 +253,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
return status;
/*
- * According to spec, unsupported attributes return ERR_NOTSUPP;
+ * According to spec, unsupported attributes return ERR_ATTRNOTSUPP;
* read-only attributes return ERR_INVAL.
*/
if ((bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) || (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1))
@@ -273,42 +271,42 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
iattr->ia_valid |= ATTR_SIZE;
}
if (bmval[0] & FATTR4_WORD0_ACL) {
- int nace, i;
- struct nfs4_ace ace;
+ int nace;
+ struct nfs4_ace *ace;
READ_BUF(4); len += 4;
READ32(nace);
- *acl = nfs4_acl_new();
+ if (nace > NFS4_ACL_MAX)
+ return nfserr_resource;
+
+ *acl = nfs4_acl_new(nace);
if (*acl == NULL) {
host_err = -ENOMEM;
goto out_nfserr;
}
- defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl);
+ defer_free(argp, kfree, *acl);
- for (i = 0; i < nace; i++) {
+ (*acl)->naces = nace;
+ for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
READ_BUF(16); len += 16;
- READ32(ace.type);
- READ32(ace.flag);
- READ32(ace.access_mask);
+ READ32(ace->type);
+ READ32(ace->flag);
+ READ32(ace->access_mask);
READ32(dummy32);
READ_BUF(dummy32);
len += XDR_QUADLEN(dummy32) << 2;
READMEM(buf, dummy32);
- ace.whotype = nfs4_acl_get_whotype(buf, dummy32);
+ ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
host_err = 0;
- if (ace.whotype != NFS4_ACL_WHO_NAMED)
- ace.who = 0;
- else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP)
+ if (ace->whotype != NFS4_ACL_WHO_NAMED)
+ ace->who = 0;
+ else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
host_err = nfsd_map_name_to_gid(argp->rqstp,
- buf, dummy32, &ace.who);
+ buf, dummy32, &ace->who);
else
host_err = nfsd_map_name_to_uid(argp->rqstp,
- buf, dummy32, &ace.who);
- if (host_err)
- goto out_nfserr;
- host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag,
- ace.access_mask, ace.whotype, ace.who);
+ buf, dummy32, &ace->who);
if (host_err)
goto out_nfserr;
}
@@ -1563,14 +1561,20 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
if (exp->ex_fslocs.migrated) {
WRITE64(NFS4_REFERRAL_FSID_MAJOR);
WRITE64(NFS4_REFERRAL_FSID_MINOR);
- } else if (is_fsid(fhp, rqstp->rq_reffh)) {
+ } else switch(fsid_source(fhp)) {
+ case FSIDSOURCE_FSID:
WRITE64((u64)exp->ex_fsid);
WRITE64((u64)0);
- } else {
+ break;
+ case FSIDSOURCE_DEV:
WRITE32(0);
WRITE32(MAJOR(stat.dev));
WRITE32(0);
WRITE32(MINOR(stat.dev));
+ break;
+ case FSIDSOURCE_UUID:
+ WRITEMEM(exp->ex_uuid, 16);
+ break;
}
}
if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
@@ -1590,7 +1594,6 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
}
if (bmval0 & FATTR4_WORD0_ACL) {
struct nfs4_ace *ace;
- struct list_head *h;
if (acl == NULL) {
if ((buflen -= 4) < 0)
@@ -1603,9 +1606,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
goto out_resource;
WRITE32(acl->naces);
- list_for_each(h, &acl->ace_head) {
- ace = list_entry(h, struct nfs4_ace, l_ace);
-
+ for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
if ((buflen -= 4*3) < 0)
goto out_resource;
WRITE32(ace->type);
@@ -1815,7 +1816,7 @@ out_acl:
status = nfs_ok;
out:
- nfs4_acl_free(acl);
+ kfree(acl);
if (fhp == &tempfh)
fh_put(&tempfh);
return status;