nfsd41: split out share_access want and signal flags while decoding
authorBenny Halevy <benny@tonian.com>
Thu, 16 Feb 2012 18:57:09 +0000 (20:57 +0200)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 17 Feb 2012 23:38:42 +0000 (18:38 -0500)
Signed-off-by: Benny Halevy <bhalevy@tonian.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/xdr4.h

index 53636ff..cdb7ca3 100644 (file)
@@ -311,9 +311,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
                return nfserr_inval;
 
-       /* We don't yet support WANT bits: */
-       open->op_share_access &= NFS4_SHARE_ACCESS_MASK;
-
        open->op_created = 0;
        /*
         * RFC5661 18.51.3
index f89ccc2..45966a4 100644 (file)
@@ -2637,8 +2637,6 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
 
 static int share_access_to_flags(u32 share_access)
 {
-       share_access &= NFS4_SHARE_ACCESS_MASK;
-
        return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
 }
 
@@ -3600,7 +3598,9 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
                        cstate->current_fh.fh_dentry->d_name.name);
 
        /* We don't yet support WANT bits: */
-       od->od_share_access &= NFS4_SHARE_ACCESS_MASK;
+       if (od->od_deleg_want)
+               dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
+                       od->od_deleg_want);
 
        nfs4_lock_state();
        status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
index 279a705..d241a85 100644 (file)
@@ -638,14 +638,18 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
        DECODE_TAIL;
 }
 
-static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
+static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
        __be32 *p;
        u32 w;
 
        READ_BUF(4);
        READ32(w);
-       *x = w;
+       *share_access = w & NFS4_SHARE_ACCESS_MASK;
+       *deleg_want = w & NFS4_SHARE_WANT_MASK;
+       if (deleg_when)
+               *deleg_when = w & NFS4_SHARE_WHEN_MASK;
+
        switch (w & NFS4_SHARE_ACCESS_MASK) {
        case NFS4_SHARE_ACCESS_READ:
        case NFS4_SHARE_ACCESS_WRITE:
@@ -673,6 +677,9 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
        w &= ~NFS4_SHARE_WANT_MASK;
        if (!w)
                return nfs_ok;
+
+       if (!deleg_when)        /* open_downgrade */
+               return nfserr_inval;
        switch (w) {
        case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
        case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
@@ -719,6 +726,7 @@ static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
        DECODE_HEAD;
+       u32 dummy;
 
        memset(open->op_bmval, 0, sizeof(open->op_bmval));
        open->op_iattr.ia_valid = 0;
@@ -727,7 +735,9 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
        /* seqid, share_access, share_deny, clientid, ownerlen */
        READ_BUF(4);
        READ32(open->op_seqid);
-       status = nfsd4_decode_share_access(argp, &open->op_share_access);
+       /* decode, yet ignore deleg_when until supported */
+       status = nfsd4_decode_share_access(argp, &open->op_share_access,
+                                          &open->op_deleg_want, &dummy);
        if (status)
                goto xdr_error;
        status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
@@ -848,7 +858,8 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
                return status;
        READ_BUF(4);
        READ32(open_down->od_seqid);
-       status = nfsd4_decode_share_access(argp, &open_down->od_share_access);
+       status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
+                                          &open_down->od_deleg_want, NULL);
        if (status)
                return status;
        status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
index 12789eb..4949832 100644 (file)
@@ -233,6 +233,7 @@ struct nfsd4_open {
        u32             op_seqid;           /* request */
        u32             op_share_access;    /* request */
        u32             op_share_deny;      /* request */
+       u32             op_deleg_want;      /* request */
        stateid_t       op_stateid;         /* response */
        u32             op_recall;          /* recall */
        struct nfsd4_change_info  op_cinfo; /* response */
@@ -256,8 +257,9 @@ struct nfsd4_open_confirm {
 struct nfsd4_open_downgrade {
        stateid_t       od_stateid;
        u32             od_seqid;
-       u32             od_share_access;
-       u32             od_share_deny;
+       u32             od_share_access;        /* request */
+       u32             od_deleg_want;          /* request */
+       u32             od_share_deny;          /* request */
 };