renew_client_locked(clp);
 }
 
+static void put_client_renew(struct nfs4_client *clp)
+{
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
+       spin_lock(&nn->client_lock);
+       put_client_renew_locked(clp);
+       spin_unlock(&nn->client_lock);
+}
+
 static __be32 nfsd4_get_session_locked(struct nfsd4_session *ses)
 {
        __be32 status;
                        goto out_put_session;
                cstate->slot = slot;
                cstate->session = session;
+               cstate->clp = clp;
                /* Return the cached reply status and set cstate->status
                 * for nfsd4_proc_compound processing */
                status = nfsd4_replay_cache_entry(resp, seq);
 
        cstate->slot = slot;
        cstate->session = session;
+       cstate->clp = clp;
 
 out:
        switch (clp->cl_cb_state) {
                }
                /* Drop session reference that was taken in nfsd4_sequence() */
                nfsd4_put_session(cs->session);
-       }
+       } else if (cs->clp)
+               put_client_renew(cs->clp);
 }
 
 __be32
        return nfserr_bad_seqid;
 }
 
+static __be32 lookup_clientid(clientid_t *clid,
+               struct nfsd4_compound_state *cstate,
+               struct nfsd_net *nn)
+{
+       struct nfs4_client *found;
+
+       if (cstate->clp) {
+               found = cstate->clp;
+               if (!same_clid(&found->cl_clientid, clid))
+                       return nfserr_stale_clientid;
+               return nfs_ok;
+       }
+
+       if (STALE_CLIENTID(clid, nn))
+               return nfserr_stale_clientid;
+
+       /*
+        * For v4.1+ we get the client in the SEQUENCE op. If we don't have one
+        * cached already then we know this is for is for v4.0 and "sessions"
+        * will be false.
+        */
+       WARN_ON_ONCE(cstate->session);
+       found = find_confirmed_client(clid, false, nn);
+       if (!found)
+               return nfserr_expired;
+
+       /* Cache the nfs4_client in cstate! */
+       cstate->clp = found;
+       atomic_inc(&found->cl_refcount);
+       return nfs_ok;
+}
+
 __be32
 nfsd4_process_open1(struct nfsd4_compound_state *cstate,
                    struct nfsd4_open *open, struct nfsd_net *nn)
                free_generic_stateid(open->op_stp);
 }
 
-static __be32 lookup_clientid(clientid_t *clid, bool session, struct nfsd_net *nn, struct nfs4_client **clp)
-{
-       struct nfs4_client *found;
-
-       if (STALE_CLIENTID(clid, nn))
-               return nfserr_stale_clientid;
-       found = find_confirmed_client(clid, session, nn);
-       if (clp)
-               *clp = found;
-       return found ? nfs_ok : nfserr_expired;
-}
-
 __be32
 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
            clientid_t *clid)
        nfs4_lock_state();
        dprintk("process_renew(%08x/%08x): starting\n", 
                        clid->cl_boot, clid->cl_id);
-       status = lookup_clientid(clid, cstate->minorversion, nn, &clp);
+       status = lookup_clientid(clid, cstate, nn);
        if (status)
                goto out;
+       clp = cstate->clp;
        status = nfserr_cb_path_down;
        if (!list_empty(&clp->cl_delegations)
                        && clp->cl_cb_state != NFSD4_CB_UP)
                     stateid_t *stateid, unsigned char typemask,
                     struct nfs4_stid **s, struct nfsd_net *nn)
 {
-       struct nfs4_client *cl;
        __be32 status;
-       bool sessions = cstate->minorversion != 0;
 
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
                return nfserr_bad_stateid;
-       status = lookup_clientid(&stateid->si_opaque.so_clid, sessions,
-                                                       nn, &cl);
+       status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn);
        if (status == nfserr_stale_clientid) {
-               if (sessions)
+               if (cstate->session)
                        return nfserr_bad_stateid;
                return nfserr_stale_stateid;
        }
        if (status)
                return status;
-       *s = find_stateid_by_type(cl, stateid, typemask);
+       *s = find_stateid_by_type(cstate->clp, stateid, typemask);
        if (!*s)
                return nfserr_bad_stateid;
        return nfs_ok;
        nfs4_lock_state();
 
        if (!nfsd4_has_session(cstate)) {
-               status = lookup_clientid(&lockt->lt_clientid, false, nn, NULL);
+               status = lookup_clientid(&lockt->lt_clientid, cstate, nn);
                if (status)
                        goto out;
        }
 
        nfs4_lock_state();
 
-       status = lookup_clientid(clid, cstate->minorversion, nn, NULL);
+       status = lookup_clientid(clid, cstate, nn);
        if (status)
                goto out;