NFSd: Clean up nfs4_preprocess_stateid_op
authorTrond Myklebust <trond.myklebust@primarydata.com>
Fri, 18 Apr 2014 18:44:07 +0000 (14:44 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 7 May 2014 15:05:48 +0000 (11:05 -0400)
Move the state locking and file descriptor reference out from the
callers and into nfs4_preprocess_stateid_op() itself.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c

index d543222babf36beb28aba95afd746ddd9298d8ce..ac837783b37dacb64c56769a4b88c0ecf35adcf3 100644 (file)
@@ -786,7 +786,6 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (!nfsd4_last_compound_op(rqstp))
                rqstp->rq_splice_ok = false;
 
-       nfs4_lock_state();
        /* check stateid */
        if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
                                                 cstate, &read->rd_stateid,
@@ -794,11 +793,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
                goto out;
        }
-       if (read->rd_filp)
-               get_file(read->rd_filp);
        status = nfs_ok;
 out:
-       nfs4_unlock_state();
        read->rd_rqstp = rqstp;
        read->rd_fhp = &cstate->current_fh;
        return status;
@@ -937,10 +933,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        int err;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
-               nfs4_lock_state();
                status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
                        &setattr->sa_stateid, WR_STATE, NULL);
-               nfs4_unlock_state();
                if (status) {
                        dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
                        return status;
@@ -1006,17 +1000,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (write->wr_offset >= OFFSET_MAX)
                return nfserr_inval;
 
-       nfs4_lock_state();
        status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
                                        cstate, stateid, WR_STATE, &filp);
        if (status) {
-               nfs4_unlock_state();
                dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
                return status;
        }
-       if (filp)
-               get_file(filp);
-       nfs4_unlock_state();
 
        cnt = write->wr_buflen;
        write->wr_how_written = write->wr_stable_how;
index fcab9091f094ea58fac2fd3f86848c4d6a2f8608..b5278941f3a1069e4e6985f09b13a08a78772325 100644 (file)
@@ -3654,6 +3654,7 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
        struct svc_fh *current_fh = &cstate->current_fh;
        struct inode *ino = current_fh->fh_dentry->d_inode;
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+       struct file *file = NULL;
        __be32 status;
 
        if (filpp)
@@ -3665,10 +3666,12 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
                return check_special_stateids(net, current_fh, stateid, flags);
 
+       nfs4_lock_state();
+
        status = nfsd4_lookup_stateid(stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
                                      &s, cstate->minorversion, nn);
        if (status)
-               return status;
+               goto out;
        status = check_stateid_generation(stateid, &s->sc_stateid, nfsd4_has_session(cstate));
        if (status)
                goto out;
@@ -3679,8 +3682,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
                if (status)
                        goto out;
                if (filpp) {
-                       *filpp = dp->dl_file->fi_deleg_file;
-                       if (!*filpp) {
+                       file = dp->dl_file->fi_deleg_file;
+                       if (!file) {
                                WARN_ON_ONCE(1);
                                status = nfserr_serverfault;
                                goto out;
@@ -3701,16 +3704,20 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
                        goto out;
                if (filpp) {
                        if (flags & RD_STATE)
-                               *filpp = find_readable_file(stp->st_file);
+                               file = find_readable_file(stp->st_file);
                        else
-                               *filpp = find_writeable_file(stp->st_file);
+                               file = find_writeable_file(stp->st_file);
                }
                break;
        default:
-               return nfserr_bad_stateid;
+               status = nfserr_bad_stateid;
+               goto out;
        }
        status = nfs_ok;
+       if (file)
+               *filpp = get_file(file);
 out:
+       nfs4_unlock_state();
        return status;
 }