aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4_fs.h10
-rw-r--r--fs/nfs/nfs4proc.c34
-rw-r--r--include/linux/nfs_xdr.h4
3 files changed, 46 insertions, 2 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index acac6f8c3d39..eccf4e93e7d7 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -203,8 +203,18 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
203extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; 203extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
204extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops; 204extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
205#if defined(CONFIG_NFS_V4_1) 205#if defined(CONFIG_NFS_V4_1)
206extern int nfs4_setup_sequence(struct nfs_client *clp,
207 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
208 int cache_reply, struct rpc_task *task);
206extern void nfs4_destroy_session(struct nfs4_session *session); 209extern void nfs4_destroy_session(struct nfs4_session *session);
207extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); 210extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
211#else /* CONFIG_NFS_v4_1 */
212static inline int nfs4_setup_sequence(struct nfs_client *clp,
213 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
214 int cache_reply, struct rpc_task *task)
215{
216 return 0;
217}
208#endif /* CONFIG_NFS_V4_1 */ 218#endif /* CONFIG_NFS_V4_1 */
209 219
210extern const u32 nfs4_fattr_bitmap[2]; 220extern const u32 nfs4_fattr_bitmap[2];
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0946a0d116e..c9618080317e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -280,6 +280,8 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
280 * If found, we mark the slot as used, update the highest_used_slotid, 280 * If found, we mark the slot as used, update the highest_used_slotid,
281 * and respectively set up the sequence operation args. 281 * and respectively set up the sequence operation args.
282 * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise. 282 * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
283 *
284 * Note: must be called with under the slot_tbl_lock.
283 */ 285 */
284static u8 286static u8
285nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) 287nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
@@ -288,7 +290,6 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
288 u8 ret_id = NFS4_MAX_SLOT_TABLE; 290 u8 ret_id = NFS4_MAX_SLOT_TABLE;
289 BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE); 291 BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
290 292
291 spin_lock(&tbl->slot_tbl_lock);
292 dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n", 293 dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
293 __func__, tbl->used_slots[0], tbl->highest_used_slotid, 294 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
294 tbl->max_slots); 295 tbl->max_slots);
@@ -302,7 +303,6 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
302out: 303out:
303 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", 304 dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
304 __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id); 305 __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
305 spin_unlock(&tbl->slot_tbl_lock);
306 return ret_id; 306 return ret_id;
307} 307}
308 308
@@ -312,12 +312,42 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
312 int cache_reply, 312 int cache_reply,
313 struct rpc_task *task) 313 struct rpc_task *task)
314{ 314{
315 struct nfs4_slot *slot;
316 struct nfs4_slot_table *tbl;
317 u8 slotid;
318
319 dprintk("--> %s\n", __func__);
315 /* slot already allocated? */ 320 /* slot already allocated? */
316 if (res->sr_slotid != NFS4_MAX_SLOT_TABLE) 321 if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
317 return 0; 322 return 0;
318 323
319 memset(res, 0, sizeof(*res)); 324 memset(res, 0, sizeof(*res));
320 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 325 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
326 tbl = &session->fc_slot_table;
327
328 spin_lock(&tbl->slot_tbl_lock);
329 slotid = nfs4_find_slot(tbl, task);
330 if (slotid == NFS4_MAX_SLOT_TABLE) {
331 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
332 spin_unlock(&tbl->slot_tbl_lock);
333 dprintk("<-- %s: no free slots\n", __func__);
334 return -EAGAIN;
335 }
336 spin_unlock(&tbl->slot_tbl_lock);
337
338 slot = tbl->slots + slotid;
339 args->sa_slotid = slotid;
340 args->sa_cache_this = cache_reply;
341
342 dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
343
344 res->sr_slotid = slotid;
345 res->sr_renewal_time = jiffies;
346 /*
347 * sr_status is only set in decode_sequence, and so will remain
348 * set to 1 if an rpc level failure occurs.
349 */
350 res->sr_status = 1;
321 return 0; 351 return 0;
322} 352}
323 353
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index db0d1236aae7..4ac14b40efc9 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -163,11 +163,15 @@ struct nfs4_slot {
163 163
164struct nfs4_sequence_args { 164struct nfs4_sequence_args {
165 struct nfs4_session *sa_session; 165 struct nfs4_session *sa_session;
166 u8 sa_slotid;
167 u8 sa_cache_this;
166}; 168};
167 169
168struct nfs4_sequence_res { 170struct nfs4_sequence_res {
169 struct nfs4_session *sr_session; 171 struct nfs4_session *sr_session;
170 u8 sr_slotid; /* slot used to send request */ 172 u8 sr_slotid; /* slot used to send request */
173 unsigned long sr_renewal_time;
174 int sr_status; /* sequence operation status */
171}; 175};
172 176
173/* 177/*