]> git.hungrycats.org Git - linux/commitdiff
[PATCH] kNFSd: NFSdV4 fixes for replaying open requests.
authorAndrew Morton <akpm@osdl.org>
Thu, 26 Feb 2004 14:46:54 +0000 (06:46 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 26 Feb 2004 14:46:54 +0000 (06:46 -0800)
From: NeilBrown <neilb@cse.unsw.edu.au>

Since the open op changes the current filehandle, we can't correctly replay
compounds containing opens unless we save the filehandle resulting from the
open as well as the encoded reply.

fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c
include/linux/nfsd/state.h

index c9398a6531e43d4ad4ee3def3d9a60bdebfeb3be..a7c429b750ced09448b9335b20826726648efaf4 100644 (file)
@@ -89,6 +89,12 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
        if (!status) {
                set_change_info(&open->op_cinfo, current_fh);
                fh_dup2(current_fh, &resfh);
+               /* XXXJBF: keep a saved svc_fh struct instead?? */
+               open->op_stateowner->so_replay.rp_openfh_len =
+                       resfh.fh_handle.fh_size;
+               memcpy(open->op_stateowner->so_replay.rp_openfh,
+                               &resfh.fh_handle.fh_base,
+                               resfh.fh_handle.fh_size);
 
                accmode = MAY_NOP;
                if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
@@ -116,6 +122,19 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
 
        /* check seqid for replay. set nfs4_owner */
        status = nfsd4_process_open1(open);
+       if (status == NFSERR_REPLAY_ME) {
+               struct nfs4_replay *rp = &open->op_stateowner->so_replay;
+               fh_put(current_fh);
+               current_fh->fh_handle.fh_size = rp->rp_openfh_len;
+               memcpy(&current_fh->fh_handle.fh_base, rp->rp_openfh,
+                               rp->rp_openfh_len);
+               status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+               if (status)
+                       dprintk("nfsd4_open: replay failed"
+                               " restoring previous filehandle\n");
+               else
+                       status = NFSERR_REPLAY_ME;
+       }
        if (status)
                return status;
        /*
index 919141d7cbcf30c44e395d655909888c7b61723c..5ff917c855601e73ec2b1048d4abe9a59bea7ab9 100644 (file)
@@ -1913,6 +1913,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open
        default:
                BUG();
        }
+       /* XXX save filehandle here */
 
        ENCODE_SEQID_OP_TAIL(open->op_stateowner);
 }
index b48b3620158547d77d5934f80db63db58865780d..4fdd1d2e8c25d1ebf78370eb8b2bc084993e4389 100644 (file)
@@ -113,6 +113,8 @@ struct nfs4_replay {
        unsigned int            rp_buflen;
        char                    *rp_buf;
        unsigned                intrp_allocated;
+       int                     rp_openfh_len;
+       char                    rp_openfh[NFS4_FHSIZE];
        char                    rp_ibuf[NFSD4_REPLAY_ISIZE];
 };