diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-01 09:22:13 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 13:46:36 -0400 |
commit | ce5039c1be1fd04c2d9b1af80d41a6d003f2e20c (patch) | |
tree | 6ad09f92b5d6903fabeee3f4a59c58e174ccb33c /fs/nfs/nfs4proc.c | |
parent | 9b7b9fcc9c124b8a2a079f748239ce9b7a8d8304 (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.c | 100 |
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 | ||
276 | static 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 | |||
291 | int 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 | } | ||
311 | out: | ||
312 | dprintk("<-- %s status=%d\n", __func__, ret); | ||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | struct 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 | |||
323 | static 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 | |||
335 | struct rpc_call_ops nfs41_call_sync_ops = { | ||
336 | .rpc_call_prepare = nfs41_call_sync_prepare, | ||
337 | }; | ||
338 | |||
339 | static 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 | |||
276 | int _nfs4_call_sync_session(struct nfs_server *server, | 372 | int _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 */ |