summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2003-09-22 05:22:37 -0700
committerLinus Torvalds <torvalds@home.osdl.org>2003-09-22 05:22:37 -0700
commitb8ba293df9d5ca62d2a326ade669c46860cacad5 (patch)
tree67d95fe77b5f7b509845a0b05e512268bb64070b /include
parentca04cb992b687acc0dccd17074dc80239dc52e42 (diff)
[PATCH] knfsd: idempotent replay cache for OPEN state
This implements the idempotent replay cache need for NFSv4 OPEN state. each state owner (open owner or lock owner) is required to store the last sequence number mutating operation, and retransmit it when replayed sequence number is presented for the operation. I've implemented the cache as a static buffer of size 112 bytes (NFSD4_REPLAY_ISIZE) which is large enough to hold the OPEN, the largest of the sequence mutation operations. This implements the cache for OPEN, OPEN_CONFIRM, OPEN_DOWNGRADE, and CLOSE. LOCK and UNLOCK will be added when byte-range locking is done (soon!).
Diffstat (limited to 'include')
-rw-r--r--include/linux/nfsd/state.h22
-rw-r--r--include/linux/nfsd/xdr4.h2
2 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index 66422a1c8277..b4d10b7dcc16 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -95,6 +95,27 @@ update_stateid(stateid_t *stateid)
stateid->si_generation++;
}
+/* A reasonable value for REPLAY_ISIZE was estimated as follows:
+ * The OPEN response, typically the largest, requires
+ * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
+ * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
+ * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
+ */
+
+#define NFSD4_REPLAY_ISIZE 112
+
+/*
+ * Replay buffer, where the result of the last seqid-mutating operation
+ * is cached.
+ */
+struct nfs4_replay {
+ u32 rp_status;
+ unsigned int rp_buflen;
+ char *rp_buf;
+ unsigned intrp_allocated;
+ char rp_ibuf[NFSD4_REPLAY_ISIZE];
+};
+
/*
* nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner
*
@@ -111,6 +132,7 @@ struct nfs4_stateowner {
u32 so_seqid;
struct xdr_netobj so_owner; /* open owner name */
int so_confirmed; /* successful OPEN_CONFIRM? */
+ struct nfs4_replay so_replay;
};
/*
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 54c3049f6068..254d5d2c5647 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -284,6 +284,7 @@ struct nfsd4_op {
struct nfsd4_verify verify;
struct nfsd4_write write;
} u;
+ struct nfs4_replay * replay;
};
struct nfsd4_compoundargs {
@@ -339,6 +340,7 @@ int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *,
int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *,
struct nfsd4_compoundres *);
void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
+void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry, u32 *buffer, int *countp,
u32 *bmval);