aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-04-01 09:22:13 -0400
committerBenny Halevy <bhalevy@panasas.com>2009-06-17 13:46:36 -0400
commitce5039c1be1fd04c2d9b1af80d41a6d003f2e20c (patch)
tree6ad09f92b5d6903fabeee3f4a59c58e174ccb33c /fs/nfs/nfs4proc.c
parent9b7b9fcc9c124b8a2a079f748239ce9b7a8d8304 (diff)
nfs41: nfs4_setup_sequence
Perform the nfs4_setup_sequence in the rpc_call_prepare state. If a session slot is not available, we will rpc_sleep_on the slot wait queue leaving the tk_action as rpc_call_prepare. Once we have a session slot, hang on to it even through rpc_restart_calls. Ensure the nfs41_sequence_res sr_slot pointer is NULL before rpc_run_task is called as nfs41_setup_sequence will only find a new slot if it is NULL. A future patch will call free slot after any rpc_restart_calls, and handle the rpc restart that result from a sequence operation error. Signed-off-by: Rahul Iyer <iyer@netapp.com> [nfs41: sequence res use slotid] Signed-off-by: Andy Adamson<andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: simplify nfs4_call_sync] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: nfs4_call_sync] [nfs41: check for session not minorversion] [nfs41: remove rpc_message from nfs41_call_sync_args] [moved NFS4_MAX_SLOT_TABLE logic into nfs41_setup_sequence] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: nfs41_call_sync_data use nfs_client not nfs_server] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: expose nfs4_call_sync_session for lease renewal] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: remove unnecessary return check] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c100
1 files changed, 98 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5878930b4c3b..90aed76e593b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -273,14 +273,110 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
273 273
274#if defined(CONFIG_NFS_V4_1) 274#if defined(CONFIG_NFS_V4_1)
275 275
276static int nfs41_setup_sequence(struct nfs4_session *session,
277 struct nfs4_sequence_args *args,
278 struct nfs4_sequence_res *res,
279 int cache_reply,
280 struct rpc_task *task)
281{
282 /* slot already allocated? */
283 if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
284 return 0;
285
286 memset(res, 0, sizeof(*res));
287 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
288 return 0;
289}
290
291int nfs4_setup_sequence(struct nfs_client *clp,
292 struct nfs4_sequence_args *args,
293 struct nfs4_sequence_res *res,
294 int cache_reply,
295 struct rpc_task *task)
296{
297 int ret = 0;
298
299 dprintk("--> %s clp %p session %p sr_slotid %d\n",
300 __func__, clp, clp->cl_session, res->sr_slotid);
301
302 if (!nfs4_has_session(clp))
303 goto out;
304 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
305 task);
306 if (ret != -EAGAIN) {
307 /* terminate rpc task */
308 task->tk_status = ret;
309 task->tk_action = NULL;
310 }
311out:
312 dprintk("<-- %s status=%d\n", __func__, ret);
313 return ret;
314}
315
316struct nfs41_call_sync_data {
317 struct nfs_client *clp;
318 struct nfs4_sequence_args *seq_args;
319 struct nfs4_sequence_res *seq_res;
320 int cache_reply;
321};
322
323static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
324{
325 struct nfs41_call_sync_data *data = calldata;
326
327 dprintk("--> %s data->clp->cl_session %p\n", __func__,
328 data->clp->cl_session);
329 if (nfs4_setup_sequence(data->clp, data->seq_args,
330 data->seq_res, data->cache_reply, task))
331 return;
332 rpc_call_start(task);
333}
334
335struct rpc_call_ops nfs41_call_sync_ops = {
336 .rpc_call_prepare = nfs41_call_sync_prepare,
337};
338
339static int nfs4_call_sync_sequence(struct nfs_client *clp,
340 struct rpc_clnt *clnt,
341 struct rpc_message *msg,
342 struct nfs4_sequence_args *args,
343 struct nfs4_sequence_res *res,
344 int cache_reply)
345{
346 int ret;
347 struct rpc_task *task;
348 struct nfs41_call_sync_data data = {
349 .clp = clp,
350 .seq_args = args,
351 .seq_res = res,
352 .cache_reply = cache_reply,
353 };
354 struct rpc_task_setup task_setup = {
355 .rpc_client = clnt,
356 .rpc_message = msg,
357 .callback_ops = &nfs41_call_sync_ops,
358 .callback_data = &data
359 };
360
361 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
362 task = rpc_run_task(&task_setup);
363 if (IS_ERR(task))
364 ret = PTR_ERR(task);
365 else {
366 ret = task->tk_status;
367 rpc_put_task(task);
368 }
369 return ret;
370}
371
276int _nfs4_call_sync_session(struct nfs_server *server, 372int _nfs4_call_sync_session(struct nfs_server *server,
277 struct rpc_message *msg, 373 struct rpc_message *msg,
278 struct nfs4_sequence_args *args, 374 struct nfs4_sequence_args *args,
279 struct nfs4_sequence_res *res, 375 struct nfs4_sequence_res *res,
280 int cache_reply) 376 int cache_reply)
281{ 377{
282 /* in preparation for setting up the sequence op */ 378 return nfs4_call_sync_sequence(server->nfs_client, server->client,
283 return rpc_call_sync(server->client, msg, 0); 379 msg, args, res, cache_reply);
284} 380}
285 381
286#endif /* CONFIG_NFS_V4_1 */ 382#endif /* CONFIG_NFS_V4_1 */