nfsd4: call nfsd4_release_compoundargs from pc_release
[deliverable/linux.git] / fs / nfsd / nfs4proc.c
index 3a6dbd70b34b57146cacfb8e22d0601481ec5349..7ef1b27f1125b263830df30291be1b0c73979a41 100644 (file)
@@ -291,6 +291,15 @@ 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;
 
+       /*
+        * RFC5661 18.51.3
+        * Before RECLAIM_COMPLETE done, server should deny new lock
+        */
+       if (nfsd4_has_session(cstate) &&
+           !cstate->session->se_client->cl_firststate &&
+           open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
+               return nfserr_grace;
+
        if (nfsd4_has_session(cstate))
                copy_clientid(&open->op_clientid, cstate->session);
 
@@ -1209,7 +1218,6 @@ encode_op:
        fh_put(&resp->cstate.save_fh);
        BUG_ON(resp->cstate.replay_owner);
 out:
-       nfsd4_release_compoundargs(args);
        /* Reset deferral mechanism for RPC deferrals */
        rqstp->rq_usedeferral = 1;
        dprintk("nfsv4 compound returned %d\n", ntohl(status));
@@ -1402,6 +1410,11 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
                .op_name = "OP_SEQUENCE",
        },
+       [OP_DESTROY_CLIENTID] = {
+               .op_func = NULL,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+               .op_name = "OP_DESTROY_CLIENTID",
+       },
        [OP_RECLAIM_COMPLETE] = {
                .op_func = (nfsd4op_func)nfsd4_reclaim_complete,
                .op_flags = ALLOWED_WITHOUT_FH,
@@ -1412,6 +1425,16 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_flags = OP_HANDLES_WRONGSEC,
                .op_name = "OP_SECINFO_NO_NAME",
        },
+       [OP_TEST_STATEID] = {
+               .op_func = (nfsd4op_func)nfsd4_test_stateid,
+               .op_flags = ALLOWED_WITHOUT_FH,
+               .op_name = "OP_TEST_STATEID",
+       },
+       [OP_FREE_STATEID] = {
+               .op_func = (nfsd4op_func)nfsd4_free_stateid,
+               .op_flags = ALLOWED_WITHOUT_FH,
+               .op_name = "OP_FREE_STATEID",
+       },
 };
 
 static const char *nfsd4_op_name(unsigned opnum)
@@ -1449,6 +1472,7 @@ static struct svc_procedure               nfsd_procedures4[2] = {
                .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres,
                .pc_argsize = sizeof(struct nfsd4_compoundargs),
                .pc_ressize = sizeof(struct nfsd4_compoundres),
+               .pc_release = nfsd4_release_compoundargs,
                .pc_cachetype = RC_NOCACHE,
                .pc_xdrressize = NFSD_BUFSIZE/4,
        },
This page took 0.023928 seconds and 5 git commands to generate.