]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/nfsd/nfs4xdr.c
nfsd4: drop most stateowner refcounting
[karo-tx-linux.git] / fs / nfsd / nfs4xdr.c
index 78c792fb59a877823db68f67cc9f20467adafe12..c4dcba3aac1f3070f35278b77e98990fd635326e 100644 (file)
@@ -456,7 +456,6 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
        DECODE_HEAD;
 
-       close->cl_stateowner = NULL;
        READ_BUF(4);
        READ32(close->cl_seqid);
        return nfsd4_decode_stateid(argp, &close->cl_stateid);
@@ -551,7 +550,6 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 {
        DECODE_HEAD;
 
-       lock->lk_replay_owner = NULL;
        /*
        * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
        */
@@ -611,7 +609,6 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 {
        DECODE_HEAD;
 
-       locku->lu_stateowner = NULL;
        READ_BUF(8);
        READ32(locku->lu_type);
        if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
@@ -739,7 +736,6 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
 {
        DECODE_HEAD;
                    
-       open_conf->oc_stateowner = NULL;
        status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
        if (status)
                return status;
@@ -754,7 +750,6 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
 {
        DECODE_HEAD;
                    
-       open_down->od_stateowner = NULL;
        status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
        if (status)
                return status;
@@ -1623,18 +1618,6 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
                                                                \
        save = resp->p;
 
-static bool seqid_mutating_err(__be32 err)
-{
-       /* rfc 3530 section 8.1.5: */
-       return  err != nfserr_stale_clientid &&
-               err != nfserr_stale_stateid &&
-               err != nfserr_bad_stateid &&
-               err != nfserr_bad_seqid &&
-               err != nfserr_bad_xdr &&
-               err != nfserr_resource &&
-               err != nfserr_nofilehandle;
-}
-
 /*
  * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
  * is where sequence id's are incremented, and the replay cache is filled.
@@ -1642,15 +1625,19 @@ static bool seqid_mutating_err(__be32 err)
  * we know whether the error to be returned is a sequence id mutating error.
  */
 
-#define ENCODE_SEQID_OP_TAIL(stateowner) do {                  \
-       if (seqid_mutating_err(nfserr) && stateowner) {         \
-               stateowner->so_seqid++;                         \
-               stateowner->so_replay.rp_status = nfserr;       \
-               stateowner->so_replay.rp_buflen =               \
-                         (((char *)(resp)->p - (char *)save)); \
-               memcpy(stateowner->so_replay.rp_buf, save,      \
-                       stateowner->so_replay.rp_buflen);       \
-       } } while (0);
+static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, __be32 nfserr)
+{
+       struct nfs4_stateowner *stateowner = resp->cstate.replay_owner;
+
+       if (seqid_mutating_err(ntohl(nfserr)) && stateowner) {
+               stateowner->so_seqid++;
+               stateowner->so_replay.rp_status = nfserr;
+               stateowner->so_replay.rp_buflen =
+                         (char *)resp->p - (char *)save;
+               memcpy(stateowner->so_replay.rp_buf, save,
+                       stateowner->so_replay.rp_buflen);
+       }
+}
 
 /* Encode as an array of strings the string given with components
  * separated @sep.
@@ -2507,7 +2494,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
        if (!nfserr)
                nfsd4_encode_stateid(resp, &close->cl_stateid);
 
-       ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2583,17 +2570,18 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
 static void
 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
 {
+       struct xdr_netobj *conf = &ld->ld_owner;
        __be32 *p;
 
-       RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));
+       RESERVE_SPACE(32 + XDR_LEN(conf->len));
        WRITE64(ld->ld_start);
        WRITE64(ld->ld_length);
        WRITE32(ld->ld_type);
-       if (ld->ld_sop) {
+       if (conf->len) {
                WRITEMEM(&ld->ld_clientid, 8);
-               WRITE32(ld->ld_sop->so_owner.len);
-               WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
-               kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);
+               WRITE32(conf->len);
+               WRITEMEM(conf->data, conf->len);
+               kfree(conf->data);
        }  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
                WRITE64((u64)0); /* clientid */
                WRITE32(0); /* length of owner name */
@@ -2611,7 +2599,7 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
        else if (nfserr == nfserr_denied)
                nfsd4_encode_lock_denied(resp, &lock->lk_denied);
 
-       ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2631,7 +2619,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
        if (!nfserr)
                nfsd4_encode_stateid(resp, &locku->lu_stateid);
 
-       ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2712,7 +2700,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
        }
        /* XXX save filehandle here */
 out:
-       ENCODE_SEQID_OP_TAIL(open->op_stateowner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2724,7 +2712,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
        if (!nfserr)
                nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
 
-       ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2736,7 +2724,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
        if (!nfserr)
                nfsd4_encode_stateid(resp, &od->od_stateid);
 
-       ENCODE_SEQID_OP_TAIL(od->od_stateowner);
+       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -3233,9 +3221,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
        WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
        WRITE32(seq->seqid);
        WRITE32(seq->slotid);
-       WRITE32(seq->maxslots);
-       /* For now: target_maxslots = maxslots */
-       WRITE32(seq->maxslots);
+       /* Note slotid's are numbered from zero: */
+       WRITE32(seq->maxslots - 1); /* sr_highest_slotid */
+       WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
        WRITE32(seq->status_flags);
 
        ADJUST_ARGS();