aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/nfs/nfs4proc.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c830
1 files changed, 564 insertions, 266 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 741a562177fc..071fcedd517c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -39,6 +39,7 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/errno.h> 40#include <linux/errno.h>
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/slab.h>
42#include <linux/sunrpc/clnt.h> 43#include <linux/sunrpc/clnt.h>
43#include <linux/nfs.h> 44#include <linux/nfs.h>
44#include <linux/nfs4.h> 45#include <linux/nfs4.h>
@@ -64,6 +65,7 @@
64 65
65struct nfs4_opendata; 66struct nfs4_opendata;
66static int _nfs4_proc_open(struct nfs4_opendata *data); 67static int _nfs4_proc_open(struct nfs4_opendata *data);
68static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
67static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 69static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
68static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *); 70static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
69static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr); 71static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -248,19 +250,15 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
248 if (state == NULL) 250 if (state == NULL)
249 break; 251 break;
250 nfs4_state_mark_reclaim_nograce(clp, state); 252 nfs4_state_mark_reclaim_nograce(clp, state);
251 case -NFS4ERR_STALE_CLIENTID: 253 goto do_state_recovery;
252 case -NFS4ERR_STALE_STATEID: 254 case -NFS4ERR_STALE_STATEID:
253 case -NFS4ERR_EXPIRED: 255 if (state == NULL)
254 nfs4_schedule_state_recovery(clp);
255 ret = nfs4_wait_clnt_recover(clp);
256 if (ret == 0)
257 exception->retry = 1;
258#if !defined(CONFIG_NFS_V4_1)
259 break;
260#else /* !defined(CONFIG_NFS_V4_1) */
261 if (!nfs4_has_session(server->nfs_client))
262 break; 256 break;
263 /* FALLTHROUGH */ 257 nfs4_state_mark_reclaim_reboot(clp, state);
258 case -NFS4ERR_STALE_CLIENTID:
259 case -NFS4ERR_EXPIRED:
260 goto do_state_recovery;
261#if defined(CONFIG_NFS_V4_1)
264 case -NFS4ERR_BADSESSION: 262 case -NFS4ERR_BADSESSION:
265 case -NFS4ERR_BADSLOT: 263 case -NFS4ERR_BADSLOT:
266 case -NFS4ERR_BAD_HIGH_SLOT: 264 case -NFS4ERR_BAD_HIGH_SLOT:
@@ -270,13 +268,21 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
270 case -NFS4ERR_SEQ_MISORDERED: 268 case -NFS4ERR_SEQ_MISORDERED:
271 dprintk("%s ERROR: %d Reset session\n", __func__, 269 dprintk("%s ERROR: %d Reset session\n", __func__,
272 errorcode); 270 errorcode);
273 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 271 nfs4_schedule_state_recovery(clp);
274 exception->retry = 1; 272 exception->retry = 1;
275 /* FALLTHROUGH */ 273 break;
276#endif /* !defined(CONFIG_NFS_V4_1) */ 274#endif /* defined(CONFIG_NFS_V4_1) */
277 case -NFS4ERR_FILE_OPEN: 275 case -NFS4ERR_FILE_OPEN:
276 if (exception->timeout > HZ) {
277 /* We have retried a decent amount, time to
278 * fail
279 */
280 ret = -EBUSY;
281 break;
282 }
278 case -NFS4ERR_GRACE: 283 case -NFS4ERR_GRACE:
279 case -NFS4ERR_DELAY: 284 case -NFS4ERR_DELAY:
285 case -EKEYEXPIRED:
280 ret = nfs4_delay(server->client, &exception->timeout); 286 ret = nfs4_delay(server->client, &exception->timeout);
281 if (ret != 0) 287 if (ret != 0)
282 break; 288 break;
@@ -285,6 +291,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
285 } 291 }
286 /* We failed to handle the error */ 292 /* We failed to handle the error */
287 return nfs4_map_errors(ret); 293 return nfs4_map_errors(ret);
294do_state_recovery:
295 nfs4_schedule_state_recovery(clp);
296 ret = nfs4_wait_clnt_recover(clp);
297 if (ret == 0)
298 exception->retry = 1;
299 return ret;
288} 300}
289 301
290 302
@@ -311,48 +323,67 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
311 * so we need to scan down from highest_used_slotid to 0 looking for the now 323 * so we need to scan down from highest_used_slotid to 0 looking for the now
312 * highest slotid in use. 324 * highest slotid in use.
313 * If none found, highest_used_slotid is set to -1. 325 * If none found, highest_used_slotid is set to -1.
326 *
327 * Must be called while holding tbl->slot_tbl_lock
314 */ 328 */
315static void 329static void
316nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) 330nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
317{ 331{
318 int slotid = free_slotid; 332 int slotid = free_slotid;
319 333
320 spin_lock(&tbl->slot_tbl_lock);
321 /* clear used bit in bitmap */ 334 /* clear used bit in bitmap */
322 __clear_bit(slotid, tbl->used_slots); 335 __clear_bit(slotid, tbl->used_slots);
323 336
324 /* update highest_used_slotid when it is freed */ 337 /* update highest_used_slotid when it is freed */
325 if (slotid == tbl->highest_used_slotid) { 338 if (slotid == tbl->highest_used_slotid) {
326 slotid = find_last_bit(tbl->used_slots, tbl->max_slots); 339 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
327 if (slotid >= 0 && slotid < tbl->max_slots) 340 if (slotid < tbl->max_slots)
328 tbl->highest_used_slotid = slotid; 341 tbl->highest_used_slotid = slotid;
329 else 342 else
330 tbl->highest_used_slotid = -1; 343 tbl->highest_used_slotid = -1;
331 } 344 }
332 rpc_wake_up_next(&tbl->slot_tbl_waitq);
333 spin_unlock(&tbl->slot_tbl_lock);
334 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__, 345 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
335 free_slotid, tbl->highest_used_slotid); 346 free_slotid, tbl->highest_used_slotid);
336} 347}
337 348
338void nfs41_sequence_free_slot(const struct nfs_client *clp, 349/*
339 struct nfs4_sequence_res *res) 350 * Signal state manager thread if session is drained
351 */
352static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
340{ 353{
341 struct nfs4_slot_table *tbl; 354 struct rpc_task *task;
342 355
343 if (!nfs4_has_session(clp)) { 356 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
344 dprintk("%s: No session\n", __func__); 357 task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
358 if (task)
359 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
345 return; 360 return;
346 } 361 }
362
363 if (ses->fc_slot_table.highest_used_slotid != -1)
364 return;
365
366 dprintk("%s COMPLETE: Session Drained\n", __func__);
367 complete(&ses->complete);
368}
369
370static void nfs41_sequence_free_slot(const struct nfs_client *clp,
371 struct nfs4_sequence_res *res)
372{
373 struct nfs4_slot_table *tbl;
374
347 tbl = &clp->cl_session->fc_slot_table; 375 tbl = &clp->cl_session->fc_slot_table;
348 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { 376 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
349 dprintk("%s: No slot\n", __func__);
350 /* just wake up the next guy waiting since 377 /* just wake up the next guy waiting since
351 * we may have not consumed a slot after all */ 378 * we may have not consumed a slot after all */
352 rpc_wake_up_next(&tbl->slot_tbl_waitq); 379 dprintk("%s: No slot\n", __func__);
353 return; 380 return;
354 } 381 }
382
383 spin_lock(&tbl->slot_tbl_lock);
355 nfs4_free_slot(tbl, res->sr_slotid); 384 nfs4_free_slot(tbl, res->sr_slotid);
385 nfs41_check_drain_session_complete(clp->cl_session);
386 spin_unlock(&tbl->slot_tbl_lock);
356 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 387 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
357} 388}
358 389
@@ -377,10 +408,10 @@ static void nfs41_sequence_done(struct nfs_client *clp,
377 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) 408 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
378 goto out; 409 goto out;
379 410
380 tbl = &clp->cl_session->fc_slot_table; 411 /* Check the SEQUENCE operation status */
381 slot = tbl->slots + res->sr_slotid;
382
383 if (res->sr_status == 0) { 412 if (res->sr_status == 0) {
413 tbl = &clp->cl_session->fc_slot_table;
414 slot = tbl->slots + res->sr_slotid;
384 /* Update the slot's sequence and clientid lease timer */ 415 /* Update the slot's sequence and clientid lease timer */
385 ++slot->seq_nr; 416 ++slot->seq_nr;
386 timestamp = res->sr_renewal_time; 417 timestamp = res->sr_renewal_time;
@@ -388,7 +419,9 @@ static void nfs41_sequence_done(struct nfs_client *clp,
388 if (time_before(clp->cl_last_renewal, timestamp)) 419 if (time_before(clp->cl_last_renewal, timestamp))
389 clp->cl_last_renewal = timestamp; 420 clp->cl_last_renewal = timestamp;
390 spin_unlock(&clp->cl_lock); 421 spin_unlock(&clp->cl_lock);
391 return; 422 /* Check sequence flags */
423 if (atomic_read(&clp->cl_count) > 1)
424 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
392 } 425 }
393out: 426out:
394 /* The session may be reset by one of the error handlers. */ 427 /* The session may be reset by one of the error handlers. */
@@ -407,7 +440,7 @@ out:
407 * Note: must be called with under the slot_tbl_lock. 440 * Note: must be called with under the slot_tbl_lock.
408 */ 441 */
409static u8 442static u8
410nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) 443nfs4_find_slot(struct nfs4_slot_table *tbl)
411{ 444{
412 int slotid; 445 int slotid;
413 u8 ret_id = NFS4_MAX_SLOT_TABLE; 446 u8 ret_id = NFS4_MAX_SLOT_TABLE;
@@ -429,24 +462,6 @@ out:
429 return ret_id; 462 return ret_id;
430} 463}
431 464
432static int nfs4_recover_session(struct nfs4_session *session)
433{
434 struct nfs_client *clp = session->clp;
435 unsigned int loop;
436 int ret;
437
438 for (loop = NFS4_MAX_LOOP_ON_RECOVER; loop != 0; loop--) {
439 ret = nfs4_wait_clnt_recover(clp);
440 if (ret != 0)
441 break;
442 if (!test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state))
443 break;
444 nfs4_schedule_state_manager(clp);
445 ret = -EIO;
446 }
447 return ret;
448}
449
450static int nfs41_setup_sequence(struct nfs4_session *session, 465static int nfs41_setup_sequence(struct nfs4_session *session,
451 struct nfs4_sequence_args *args, 466 struct nfs4_sequence_args *args,
452 struct nfs4_sequence_res *res, 467 struct nfs4_sequence_res *res,
@@ -455,7 +470,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
455{ 470{
456 struct nfs4_slot *slot; 471 struct nfs4_slot *slot;
457 struct nfs4_slot_table *tbl; 472 struct nfs4_slot_table *tbl;
458 int status = 0;
459 u8 slotid; 473 u8 slotid;
460 474
461 dprintk("--> %s\n", __func__); 475 dprintk("--> %s\n", __func__);
@@ -468,24 +482,27 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
468 tbl = &session->fc_slot_table; 482 tbl = &session->fc_slot_table;
469 483
470 spin_lock(&tbl->slot_tbl_lock); 484 spin_lock(&tbl->slot_tbl_lock);
471 if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) { 485 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state) &&
472 if (tbl->highest_used_slotid != -1) { 486 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
473 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 487 /*
474 spin_unlock(&tbl->slot_tbl_lock); 488 * The state manager will wait until the slot table is empty.
475 dprintk("<-- %s: Session reset: draining\n", __func__); 489 * Schedule the reset thread
476 return -EAGAIN; 490 */
477 } 491 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
492 spin_unlock(&tbl->slot_tbl_lock);
493 dprintk("%s Schedule Session Reset\n", __func__);
494 return -EAGAIN;
495 }
478 496
479 /* The slot table is empty; start the reset thread */ 497 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) &&
480 dprintk("%s Session Reset\n", __func__); 498 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
499 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
481 spin_unlock(&tbl->slot_tbl_lock); 500 spin_unlock(&tbl->slot_tbl_lock);
482 status = nfs4_recover_session(session); 501 dprintk("%s enforce FIFO order\n", __func__);
483 if (status) 502 return -EAGAIN;
484 return status;
485 spin_lock(&tbl->slot_tbl_lock);
486 } 503 }
487 504
488 slotid = nfs4_find_slot(tbl, task); 505 slotid = nfs4_find_slot(tbl);
489 if (slotid == NFS4_MAX_SLOT_TABLE) { 506 if (slotid == NFS4_MAX_SLOT_TABLE) {
490 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 507 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
491 spin_unlock(&tbl->slot_tbl_lock); 508 spin_unlock(&tbl->slot_tbl_lock);
@@ -494,6 +511,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
494 } 511 }
495 spin_unlock(&tbl->slot_tbl_lock); 512 spin_unlock(&tbl->slot_tbl_lock);
496 513
514 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);
497 slot = tbl->slots + slotid; 515 slot = tbl->slots + slotid;
498 args->sa_session = session; 516 args->sa_session = session;
499 args->sa_slotid = slotid; 517 args->sa_slotid = slotid;
@@ -527,7 +545,7 @@ int nfs4_setup_sequence(struct nfs_client *clp,
527 goto out; 545 goto out;
528 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply, 546 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
529 task); 547 task);
530 if (ret != -EAGAIN) { 548 if (ret && ret != -EAGAIN) {
531 /* terminate rpc task */ 549 /* terminate rpc task */
532 task->tk_status = ret; 550 task->tk_status = ret;
533 task->tk_action = NULL; 551 task->tk_action = NULL;
@@ -556,12 +574,17 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
556 rpc_call_start(task); 574 rpc_call_start(task);
557} 575}
558 576
577static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
578{
579 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
580 nfs41_call_sync_prepare(task, calldata);
581}
582
559static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 583static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
560{ 584{
561 struct nfs41_call_sync_data *data = calldata; 585 struct nfs41_call_sync_data *data = calldata;
562 586
563 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); 587 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
564 nfs41_sequence_free_slot(data->clp, data->seq_res);
565} 588}
566 589
567struct rpc_call_ops nfs41_call_sync_ops = { 590struct rpc_call_ops nfs41_call_sync_ops = {
@@ -569,12 +592,18 @@ struct rpc_call_ops nfs41_call_sync_ops = {
569 .rpc_call_done = nfs41_call_sync_done, 592 .rpc_call_done = nfs41_call_sync_done,
570}; 593};
571 594
595struct rpc_call_ops nfs41_call_priv_sync_ops = {
596 .rpc_call_prepare = nfs41_call_priv_sync_prepare,
597 .rpc_call_done = nfs41_call_sync_done,
598};
599
572static int nfs4_call_sync_sequence(struct nfs_client *clp, 600static int nfs4_call_sync_sequence(struct nfs_client *clp,
573 struct rpc_clnt *clnt, 601 struct rpc_clnt *clnt,
574 struct rpc_message *msg, 602 struct rpc_message *msg,
575 struct nfs4_sequence_args *args, 603 struct nfs4_sequence_args *args,
576 struct nfs4_sequence_res *res, 604 struct nfs4_sequence_res *res,
577 int cache_reply) 605 int cache_reply,
606 int privileged)
578{ 607{
579 int ret; 608 int ret;
580 struct rpc_task *task; 609 struct rpc_task *task;
@@ -592,6 +621,8 @@ static int nfs4_call_sync_sequence(struct nfs_client *clp,
592 }; 621 };
593 622
594 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 623 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
624 if (privileged)
625 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
595 task = rpc_run_task(&task_setup); 626 task = rpc_run_task(&task_setup);
596 if (IS_ERR(task)) 627 if (IS_ERR(task))
597 ret = PTR_ERR(task); 628 ret = PTR_ERR(task);
@@ -609,7 +640,7 @@ int _nfs4_call_sync_session(struct nfs_server *server,
609 int cache_reply) 640 int cache_reply)
610{ 641{
611 return nfs4_call_sync_sequence(server->nfs_client, server->client, 642 return nfs4_call_sync_sequence(server->nfs_client, server->client,
612 msg, args, res, cache_reply); 643 msg, args, res, cache_reply, 0);
613} 644}
614 645
615#endif /* CONFIG_NFS_V4_1 */ 646#endif /* CONFIG_NFS_V4_1 */
@@ -637,15 +668,6 @@ static void nfs4_sequence_done(const struct nfs_server *server,
637#endif /* CONFIG_NFS_V4_1 */ 668#endif /* CONFIG_NFS_V4_1 */
638} 669}
639 670
640/* no restart, therefore free slot here */
641static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
642 struct nfs4_sequence_res *res,
643 int rpc_status)
644{
645 nfs4_sequence_done(server, res, rpc_status);
646 nfs4_sequence_free_slot(server->nfs_client, res);
647}
648
649static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo) 671static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
650{ 672{
651 struct nfs_inode *nfsi = NFS_I(dir); 673 struct nfs_inode *nfsi = NFS_I(dir);
@@ -705,8 +727,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
705 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); 727 p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
706 if (p->o_arg.seqid == NULL) 728 if (p->o_arg.seqid == NULL)
707 goto err_free; 729 goto err_free;
708 p->path.mnt = mntget(path->mnt); 730 path_get(path);
709 p->path.dentry = dget(path->dentry); 731 p->path = *path;
710 p->dir = parent; 732 p->dir = parent;
711 p->owner = sp; 733 p->owner = sp;
712 atomic_inc(&sp->so_count); 734 atomic_inc(&sp->so_count);
@@ -720,9 +742,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
720 p->o_arg.bitmask = server->attr_bitmask; 742 p->o_arg.bitmask = server->attr_bitmask;
721 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 743 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
722 if (flags & O_EXCL) { 744 if (flags & O_EXCL) {
723 u32 *s = (u32 *) p->o_arg.u.verifier.data; 745 if (nfs4_has_persistent_session(server->nfs_client)) {
724 s[0] = jiffies; 746 /* GUARDED */
725 s[1] = current->pid; 747 p->o_arg.u.attrs = &p->attrs;
748 memcpy(&p->attrs, attrs, sizeof(p->attrs));
749 } else { /* EXCLUSIVE4_1 */
750 u32 *s = (u32 *) p->o_arg.u.verifier.data;
751 s[0] = jiffies;
752 s[1] = current->pid;
753 }
726 } else if (flags & O_CREAT) { 754 } else if (flags & O_CREAT) {
727 p->o_arg.u.attrs = &p->attrs; 755 p->o_arg.u.attrs = &p->attrs;
728 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 756 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -776,13 +804,16 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
776 goto out; 804 goto out;
777 switch (mode & (FMODE_READ|FMODE_WRITE)) { 805 switch (mode & (FMODE_READ|FMODE_WRITE)) {
778 case FMODE_READ: 806 case FMODE_READ:
779 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; 807 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
808 && state->n_rdonly != 0;
780 break; 809 break;
781 case FMODE_WRITE: 810 case FMODE_WRITE:
782 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; 811 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0
812 && state->n_wronly != 0;
783 break; 813 break;
784 case FMODE_READ|FMODE_WRITE: 814 case FMODE_READ|FMODE_WRITE:
785 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; 815 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0
816 && state->n_rdwr != 0;
786 } 817 }
787out: 818out:
788 return ret; 819 return ret;
@@ -1047,7 +1078,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod
1047 memset(&opendata->o_res, 0, sizeof(opendata->o_res)); 1078 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
1048 memset(&opendata->c_res, 0, sizeof(opendata->c_res)); 1079 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
1049 nfs4_init_opendata_res(opendata); 1080 nfs4_init_opendata_res(opendata);
1050 ret = _nfs4_proc_open(opendata); 1081 ret = _nfs4_recover_proc_open(opendata);
1051 if (ret != 0) 1082 if (ret != 0)
1052 return ret; 1083 return ret;
1053 newstate = nfs4_opendata_to_nfs4_state(opendata); 1084 newstate = nfs4_opendata_to_nfs4_state(opendata);
@@ -1135,7 +1166,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
1135 int err; 1166 int err;
1136 do { 1167 do {
1137 err = _nfs4_do_open_reclaim(ctx, state); 1168 err = _nfs4_do_open_reclaim(ctx, state);
1138 if (err != -NFS4ERR_DELAY) 1169 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
1139 break; 1170 break;
1140 nfs4_handle_exception(server, err, &exception); 1171 nfs4_handle_exception(server, err, &exception);
1141 } while (exception.retry); 1172 } while (exception.retry);
@@ -1183,6 +1214,14 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1183 case -ENOENT: 1214 case -ENOENT:
1184 case -ESTALE: 1215 case -ESTALE:
1185 goto out; 1216 goto out;
1217 case -NFS4ERR_BADSESSION:
1218 case -NFS4ERR_BADSLOT:
1219 case -NFS4ERR_BAD_HIGH_SLOT:
1220 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1221 case -NFS4ERR_DEADSESSION:
1222 nfs4_schedule_state_recovery(
1223 server->nfs_client);
1224 goto out;
1186 case -NFS4ERR_STALE_CLIENTID: 1225 case -NFS4ERR_STALE_CLIENTID:
1187 case -NFS4ERR_STALE_STATEID: 1226 case -NFS4ERR_STALE_STATEID:
1188 case -NFS4ERR_EXPIRED: 1227 case -NFS4ERR_EXPIRED:
@@ -1330,14 +1369,20 @@ out_no_action:
1330 1369
1331} 1370}
1332 1371
1372static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
1373{
1374 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
1375 nfs4_open_prepare(task, calldata);
1376}
1377
1333static void nfs4_open_done(struct rpc_task *task, void *calldata) 1378static void nfs4_open_done(struct rpc_task *task, void *calldata)
1334{ 1379{
1335 struct nfs4_opendata *data = calldata; 1380 struct nfs4_opendata *data = calldata;
1336 1381
1337 data->rpc_status = task->tk_status; 1382 data->rpc_status = task->tk_status;
1338 1383
1339 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res, 1384 nfs4_sequence_done(data->o_arg.server, &data->o_res.seq_res,
1340 task->tk_status); 1385 task->tk_status);
1341 1386
1342 if (RPC_ASSASSINATED(task)) 1387 if (RPC_ASSASSINATED(task))
1343 return; 1388 return;
@@ -1388,10 +1433,13 @@ static const struct rpc_call_ops nfs4_open_ops = {
1388 .rpc_release = nfs4_open_release, 1433 .rpc_release = nfs4_open_release,
1389}; 1434};
1390 1435
1391/* 1436static const struct rpc_call_ops nfs4_recover_open_ops = {
1392 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata 1437 .rpc_call_prepare = nfs4_recover_open_prepare,
1393 */ 1438 .rpc_call_done = nfs4_open_done,
1394static int _nfs4_proc_open(struct nfs4_opendata *data) 1439 .rpc_release = nfs4_open_release,
1440};
1441
1442static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1395{ 1443{
1396 struct inode *dir = data->dir->d_inode; 1444 struct inode *dir = data->dir->d_inode;
1397 struct nfs_server *server = NFS_SERVER(dir); 1445 struct nfs_server *server = NFS_SERVER(dir);
@@ -1418,27 +1466,65 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1418 data->rpc_done = 0; 1466 data->rpc_done = 0;
1419 data->rpc_status = 0; 1467 data->rpc_status = 0;
1420 data->cancelled = 0; 1468 data->cancelled = 0;
1469 if (isrecover)
1470 task_setup_data.callback_ops = &nfs4_recover_open_ops;
1421 task = rpc_run_task(&task_setup_data); 1471 task = rpc_run_task(&task_setup_data);
1422 if (IS_ERR(task)) 1472 if (IS_ERR(task))
1423 return PTR_ERR(task); 1473 return PTR_ERR(task);
1424 status = nfs4_wait_for_completion_rpc_task(task); 1474 status = nfs4_wait_for_completion_rpc_task(task);
1425 if (status != 0) { 1475 if (status != 0) {
1426 data->cancelled = 1; 1476 data->cancelled = 1;
1427 smp_wmb(); 1477 smp_wmb();
1428 } else 1478 } else
1429 status = data->rpc_status; 1479 status = data->rpc_status;
1430 rpc_put_task(task); 1480 rpc_put_task(task);
1481
1482 return status;
1483}
1484
1485static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1486{
1487 struct inode *dir = data->dir->d_inode;
1488 struct nfs_openres *o_res = &data->o_res;
1489 int status;
1490
1491 status = nfs4_run_open_task(data, 1);
1431 if (status != 0 || !data->rpc_done) 1492 if (status != 0 || !data->rpc_done)
1432 return status; 1493 return status;
1433 1494
1434 if (o_res->fh.size == 0) 1495 nfs_refresh_inode(dir, o_res->dir_attr);
1435 _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); 1496
1497 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1498 status = _nfs4_proc_open_confirm(data);
1499 if (status != 0)
1500 return status;
1501 }
1502
1503 return status;
1504}
1505
1506/*
1507 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
1508 */
1509static int _nfs4_proc_open(struct nfs4_opendata *data)
1510{
1511 struct inode *dir = data->dir->d_inode;
1512 struct nfs_server *server = NFS_SERVER(dir);
1513 struct nfs_openargs *o_arg = &data->o_arg;
1514 struct nfs_openres *o_res = &data->o_res;
1515 int status;
1516
1517 status = nfs4_run_open_task(data, 0);
1518 if (status != 0 || !data->rpc_done)
1519 return status;
1436 1520
1437 if (o_arg->open_flags & O_CREAT) { 1521 if (o_arg->open_flags & O_CREAT) {
1438 update_changeattr(dir, &o_res->cinfo); 1522 update_changeattr(dir, &o_res->cinfo);
1439 nfs_post_op_update_inode(dir, o_res->dir_attr); 1523 nfs_post_op_update_inode(dir, o_res->dir_attr);
1440 } else 1524 } else
1441 nfs_refresh_inode(dir, o_res->dir_attr); 1525 nfs_refresh_inode(dir, o_res->dir_attr);
1526 if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
1527 server->caps &= ~NFS_CAP_POSIX_LOCK;
1442 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { 1528 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1443 status = _nfs4_proc_open_confirm(data); 1529 status = _nfs4_proc_open_confirm(data);
1444 if (status != 0) 1530 if (status != 0)
@@ -1488,7 +1574,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1488 return ret; 1574 return ret;
1489} 1575}
1490 1576
1491static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) 1577static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
1492{ 1578{
1493 struct nfs_server *server = NFS_SERVER(state->inode); 1579 struct nfs_server *server = NFS_SERVER(state->inode);
1494 struct nfs4_exception exception = { }; 1580 struct nfs4_exception exception = { };
@@ -1496,10 +1582,17 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4
1496 1582
1497 do { 1583 do {
1498 err = _nfs4_open_expired(ctx, state); 1584 err = _nfs4_open_expired(ctx, state);
1499 if (err != -NFS4ERR_DELAY) 1585 switch (err) {
1500 break; 1586 default:
1501 nfs4_handle_exception(server, err, &exception); 1587 goto out;
1588 case -NFS4ERR_GRACE:
1589 case -NFS4ERR_DELAY:
1590 case -EKEYEXPIRED:
1591 nfs4_handle_exception(server, err, &exception);
1592 err = 0;
1593 }
1502 } while (exception.retry); 1594 } while (exception.retry);
1595out:
1503 return err; 1596 return err;
1504} 1597}
1505 1598
@@ -1573,6 +1666,8 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
1573 status = PTR_ERR(state); 1666 status = PTR_ERR(state);
1574 if (IS_ERR(state)) 1667 if (IS_ERR(state))
1575 goto err_opendata_put; 1668 goto err_opendata_put;
1669 if (server->caps & NFS_CAP_POSIX_LOCK)
1670 set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
1576 nfs4_opendata_put(opendata); 1671 nfs4_opendata_put(opendata);
1577 nfs4_put_state_owner(sp); 1672 nfs4_put_state_owner(sp);
1578 *res = state; 1673 *res = state;
@@ -1712,6 +1807,18 @@ static void nfs4_free_closedata(void *data)
1712 kfree(calldata); 1807 kfree(calldata);
1713} 1808}
1714 1809
1810static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
1811 fmode_t fmode)
1812{
1813 spin_lock(&state->owner->so_lock);
1814 if (!(fmode & FMODE_READ))
1815 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1816 if (!(fmode & FMODE_WRITE))
1817 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1818 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1819 spin_unlock(&state->owner->so_lock);
1820}
1821
1715static void nfs4_close_done(struct rpc_task *task, void *data) 1822static void nfs4_close_done(struct rpc_task *task, void *data)
1716{ 1823{
1717 struct nfs4_closedata *calldata = data; 1824 struct nfs4_closedata *calldata = data;
@@ -1728,6 +1835,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1728 case 0: 1835 case 0:
1729 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1836 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1730 renew_lease(server, calldata->timestamp); 1837 renew_lease(server, calldata->timestamp);
1838 nfs4_close_clear_stateid_flags(state,
1839 calldata->arg.fmode);
1731 break; 1840 break;
1732 case -NFS4ERR_STALE_STATEID: 1841 case -NFS4ERR_STALE_STATEID:
1733 case -NFS4ERR_OLD_STATEID: 1842 case -NFS4ERR_OLD_STATEID:
@@ -1736,12 +1845,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1736 if (calldata->arg.fmode == 0) 1845 if (calldata->arg.fmode == 0)
1737 break; 1846 break;
1738 default: 1847 default:
1739 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1848 if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
1740 nfs4_restart_rpc(task, server->nfs_client); 1849 rpc_restart_call_prepare(task);
1741 return;
1742 }
1743 } 1850 }
1744 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res); 1851 nfs_release_seqid(calldata->arg.seqid);
1745 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1852 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1746} 1853}
1747 1854
@@ -1749,38 +1856,39 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1749{ 1856{
1750 struct nfs4_closedata *calldata = data; 1857 struct nfs4_closedata *calldata = data;
1751 struct nfs4_state *state = calldata->state; 1858 struct nfs4_state *state = calldata->state;
1752 int clear_rd, clear_wr, clear_rdwr; 1859 int call_close = 0;
1753 1860
1754 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) 1861 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
1755 return; 1862 return;
1756 1863
1757 clear_rd = clear_wr = clear_rdwr = 0; 1864 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1865 calldata->arg.fmode = FMODE_READ|FMODE_WRITE;
1758 spin_lock(&state->owner->so_lock); 1866 spin_lock(&state->owner->so_lock);
1759 /* Calculate the change in open mode */ 1867 /* Calculate the change in open mode */
1760 if (state->n_rdwr == 0) { 1868 if (state->n_rdwr == 0) {
1761 if (state->n_rdonly == 0) { 1869 if (state->n_rdonly == 0) {
1762 clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1870 call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
1763 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1871 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1872 calldata->arg.fmode &= ~FMODE_READ;
1764 } 1873 }
1765 if (state->n_wronly == 0) { 1874 if (state->n_wronly == 0) {
1766 clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1875 call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
1767 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1876 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1877 calldata->arg.fmode &= ~FMODE_WRITE;
1768 } 1878 }
1769 } 1879 }
1770 spin_unlock(&state->owner->so_lock); 1880 spin_unlock(&state->owner->so_lock);
1771 if (!clear_rd && !clear_wr && !clear_rdwr) { 1881
1882 if (!call_close) {
1772 /* Note: exit _without_ calling nfs4_close_done */ 1883 /* Note: exit _without_ calling nfs4_close_done */
1773 task->tk_action = NULL; 1884 task->tk_action = NULL;
1774 return; 1885 return;
1775 } 1886 }
1887
1888 if (calldata->arg.fmode == 0)
1889 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1890
1776 nfs_fattr_init(calldata->res.fattr); 1891 nfs_fattr_init(calldata->res.fattr);
1777 if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
1778 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1779 calldata->arg.fmode = FMODE_READ;
1780 } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
1781 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1782 calldata->arg.fmode = FMODE_WRITE;
1783 }
1784 calldata->timestamp = jiffies; 1892 calldata->timestamp = jiffies;
1785 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client, 1893 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1786 &calldata->arg.seq_args, &calldata->res.seq_res, 1894 &calldata->arg.seq_args, &calldata->res.seq_res,
@@ -1832,8 +1940,6 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1832 calldata->state = state; 1940 calldata->state = state;
1833 calldata->arg.fh = NFS_FH(state->inode); 1941 calldata->arg.fh = NFS_FH(state->inode);
1834 calldata->arg.stateid = &state->open_stateid; 1942 calldata->arg.stateid = &state->open_stateid;
1835 if (nfs4_has_session(server->nfs_client))
1836 memset(calldata->arg.stateid->data, 0, 4); /* clear seqid */
1837 /* Serialization for the sequence id */ 1943 /* Serialization for the sequence id */
1838 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1944 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1839 if (calldata->arg.seqid == NULL) 1945 if (calldata->arg.seqid == NULL)
@@ -1844,8 +1950,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1844 calldata->res.seqid = calldata->arg.seqid; 1950 calldata->res.seqid = calldata->arg.seqid;
1845 calldata->res.server = server; 1951 calldata->res.server = server;
1846 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE; 1952 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
1847 calldata->path.mnt = mntget(path->mnt); 1953 path_get(path);
1848 calldata->path.dentry = dget(path->dentry); 1954 calldata->path = *path;
1849 1955
1850 msg.rpc_argp = &calldata->arg, 1956 msg.rpc_argp = &calldata->arg,
1851 msg.rpc_resp = &calldata->res, 1957 msg.rpc_resp = &calldata->res,
@@ -1964,8 +2070,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
1964 case -EDQUOT: 2070 case -EDQUOT:
1965 case -ENOSPC: 2071 case -ENOSPC:
1966 case -EROFS: 2072 case -EROFS:
1967 lookup_instantiate_filp(nd, (struct dentry *)state, NULL); 2073 return PTR_ERR(state);
1968 return 1;
1969 default: 2074 default:
1970 goto out_drop; 2075 goto out_drop;
1971 } 2076 }
@@ -1981,7 +2086,7 @@ out_drop:
1981 return 0; 2086 return 0;
1982} 2087}
1983 2088
1984void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2089static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1985{ 2090{
1986 if (ctx->state == NULL) 2091 if (ctx->state == NULL)
1987 return; 2092 return;
@@ -2532,7 +2637,6 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
2532 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status); 2637 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2533 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2638 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2534 return 0; 2639 return 0;
2535 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2536 update_changeattr(dir, &res->cinfo); 2640 update_changeattr(dir, &res->cinfo);
2537 nfs_post_op_update_inode(dir, &res->dir_attr); 2641 nfs_post_op_update_inode(dir, &res->dir_attr);
2538 return 1; 2642 return 1;
@@ -2971,11 +3075,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2971 3075
2972 dprintk("--> %s\n", __func__); 3076 dprintk("--> %s\n", __func__);
2973 3077
2974 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2975 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); 3078 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2976 3079
2977 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3080 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2978 nfs4_restart_rpc(task, server->nfs_client); 3081 nfs_restart_rpc(task, server->nfs_client);
2979 return -EAGAIN; 3082 return -EAGAIN;
2980 } 3083 }
2981 3084
@@ -2995,12 +3098,11 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2995{ 3098{
2996 struct inode *inode = data->inode; 3099 struct inode *inode = data->inode;
2997 3100
2998 /* slot is freed in nfs_writeback_done */
2999 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3101 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3000 task->tk_status); 3102 task->tk_status);
3001 3103
3002 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3104 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3003 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3105 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3004 return -EAGAIN; 3106 return -EAGAIN;
3005 } 3107 }
3006 if (task->tk_status >= 0) { 3108 if (task->tk_status >= 0) {
@@ -3028,11 +3130,9 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
3028 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3130 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3029 task->tk_status); 3131 task->tk_status);
3030 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3132 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3031 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3133 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3032 return -EAGAIN; 3134 return -EAGAIN;
3033 } 3135 }
3034 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
3035 &data->res.seq_res);
3036 nfs_refresh_inode(inode, data->res.fattr); 3136 nfs_refresh_inode(inode, data->res.fattr);
3037 return 0; 3137 return 0;
3038} 3138}
@@ -3050,10 +3150,19 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
3050 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special 3150 * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
3051 * standalone procedure for queueing an asynchronous RENEW. 3151 * standalone procedure for queueing an asynchronous RENEW.
3052 */ 3152 */
3153static void nfs4_renew_release(void *data)
3154{
3155 struct nfs_client *clp = data;
3156
3157 if (atomic_read(&clp->cl_count) > 1)
3158 nfs4_schedule_state_renewal(clp);
3159 nfs_put_client(clp);
3160}
3161
3053static void nfs4_renew_done(struct rpc_task *task, void *data) 3162static void nfs4_renew_done(struct rpc_task *task, void *data)
3054{ 3163{
3055 struct nfs_client *clp = (struct nfs_client *)task->tk_msg.rpc_argp; 3164 struct nfs_client *clp = data;
3056 unsigned long timestamp = (unsigned long)data; 3165 unsigned long timestamp = task->tk_start;
3057 3166
3058 if (task->tk_status < 0) { 3167 if (task->tk_status < 0) {
3059 /* Unless we're shutting down, schedule state recovery! */ 3168 /* Unless we're shutting down, schedule state recovery! */
@@ -3069,6 +3178,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *data)
3069 3178
3070static const struct rpc_call_ops nfs4_renew_ops = { 3179static const struct rpc_call_ops nfs4_renew_ops = {
3071 .rpc_call_done = nfs4_renew_done, 3180 .rpc_call_done = nfs4_renew_done,
3181 .rpc_release = nfs4_renew_release,
3072}; 3182};
3073 3183
3074int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) 3184int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3079,8 +3189,10 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
3079 .rpc_cred = cred, 3189 .rpc_cred = cred,
3080 }; 3190 };
3081 3191
3192 if (!atomic_inc_not_zero(&clp->cl_count))
3193 return -EIO;
3082 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, 3194 return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
3083 &nfs4_renew_ops, (void *)jiffies); 3195 &nfs4_renew_ops, clp);
3084} 3196}
3085 3197
3086int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) 3198int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3331,15 +3443,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3331 if (state == NULL) 3443 if (state == NULL)
3332 break; 3444 break;
3333 nfs4_state_mark_reclaim_nograce(clp, state); 3445 nfs4_state_mark_reclaim_nograce(clp, state);
3334 case -NFS4ERR_STALE_CLIENTID: 3446 goto do_state_recovery;
3335 case -NFS4ERR_STALE_STATEID: 3447 case -NFS4ERR_STALE_STATEID:
3448 if (state == NULL)
3449 break;
3450 nfs4_state_mark_reclaim_reboot(clp, state);
3451 case -NFS4ERR_STALE_CLIENTID:
3336 case -NFS4ERR_EXPIRED: 3452 case -NFS4ERR_EXPIRED:
3337 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); 3453 goto do_state_recovery;
3338 nfs4_schedule_state_recovery(clp);
3339 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
3340 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
3341 task->tk_status = 0;
3342 return -EAGAIN;
3343#if defined(CONFIG_NFS_V4_1) 3454#if defined(CONFIG_NFS_V4_1)
3344 case -NFS4ERR_BADSESSION: 3455 case -NFS4ERR_BADSESSION:
3345 case -NFS4ERR_BADSLOT: 3456 case -NFS4ERR_BADSLOT:
@@ -3350,7 +3461,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3350 case -NFS4ERR_SEQ_MISORDERED: 3461 case -NFS4ERR_SEQ_MISORDERED:
3351 dprintk("%s ERROR %d, Reset session\n", __func__, 3462 dprintk("%s ERROR %d, Reset session\n", __func__,
3352 task->tk_status); 3463 task->tk_status);
3353 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 3464 nfs4_schedule_state_recovery(clp);
3354 task->tk_status = 0; 3465 task->tk_status = 0;
3355 return -EAGAIN; 3466 return -EAGAIN;
3356#endif /* CONFIG_NFS_V4_1 */ 3467#endif /* CONFIG_NFS_V4_1 */
@@ -3358,6 +3469,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3358 if (server) 3469 if (server)
3359 nfs_inc_server_stats(server, NFSIOS_DELAY); 3470 nfs_inc_server_stats(server, NFSIOS_DELAY);
3360 case -NFS4ERR_GRACE: 3471 case -NFS4ERR_GRACE:
3472 case -EKEYEXPIRED:
3361 rpc_delay(task, NFS4_POLL_RETRY_MAX); 3473 rpc_delay(task, NFS4_POLL_RETRY_MAX);
3362 task->tk_status = 0; 3474 task->tk_status = 0;
3363 return -EAGAIN; 3475 return -EAGAIN;
@@ -3367,6 +3479,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3367 } 3479 }
3368 task->tk_status = nfs4_map_errors(task->tk_status); 3480 task->tk_status = nfs4_map_errors(task->tk_status);
3369 return 0; 3481 return 0;
3482do_state_recovery:
3483 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
3484 nfs4_schedule_state_recovery(clp);
3485 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
3486 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
3487 task->tk_status = 0;
3488 return -EAGAIN;
3370} 3489}
3371 3490
3372static int 3491static int
@@ -3463,6 +3582,7 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
3463 case -NFS4ERR_RESOURCE: 3582 case -NFS4ERR_RESOURCE:
3464 /* The IBM lawyers misread another document! */ 3583 /* The IBM lawyers misread another document! */
3465 case -NFS4ERR_DELAY: 3584 case -NFS4ERR_DELAY:
3585 case -EKEYEXPIRED:
3466 err = nfs4_delay(clp->cl_rpcclient, &timeout); 3586 err = nfs4_delay(clp->cl_rpcclient, &timeout);
3467 } 3587 }
3468 } while (err == 0); 3588 } while (err == 0);
@@ -3483,12 +3603,23 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3483{ 3603{
3484 struct nfs4_delegreturndata *data = calldata; 3604 struct nfs4_delegreturndata *data = calldata;
3485 3605
3486 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res, 3606 nfs4_sequence_done(data->res.server, &data->res.seq_res,
3487 task->tk_status); 3607 task->tk_status);
3488 3608
3489 data->rpc_status = task->tk_status; 3609 switch (task->tk_status) {
3490 if (data->rpc_status == 0) 3610 case -NFS4ERR_STALE_STATEID:
3611 case -NFS4ERR_EXPIRED:
3612 case 0:
3491 renew_lease(data->res.server, data->timestamp); 3613 renew_lease(data->res.server, data->timestamp);
3614 break;
3615 default:
3616 if (nfs4_async_handle_error(task, data->res.server, NULL) ==
3617 -EAGAIN) {
3618 nfs_restart_rpc(task, data->res.server->nfs_client);
3619 return;
3620 }
3621 }
3622 data->rpc_status = task->tk_status;
3492} 3623}
3493 3624
3494static void nfs4_delegreturn_release(void *calldata) 3625static void nfs4_delegreturn_release(void *calldata)
@@ -3741,11 +3872,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3741 break; 3872 break;
3742 default: 3873 default:
3743 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3874 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3744 nfs4_restart_rpc(task, 3875 nfs_restart_rpc(task,
3745 calldata->server->nfs_client); 3876 calldata->server->nfs_client);
3746 } 3877 }
3747 nfs4_sequence_free_slot(calldata->server->nfs_client,
3748 &calldata->res.seq_res);
3749} 3878}
3750 3879
3751static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3880static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3921,14 +4050,20 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3921 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 4050 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3922} 4051}
3923 4052
4053static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
4054{
4055 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4056 nfs4_lock_prepare(task, calldata);
4057}
4058
3924static void nfs4_lock_done(struct rpc_task *task, void *calldata) 4059static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3925{ 4060{
3926 struct nfs4_lockdata *data = calldata; 4061 struct nfs4_lockdata *data = calldata;
3927 4062
3928 dprintk("%s: begin!\n", __func__); 4063 dprintk("%s: begin!\n", __func__);
3929 4064
3930 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res, 4065 nfs4_sequence_done(data->server, &data->res.seq_res,
3931 task->tk_status); 4066 task->tk_status);
3932 4067
3933 data->rpc_status = task->tk_status; 4068 data->rpc_status = task->tk_status;
3934 if (RPC_ASSASSINATED(task)) 4069 if (RPC_ASSASSINATED(task))
@@ -3976,7 +4111,35 @@ static const struct rpc_call_ops nfs4_lock_ops = {
3976 .rpc_release = nfs4_lock_release, 4111 .rpc_release = nfs4_lock_release,
3977}; 4112};
3978 4113
3979static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) 4114static const struct rpc_call_ops nfs4_recover_lock_ops = {
4115 .rpc_call_prepare = nfs4_recover_lock_prepare,
4116 .rpc_call_done = nfs4_lock_done,
4117 .rpc_release = nfs4_lock_release,
4118};
4119
4120static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error)
4121{
4122 struct nfs_client *clp = server->nfs_client;
4123 struct nfs4_state *state = lsp->ls_state;
4124
4125 switch (error) {
4126 case -NFS4ERR_ADMIN_REVOKED:
4127 case -NFS4ERR_BAD_STATEID:
4128 case -NFS4ERR_EXPIRED:
4129 if (new_lock_owner != 0 ||
4130 (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
4131 nfs4_state_mark_reclaim_nograce(clp, state);
4132 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
4133 break;
4134 case -NFS4ERR_STALE_STATEID:
4135 if (new_lock_owner != 0 ||
4136 (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
4137 nfs4_state_mark_reclaim_reboot(clp, state);
4138 lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
4139 };
4140}
4141
4142static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
3980{ 4143{
3981 struct nfs4_lockdata *data; 4144 struct nfs4_lockdata *data;
3982 struct rpc_task *task; 4145 struct rpc_task *task;
@@ -4000,8 +4163,11 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4000 return -ENOMEM; 4163 return -ENOMEM;
4001 if (IS_SETLKW(cmd)) 4164 if (IS_SETLKW(cmd))
4002 data->arg.block = 1; 4165 data->arg.block = 1;
4003 if (reclaim != 0) 4166 if (recovery_type > NFS_LOCK_NEW) {
4004 data->arg.reclaim = 1; 4167 if (recovery_type == NFS_LOCK_RECLAIM)
4168 data->arg.reclaim = NFS_LOCK_RECLAIM;
4169 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4170 }
4005 msg.rpc_argp = &data->arg, 4171 msg.rpc_argp = &data->arg,
4006 msg.rpc_resp = &data->res, 4172 msg.rpc_resp = &data->res,
4007 task_setup_data.callback_data = data; 4173 task_setup_data.callback_data = data;
@@ -4011,6 +4177,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4011 ret = nfs4_wait_for_completion_rpc_task(task); 4177 ret = nfs4_wait_for_completion_rpc_task(task);
4012 if (ret == 0) { 4178 if (ret == 0) {
4013 ret = data->rpc_status; 4179 ret = data->rpc_status;
4180 if (ret)
4181 nfs4_handle_setlk_error(data->server, data->lsp,
4182 data->arg.new_lock_owner, ret);
4014 } else 4183 } else
4015 data->cancelled = 1; 4184 data->cancelled = 1;
4016 rpc_put_task(task); 4185 rpc_put_task(task);
@@ -4028,8 +4197,8 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4028 /* Cache the lock if possible... */ 4197 /* Cache the lock if possible... */
4029 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4198 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4030 return 0; 4199 return 0;
4031 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 4200 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4032 if (err != -NFS4ERR_DELAY) 4201 if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED)
4033 break; 4202 break;
4034 nfs4_handle_exception(server, err, &exception); 4203 nfs4_handle_exception(server, err, &exception);
4035 } while (exception.retry); 4204 } while (exception.retry);
@@ -4048,11 +4217,18 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4048 do { 4217 do {
4049 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4218 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4050 return 0; 4219 return 0;
4051 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 4220 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
4052 if (err != -NFS4ERR_DELAY) 4221 switch (err) {
4053 break; 4222 default:
4054 nfs4_handle_exception(server, err, &exception); 4223 goto out;
4224 case -NFS4ERR_GRACE:
4225 case -NFS4ERR_DELAY:
4226 case -EKEYEXPIRED:
4227 nfs4_handle_exception(server, err, &exception);
4228 err = 0;
4229 }
4055 } while (exception.retry); 4230 } while (exception.retry);
4231out:
4056 return err; 4232 return err;
4057} 4233}
4058 4234
@@ -4060,8 +4236,11 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
4060{ 4236{
4061 struct nfs_inode *nfsi = NFS_I(state->inode); 4237 struct nfs_inode *nfsi = NFS_I(state->inode);
4062 unsigned char fl_flags = request->fl_flags; 4238 unsigned char fl_flags = request->fl_flags;
4063 int status; 4239 int status = -ENOLCK;
4064 4240
4241 if ((fl_flags & FL_POSIX) &&
4242 !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
4243 goto out;
4065 /* Is this a delegated open? */ 4244 /* Is this a delegated open? */
4066 status = nfs4_set_lock_state(state, request); 4245 status = nfs4_set_lock_state(state, request);
4067 if (status != 0) 4246 if (status != 0)
@@ -4078,7 +4257,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
4078 status = do_vfs_lock(request->fl_file, request); 4257 status = do_vfs_lock(request->fl_file, request);
4079 goto out_unlock; 4258 goto out_unlock;
4080 } 4259 }
4081 status = _nfs4_do_setlk(state, cmd, request, 0); 4260 status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
4082 if (status != 0) 4261 if (status != 0)
4083 goto out_unlock; 4262 goto out_unlock;
4084 /* Note: we always want to sleep here! */ 4263 /* Note: we always want to sleep here! */
@@ -4161,7 +4340,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4161 if (err != 0) 4340 if (err != 0)
4162 goto out; 4341 goto out;
4163 do { 4342 do {
4164 err = _nfs4_do_setlk(state, F_SETLK, fl, 0); 4343 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
4165 switch (err) { 4344 switch (err) {
4166 default: 4345 default:
4167 printk(KERN_ERR "%s: unhandled error %d.\n", 4346 printk(KERN_ERR "%s: unhandled error %d.\n",
@@ -4172,6 +4351,11 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4172 case -NFS4ERR_EXPIRED: 4351 case -NFS4ERR_EXPIRED:
4173 case -NFS4ERR_STALE_CLIENTID: 4352 case -NFS4ERR_STALE_CLIENTID:
4174 case -NFS4ERR_STALE_STATEID: 4353 case -NFS4ERR_STALE_STATEID:
4354 case -NFS4ERR_BADSESSION:
4355 case -NFS4ERR_BADSLOT:
4356 case -NFS4ERR_BAD_HIGH_SLOT:
4357 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4358 case -NFS4ERR_DEADSESSION:
4175 nfs4_schedule_state_recovery(server->nfs_client); 4359 nfs4_schedule_state_recovery(server->nfs_client);
4176 goto out; 4360 goto out;
4177 case -ERESTARTSYS: 4361 case -ERESTARTSYS:
@@ -4191,6 +4375,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4191 err = 0; 4375 err = 0;
4192 goto out; 4376 goto out;
4193 case -NFS4ERR_DELAY: 4377 case -NFS4ERR_DELAY:
4378 case -EKEYEXPIRED:
4194 break; 4379 break;
4195 } 4380 }
4196 err = nfs4_handle_exception(server, err, &exception); 4381 err = nfs4_handle_exception(server, err, &exception);
@@ -4296,7 +4481,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4296 * NFS4ERR_BADSESSION in the sequence operation, and will therefore 4481 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4297 * be in some phase of session reset. 4482 * be in some phase of session reset.
4298 */ 4483 */
4299static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 4484int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4300{ 4485{
4301 nfs4_verifier verifier; 4486 nfs4_verifier verifier;
4302 struct nfs41_exchange_id_args args = { 4487 struct nfs41_exchange_id_args args = {
@@ -4318,6 +4503,9 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4318 dprintk("--> %s\n", __func__); 4503 dprintk("--> %s\n", __func__);
4319 BUG_ON(clp == NULL); 4504 BUG_ON(clp == NULL);
4320 4505
4506 /* Remove server-only flags */
4507 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4508
4321 p = (u32 *)verifier.data; 4509 p = (u32 *)verifier.data;
4322 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4510 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4323 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4511 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4333,7 +4521,7 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4333 4521
4334 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); 4522 status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
4335 4523
4336 if (status != NFS4ERR_CLID_INUSE) 4524 if (status != -NFS4ERR_CLID_INUSE)
4337 break; 4525 break;
4338 4526
4339 if (signalled()) 4527 if (signalled())
@@ -4361,11 +4549,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4361 (struct nfs4_get_lease_time_data *)calldata; 4549 (struct nfs4_get_lease_time_data *)calldata;
4362 4550
4363 dprintk("--> %s\n", __func__); 4551 dprintk("--> %s\n", __func__);
4552 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4364 /* just setup sequence, do not trigger session recovery 4553 /* just setup sequence, do not trigger session recovery
4365 since we're invoked within one */ 4554 since we're invoked within one */
4366 ret = nfs41_setup_sequence(data->clp->cl_session, 4555 ret = nfs41_setup_sequence(data->clp->cl_session,
4367 &data->args->la_seq_args, 4556 &data->args->la_seq_args,
4368 &data->res->lr_seq_res, 0, task); 4557 &data->res->lr_seq_res, 0, task);
4369 4558
4370 BUG_ON(ret == -EAGAIN); 4559 BUG_ON(ret == -EAGAIN);
4371 rpc_call_start(task); 4560 rpc_call_start(task);
@@ -4386,13 +4575,13 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4386 switch (task->tk_status) { 4575 switch (task->tk_status) {
4387 case -NFS4ERR_DELAY: 4576 case -NFS4ERR_DELAY:
4388 case -NFS4ERR_GRACE: 4577 case -NFS4ERR_GRACE:
4578 case -EKEYEXPIRED:
4389 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4579 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4390 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4580 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4391 task->tk_status = 0; 4581 task->tk_status = 0;
4392 nfs4_restart_rpc(task, data->clp); 4582 nfs_restart_rpc(task, data->clp);
4393 return; 4583 return;
4394 } 4584 }
4395 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4396 dprintk("<-- %s\n", __func__); 4585 dprintk("<-- %s\n", __func__);
4397} 4586}
4398 4587
@@ -4444,28 +4633,33 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
4444/* 4633/*
4445 * Reset a slot table 4634 * Reset a slot table
4446 */ 4635 */
4447static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots, 4636static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
4448 int old_max_slots, int ivalue) 4637 int ivalue)
4449{ 4638{
4639 struct nfs4_slot *new = NULL;
4450 int i; 4640 int i;
4451 int ret = 0; 4641 int ret = 0;
4452 4642
4453 dprintk("--> %s: max_reqs=%u, tbl %p\n", __func__, max_slots, tbl); 4643 dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
4644 max_reqs, tbl->max_slots);
4454 4645
4455 /* 4646 /* Does the newly negotiated max_reqs match the existing slot table? */
4456 * Until we have dynamic slot table adjustment, insist 4647 if (max_reqs != tbl->max_slots) {
4457 * upon the same slot table size 4648 ret = -ENOMEM;
4458 */ 4649 new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
4459 if (max_slots != old_max_slots) { 4650 GFP_KERNEL);
4460 dprintk("%s reset slot table does't match old\n", 4651 if (!new)
4461 __func__); 4652 goto out;
4462 ret = -EINVAL; /*XXX NFS4ERR_REQ_TOO_BIG ? */ 4653 ret = 0;
4463 goto out; 4654 kfree(tbl->slots);
4464 } 4655 }
4465 spin_lock(&tbl->slot_tbl_lock); 4656 spin_lock(&tbl->slot_tbl_lock);
4466 for (i = 0; i < max_slots; ++i) 4657 if (new) {
4658 tbl->slots = new;
4659 tbl->max_slots = max_reqs;
4660 }
4661 for (i = 0; i < tbl->max_slots; ++i)
4467 tbl->slots[i].seq_nr = ivalue; 4662 tbl->slots[i].seq_nr = ivalue;
4468 tbl->highest_used_slotid = -1;
4469 spin_unlock(&tbl->slot_tbl_lock); 4663 spin_unlock(&tbl->slot_tbl_lock);
4470 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 4664 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4471 tbl, tbl->slots, tbl->max_slots); 4665 tbl, tbl->slots, tbl->max_slots);
@@ -4482,16 +4676,12 @@ static int nfs4_reset_slot_tables(struct nfs4_session *session)
4482 int status; 4676 int status;
4483 4677
4484 status = nfs4_reset_slot_table(&session->fc_slot_table, 4678 status = nfs4_reset_slot_table(&session->fc_slot_table,
4485 session->fc_attrs.max_reqs, 4679 session->fc_attrs.max_reqs, 1);
4486 session->fc_slot_table.max_slots,
4487 1);
4488 if (status) 4680 if (status)
4489 return status; 4681 return status;
4490 4682
4491 status = nfs4_reset_slot_table(&session->bc_slot_table, 4683 status = nfs4_reset_slot_table(&session->bc_slot_table,
4492 session->bc_attrs.max_reqs, 4684 session->bc_attrs.max_reqs, 0);
4493 session->bc_slot_table.max_slots,
4494 0);
4495 return status; 4685 return status;
4496} 4686}
4497 4687
@@ -4515,7 +4705,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4515static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, 4705static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4516 int max_slots, int ivalue) 4706 int max_slots, int ivalue)
4517{ 4707{
4518 int i;
4519 struct nfs4_slot *slot; 4708 struct nfs4_slot *slot;
4520 int ret = -ENOMEM; 4709 int ret = -ENOMEM;
4521 4710
@@ -4526,18 +4715,9 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4526 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); 4715 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4527 if (!slot) 4716 if (!slot)
4528 goto out; 4717 goto out;
4529 for (i = 0; i < max_slots; ++i)
4530 slot[i].seq_nr = ivalue;
4531 ret = 0; 4718 ret = 0;
4532 4719
4533 spin_lock(&tbl->slot_tbl_lock); 4720 spin_lock(&tbl->slot_tbl_lock);
4534 if (tbl->slots != NULL) {
4535 spin_unlock(&tbl->slot_tbl_lock);
4536 dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
4537 __func__, tbl, tbl->slots);
4538 WARN_ON(1);
4539 goto out_free;
4540 }
4541 tbl->max_slots = max_slots; 4721 tbl->max_slots = max_slots;
4542 tbl->slots = slot; 4722 tbl->slots = slot;
4543 tbl->highest_used_slotid = -1; /* no slot is currently used */ 4723 tbl->highest_used_slotid = -1; /* no slot is currently used */
@@ -4547,10 +4727,6 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4547out: 4727out:
4548 dprintk("<-- %s: return %d\n", __func__, ret); 4728 dprintk("<-- %s: return %d\n", __func__, ret);
4549 return ret; 4729 return ret;
4550
4551out_free:
4552 kfree(slot);
4553 goto out;
4554} 4730}
4555 4731
4556/* 4732/*
@@ -4558,17 +4734,24 @@ out_free:
4558 */ 4734 */
4559static int nfs4_init_slot_tables(struct nfs4_session *session) 4735static int nfs4_init_slot_tables(struct nfs4_session *session)
4560{ 4736{
4561 int status; 4737 struct nfs4_slot_table *tbl;
4738 int status = 0;
4562 4739
4563 status = nfs4_init_slot_table(&session->fc_slot_table, 4740 tbl = &session->fc_slot_table;
4564 session->fc_attrs.max_reqs, 1); 4741 if (tbl->slots == NULL) {
4565 if (status) 4742 status = nfs4_init_slot_table(tbl,
4566 return status; 4743 session->fc_attrs.max_reqs, 1);
4744 if (status)
4745 return status;
4746 }
4567 4747
4568 status = nfs4_init_slot_table(&session->bc_slot_table, 4748 tbl = &session->bc_slot_table;
4569 session->bc_attrs.max_reqs, 0); 4749 if (tbl->slots == NULL) {
4570 if (status) 4750 status = nfs4_init_slot_table(tbl,
4571 nfs4_destroy_slot_tables(session); 4751 session->bc_attrs.max_reqs, 0);
4752 if (status)
4753 nfs4_destroy_slot_tables(session);
4754 }
4572 4755
4573 return status; 4756 return status;
4574} 4757}
@@ -4582,7 +4765,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4582 if (!session) 4765 if (!session)
4583 return NULL; 4766 return NULL;
4584 4767
4585 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4586 /* 4768 /*
4587 * The create session reply races with the server back 4769 * The create session reply races with the server back
4588 * channel probe. Mark the client NFS_CS_SESSION_INITING 4770 * channel probe. Mark the client NFS_CS_SESSION_INITING
@@ -4590,12 +4772,15 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4590 * nfs_client struct 4772 * nfs_client struct
4591 */ 4773 */
4592 clp->cl_cons_state = NFS_CS_SESSION_INITING; 4774 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4775 init_completion(&session->complete);
4593 4776
4594 tbl = &session->fc_slot_table; 4777 tbl = &session->fc_slot_table;
4778 tbl->highest_used_slotid = -1;
4595 spin_lock_init(&tbl->slot_tbl_lock); 4779 spin_lock_init(&tbl->slot_tbl_lock);
4596 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4780 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4597 4781
4598 tbl = &session->bc_slot_table; 4782 tbl = &session->bc_slot_table;
4783 tbl->highest_used_slotid = -1;
4599 spin_lock_init(&tbl->slot_tbl_lock); 4784 spin_lock_init(&tbl->slot_tbl_lock);
4600 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); 4785 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4601 4786
@@ -4637,16 +4822,14 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
4637 args->fc_attrs.headerpadsz = 0; 4822 args->fc_attrs.headerpadsz = 0;
4638 args->fc_attrs.max_rqst_sz = mxrqst_sz; 4823 args->fc_attrs.max_rqst_sz = mxrqst_sz;
4639 args->fc_attrs.max_resp_sz = mxresp_sz; 4824 args->fc_attrs.max_resp_sz = mxresp_sz;
4640 args->fc_attrs.max_resp_sz_cached = mxresp_sz;
4641 args->fc_attrs.max_ops = NFS4_MAX_OPS; 4825 args->fc_attrs.max_ops = NFS4_MAX_OPS;
4642 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs; 4826 args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
4643 4827
4644 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u " 4828 dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
4645 "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n", 4829 "max_ops=%u max_reqs=%u\n",
4646 __func__, 4830 __func__,
4647 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz, 4831 args->fc_attrs.max_rqst_sz, args->fc_attrs.max_resp_sz,
4648 args->fc_attrs.max_resp_sz_cached, args->fc_attrs.max_ops, 4832 args->fc_attrs.max_ops, args->fc_attrs.max_reqs);
4649 args->fc_attrs.max_reqs);
4650 4833
4651 /* Back channel attributes */ 4834 /* Back channel attributes */
4652 args->bc_attrs.headerpadsz = 0; 4835 args->bc_attrs.headerpadsz = 0;
@@ -4747,11 +4930,10 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
4747 * It is the responsibility of the caller to verify the session is 4930 * It is the responsibility of the caller to verify the session is
4748 * expired before calling this routine. 4931 * expired before calling this routine.
4749 */ 4932 */
4750int nfs4_proc_create_session(struct nfs_client *clp, int reset) 4933int nfs4_proc_create_session(struct nfs_client *clp)
4751{ 4934{
4752 int status; 4935 int status;
4753 unsigned *ptr; 4936 unsigned *ptr;
4754 struct nfs_fsinfo fsinfo;
4755 struct nfs4_session *session = clp->cl_session; 4937 struct nfs4_session *session = clp->cl_session;
4756 4938
4757 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 4939 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
@@ -4760,35 +4942,19 @@ int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4760 if (status) 4942 if (status)
4761 goto out; 4943 goto out;
4762 4944
4763 /* Init or reset the fore channel */ 4945 /* Init and reset the fore channel */
4764 if (reset) 4946 status = nfs4_init_slot_tables(session);
4765 status = nfs4_reset_slot_tables(session); 4947 dprintk("slot table initialization returned %d\n", status);
4766 else 4948 if (status)
4767 status = nfs4_init_slot_tables(session); 4949 goto out;
4768 dprintk("fore channel slot table initialization returned %d\n", status); 4950 status = nfs4_reset_slot_tables(session);
4951 dprintk("slot table reset returned %d\n", status);
4769 if (status) 4952 if (status)
4770 goto out; 4953 goto out;
4771 4954
4772 ptr = (unsigned *)&session->sess_id.data[0]; 4955 ptr = (unsigned *)&session->sess_id.data[0];
4773 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__, 4956 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4774 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]); 4957 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]);
4775
4776 if (reset)
4777 /* Lease time is aleady set */
4778 goto out;
4779
4780 /* Get the lease time */
4781 status = nfs4_proc_get_lease_time(clp, &fsinfo);
4782 if (status == 0) {
4783 /* Update lease time and schedule renewal */
4784 spin_lock(&clp->cl_lock);
4785 clp->cl_lease_time = fsinfo.lease_time * HZ;
4786 clp->cl_last_renewal = jiffies;
4787 clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
4788 spin_unlock(&clp->cl_lock);
4789
4790 nfs4_schedule_state_renewal(clp);
4791 }
4792out: 4958out:
4793 dprintk("<-- %s\n", __func__); 4959 dprintk("<-- %s\n", __func__);
4794 return status; 4960 return status;
@@ -4827,13 +4993,24 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
4827int nfs4_init_session(struct nfs_server *server) 4993int nfs4_init_session(struct nfs_server *server)
4828{ 4994{
4829 struct nfs_client *clp = server->nfs_client; 4995 struct nfs_client *clp = server->nfs_client;
4996 struct nfs4_session *session;
4997 unsigned int rsize, wsize;
4830 int ret; 4998 int ret;
4831 4999
4832 if (!nfs4_has_session(clp)) 5000 if (!nfs4_has_session(clp))
4833 return 0; 5001 return 0;
4834 5002
4835 clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; 5003 rsize = server->rsize;
4836 clp->cl_session->fc_attrs.max_resp_sz = server->rsize; 5004 if (rsize == 0)
5005 rsize = NFS_MAX_FILE_IO_SIZE;
5006 wsize = server->wsize;
5007 if (wsize == 0)
5008 wsize = NFS_MAX_FILE_IO_SIZE;
5009
5010 session = clp->cl_session;
5011 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
5012 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
5013
4837 ret = nfs4_recover_expired_lease(server); 5014 ret = nfs4_recover_expired_lease(server);
4838 if (!ret) 5015 if (!ret)
4839 ret = nfs4_check_client_ready(clp); 5016 ret = nfs4_check_client_ready(clp);
@@ -4858,10 +5035,19 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4858 args.sa_cache_this = 0; 5035 args.sa_cache_this = 0;
4859 5036
4860 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args, 5037 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4861 &res, 0); 5038 &res, args.sa_cache_this, 1);
5039}
5040
5041static void nfs41_sequence_release(void *data)
5042{
5043 struct nfs_client *clp = (struct nfs_client *)data;
5044
5045 if (atomic_read(&clp->cl_count) > 1)
5046 nfs4_schedule_state_renewal(clp);
5047 nfs_put_client(clp);
4862} 5048}
4863 5049
4864void nfs41_sequence_call_done(struct rpc_task *task, void *data) 5050static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4865{ 5051{
4866 struct nfs_client *clp = (struct nfs_client *)data; 5052 struct nfs_client *clp = (struct nfs_client *)data;
4867 5053
@@ -4869,16 +5055,17 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4869 5055
4870 if (task->tk_status < 0) { 5056 if (task->tk_status < 0) {
4871 dprintk("%s ERROR %d\n", __func__, task->tk_status); 5057 dprintk("%s ERROR %d\n", __func__, task->tk_status);
5058 if (atomic_read(&clp->cl_count) == 1)
5059 goto out;
4872 5060
4873 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 5061 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4874 == -EAGAIN) { 5062 == -EAGAIN) {
4875 nfs4_restart_rpc(task, clp); 5063 nfs_restart_rpc(task, clp);
4876 return; 5064 return;
4877 } 5065 }
4878 } 5066 }
4879 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4880 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 5067 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4881 5068out:
4882 kfree(task->tk_msg.rpc_argp); 5069 kfree(task->tk_msg.rpc_argp);
4883 kfree(task->tk_msg.rpc_resp); 5070 kfree(task->tk_msg.rpc_resp);
4884 5071
@@ -4903,6 +5090,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
4903static const struct rpc_call_ops nfs41_sequence_ops = { 5090static const struct rpc_call_ops nfs41_sequence_ops = {
4904 .rpc_call_done = nfs41_sequence_call_done, 5091 .rpc_call_done = nfs41_sequence_call_done,
4905 .rpc_call_prepare = nfs41_sequence_prepare, 5092 .rpc_call_prepare = nfs41_sequence_prepare,
5093 .rpc_release = nfs41_sequence_release,
4906}; 5094};
4907 5095
4908static int nfs41_proc_async_sequence(struct nfs_client *clp, 5096static int nfs41_proc_async_sequence(struct nfs_client *clp,
@@ -4915,12 +5103,14 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4915 .rpc_cred = cred, 5103 .rpc_cred = cred,
4916 }; 5104 };
4917 5105
5106 if (!atomic_inc_not_zero(&clp->cl_count))
5107 return -EIO;
4918 args = kzalloc(sizeof(*args), GFP_KERNEL); 5108 args = kzalloc(sizeof(*args), GFP_KERNEL);
4919 if (!args)
4920 return -ENOMEM;
4921 res = kzalloc(sizeof(*res), GFP_KERNEL); 5109 res = kzalloc(sizeof(*res), GFP_KERNEL);
4922 if (!res) { 5110 if (!args || !res) {
4923 kfree(args); 5111 kfree(args);
5112 kfree(res);
5113 nfs_put_client(clp);
4924 return -ENOMEM; 5114 return -ENOMEM;
4925 } 5115 }
4926 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 5116 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
@@ -4931,6 +5121,113 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4931 &nfs41_sequence_ops, (void *)clp); 5121 &nfs41_sequence_ops, (void *)clp);
4932} 5122}
4933 5123
5124struct nfs4_reclaim_complete_data {
5125 struct nfs_client *clp;
5126 struct nfs41_reclaim_complete_args arg;
5127 struct nfs41_reclaim_complete_res res;
5128};
5129
5130static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
5131{
5132 struct nfs4_reclaim_complete_data *calldata = data;
5133
5134 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
5135 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
5136 &calldata->res.seq_res, 0, task))
5137 return;
5138
5139 rpc_call_start(task);
5140}
5141
5142static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
5143{
5144 struct nfs4_reclaim_complete_data *calldata = data;
5145 struct nfs_client *clp = calldata->clp;
5146 struct nfs4_sequence_res *res = &calldata->res.seq_res;
5147
5148 dprintk("--> %s\n", __func__);
5149 nfs41_sequence_done(clp, res, task->tk_status);
5150 switch (task->tk_status) {
5151 case 0:
5152 case -NFS4ERR_COMPLETE_ALREADY:
5153 break;
5154 case -NFS4ERR_BADSESSION:
5155 case -NFS4ERR_DEADSESSION:
5156 /*
5157 * Handle the session error, but do not retry the operation, as
5158 * we have no way of telling whether the clientid had to be
5159 * reset before we got our reply. If reset, a new wave of
5160 * reclaim operations will follow, containing their own reclaim
5161 * complete. We don't want our retry to get on the way of
5162 * recovery by incorrectly indicating to the server that we're
5163 * done reclaiming state since the process had to be restarted.
5164 */
5165 _nfs4_async_handle_error(task, NULL, clp, NULL);
5166 break;
5167 default:
5168 if (_nfs4_async_handle_error(
5169 task, NULL, clp, NULL) == -EAGAIN) {
5170 rpc_restart_call_prepare(task);
5171 return;
5172 }
5173 }
5174
5175 dprintk("<-- %s\n", __func__);
5176}
5177
5178static void nfs4_free_reclaim_complete_data(void *data)
5179{
5180 struct nfs4_reclaim_complete_data *calldata = data;
5181
5182 kfree(calldata);
5183}
5184
5185static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
5186 .rpc_call_prepare = nfs4_reclaim_complete_prepare,
5187 .rpc_call_done = nfs4_reclaim_complete_done,
5188 .rpc_release = nfs4_free_reclaim_complete_data,
5189};
5190
5191/*
5192 * Issue a global reclaim complete.
5193 */
5194static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5195{
5196 struct nfs4_reclaim_complete_data *calldata;
5197 struct rpc_task *task;
5198 struct rpc_message msg = {
5199 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
5200 };
5201 struct rpc_task_setup task_setup_data = {
5202 .rpc_client = clp->cl_rpcclient,
5203 .rpc_message = &msg,
5204 .callback_ops = &nfs4_reclaim_complete_call_ops,
5205 .flags = RPC_TASK_ASYNC,
5206 };
5207 int status = -ENOMEM;
5208
5209 dprintk("--> %s\n", __func__);
5210 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
5211 if (calldata == NULL)
5212 goto out;
5213 calldata->clp = clp;
5214 calldata->arg.one_fs = 0;
5215 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5216
5217 msg.rpc_argp = &calldata->arg;
5218 msg.rpc_resp = &calldata->res;
5219 task_setup_data.callback_data = calldata;
5220 task = rpc_run_task(&task_setup_data);
5221 if (IS_ERR(task)) {
5222 status = PTR_ERR(task);
5223 goto out;
5224 }
5225 rpc_put_task(task);
5226 return 0;
5227out:
5228 dprintk("<-- %s status=%d\n", __func__, status);
5229 return status;
5230}
4934#endif /* CONFIG_NFS_V4_1 */ 5231#endif /* CONFIG_NFS_V4_1 */
4935 5232
4936struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 5233struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -4948,8 +5245,9 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4948 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 5245 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4949 .recover_open = nfs4_open_reclaim, 5246 .recover_open = nfs4_open_reclaim,
4950 .recover_lock = nfs4_lock_reclaim, 5247 .recover_lock = nfs4_lock_reclaim,
4951 .establish_clid = nfs4_proc_exchange_id, 5248 .establish_clid = nfs41_init_clientid,
4952 .get_clid_cred = nfs4_get_exchange_id_cred, 5249 .get_clid_cred = nfs4_get_exchange_id_cred,
5250 .reclaim_complete = nfs41_proc_reclaim_complete,
4953}; 5251};
4954#endif /* CONFIG_NFS_V4_1 */ 5252#endif /* CONFIG_NFS_V4_1 */
4955 5253
@@ -4968,7 +5266,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
4968 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 5266 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4969 .recover_open = nfs4_open_expired, 5267 .recover_open = nfs4_open_expired,
4970 .recover_lock = nfs4_lock_expired, 5268 .recover_lock = nfs4_lock_expired,
4971 .establish_clid = nfs4_proc_exchange_id, 5269 .establish_clid = nfs41_init_clientid,
4972 .get_clid_cred = nfs4_get_exchange_id_cred, 5270 .get_clid_cred = nfs4_get_exchange_id_cred,
4973}; 5271};
4974#endif /* CONFIG_NFS_V4_1 */ 5272#endif /* CONFIG_NFS_V4_1 */