aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4_fs.h
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:12 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:12 -0400
commitcee54fc944422c44e476736c045a9e8053cb0644 (patch)
tree95f4728b3ffa8a2456727b10cd3a68f2a3065415 /fs/nfs/nfs4_fs.h
parent5e5ce5be6f0161d2a069a4f8a1154fe639c5c02f (diff)
NFSv4: Add functions to order RPC calls
NFSv4 file state-changing functions such as OPEN, CLOSE, LOCK,... are all labelled with "sequence identifiers" in order to prevent the server from reordering RPC requests, as this could cause its file state to become out of sync with the client. Currently the NFS client code enforces this ordering locally using semaphores to restrict access to structures until the RPC call is done. This, of course, only works with synchronous RPC calls, since the user process must first grab the semaphore. By dropping semaphores, and instead teaching the RPC engine to hold the RPC calls until they are ready to be sent, we can extend this process to work nicely with asynchronous RPC calls too. This patch adds a new list called "rpc_sequence" that defines the order of the RPC calls to be sent. We add one such list for each state_owner. When an RPC call is ready to be sent, it checks if it is top of the rpc_sequence list. If so, it proceeds. If not, it goes back to sleep, and loops until it hits top of the list. Once the RPC call has completed, it can then bump the sequence id counter, and remove itself from the rpc_sequence list, and then wake up the next sleeper. Note that the state_owner sequence ids and lock_owner sequence ids are all indexed to the same rpc_sequence list, so OPEN, LOCK,... requests are all ordered w.r.t. each other. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4_fs.h')
-rw-r--r--fs/nfs/nfs4_fs.h42
1 files changed, 38 insertions, 4 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ec1a22d7b876..6ac6708484f5 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -93,6 +93,35 @@ struct nfs4_client {
93}; 93};
94 94
95/* 95/*
96 * struct rpc_sequence ensures that RPC calls are sent in the exact
97 * order that they appear on the list.
98 */
99struct rpc_sequence {
100 struct rpc_wait_queue wait; /* RPC call delay queue */
101 spinlock_t lock; /* Protects the list */
102 struct list_head list; /* Defines sequence of RPC calls */
103};
104
105#define NFS_SEQID_CONFIRMED 1
106struct nfs_seqid_counter {
107 struct rpc_sequence *sequence;
108 int flags;
109 u32 counter;
110};
111
112struct nfs_seqid {
113 struct list_head list;
114 struct nfs_seqid_counter *sequence;
115 struct rpc_task *task;
116};
117
118static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
119{
120 if (seqid_mutating_err(-status))
121 seqid->flags |= NFS_SEQID_CONFIRMED;
122}
123
124/*
96 * NFS4 state_owners and lock_owners are simply labels for ordered 125 * NFS4 state_owners and lock_owners are simply labels for ordered
97 * sequences of RPC calls. Their sole purpose is to provide once-only 126 * sequences of RPC calls. Their sole purpose is to provide once-only
98 * semantics by allowing the server to identify replayed requests. 127 * semantics by allowing the server to identify replayed requests.
@@ -106,12 +135,13 @@ struct nfs4_state_owner {
106 struct nfs4_client *so_client; 135 struct nfs4_client *so_client;
107 u32 so_id; /* 32-bit identifier, unique */ 136 u32 so_id; /* 32-bit identifier, unique */
108 struct semaphore so_sema; 137 struct semaphore so_sema;
109 u32 so_seqid; /* protected by so_sema */
110 atomic_t so_count; 138 atomic_t so_count;
111 139
112 struct rpc_cred *so_cred; /* Associated cred */ 140 struct rpc_cred *so_cred; /* Associated cred */
113 struct list_head so_states; 141 struct list_head so_states;
114 struct list_head so_delegations; 142 struct list_head so_delegations;
143 struct nfs_seqid_counter so_seqid;
144 struct rpc_sequence so_sequence;
115}; 145};
116 146
117/* 147/*
@@ -132,7 +162,7 @@ struct nfs4_lock_state {
132 fl_owner_t ls_owner; /* POSIX lock owner */ 162 fl_owner_t ls_owner; /* POSIX lock owner */
133#define NFS_LOCK_INITIALIZED 1 163#define NFS_LOCK_INITIALIZED 1
134 int ls_flags; 164 int ls_flags;
135 u32 ls_seqid; 165 struct nfs_seqid_counter ls_seqid;
136 u32 ls_id; 166 u32 ls_id;
137 nfs4_stateid ls_stateid; 167 nfs4_stateid ls_stateid;
138 atomic_t ls_count; 168 atomic_t ls_count;
@@ -224,12 +254,16 @@ extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state
224extern void nfs4_put_open_state(struct nfs4_state *); 254extern void nfs4_put_open_state(struct nfs4_state *);
225extern void nfs4_close_state(struct nfs4_state *, mode_t); 255extern void nfs4_close_state(struct nfs4_state *, mode_t);
226extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode); 256extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
227extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
228extern void nfs4_schedule_state_recovery(struct nfs4_client *); 257extern void nfs4_schedule_state_recovery(struct nfs4_client *);
229extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); 258extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
230extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
231extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); 259extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
232 260
261extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
262extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
263extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
264extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
265extern void nfs_free_seqid(struct nfs_seqid *seqid);
266
233extern const nfs4_stateid zero_stateid; 267extern const nfs4_stateid zero_stateid;
234 268
235/* nfs4xdr.c */ 269/* nfs4xdr.c */