aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c633
1 files changed, 427 insertions, 206 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 741a562177fc..198d51d17c13 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -64,6 +64,7 @@
64 64
65struct nfs4_opendata; 65struct nfs4_opendata;
66static int _nfs4_proc_open(struct nfs4_opendata *data); 66static int _nfs4_proc_open(struct nfs4_opendata *data);
67static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
67static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 68static 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 *); 69static 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); 70static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -270,11 +271,18 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
270 case -NFS4ERR_SEQ_MISORDERED: 271 case -NFS4ERR_SEQ_MISORDERED:
271 dprintk("%s ERROR: %d Reset session\n", __func__, 272 dprintk("%s ERROR: %d Reset session\n", __func__,
272 errorcode); 273 errorcode);
273 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 274 nfs4_schedule_state_recovery(clp);
274 exception->retry = 1; 275 exception->retry = 1;
275 /* FALLTHROUGH */ 276 break;
276#endif /* !defined(CONFIG_NFS_V4_1) */ 277#endif /* !defined(CONFIG_NFS_V4_1) */
277 case -NFS4ERR_FILE_OPEN: 278 case -NFS4ERR_FILE_OPEN:
279 if (exception->timeout > HZ) {
280 /* We have retried a decent amount, time to
281 * fail
282 */
283 ret = -EBUSY;
284 break;
285 }
278 case -NFS4ERR_GRACE: 286 case -NFS4ERR_GRACE:
279 case -NFS4ERR_DELAY: 287 case -NFS4ERR_DELAY:
280 ret = nfs4_delay(server->client, &exception->timeout); 288 ret = nfs4_delay(server->client, &exception->timeout);
@@ -311,48 +319,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 319 * so we need to scan down from highest_used_slotid to 0 looking for the now
312 * highest slotid in use. 320 * highest slotid in use.
313 * If none found, highest_used_slotid is set to -1. 321 * If none found, highest_used_slotid is set to -1.
322 *
323 * Must be called while holding tbl->slot_tbl_lock
314 */ 324 */
315static void 325static void
316nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid) 326nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
317{ 327{
318 int slotid = free_slotid; 328 int slotid = free_slotid;
319 329
320 spin_lock(&tbl->slot_tbl_lock);
321 /* clear used bit in bitmap */ 330 /* clear used bit in bitmap */
322 __clear_bit(slotid, tbl->used_slots); 331 __clear_bit(slotid, tbl->used_slots);
323 332
324 /* update highest_used_slotid when it is freed */ 333 /* update highest_used_slotid when it is freed */
325 if (slotid == tbl->highest_used_slotid) { 334 if (slotid == tbl->highest_used_slotid) {
326 slotid = find_last_bit(tbl->used_slots, tbl->max_slots); 335 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
327 if (slotid >= 0 && slotid < tbl->max_slots) 336 if (slotid < tbl->max_slots)
328 tbl->highest_used_slotid = slotid; 337 tbl->highest_used_slotid = slotid;
329 else 338 else
330 tbl->highest_used_slotid = -1; 339 tbl->highest_used_slotid = -1;
331 } 340 }
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__, 341 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
335 free_slotid, tbl->highest_used_slotid); 342 free_slotid, tbl->highest_used_slotid);
336} 343}
337 344
338void nfs41_sequence_free_slot(const struct nfs_client *clp, 345/*
339 struct nfs4_sequence_res *res) 346 * Signal state manager thread if session is drained
347 */
348static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
340{ 349{
341 struct nfs4_slot_table *tbl; 350 struct rpc_task *task;
342 351
343 if (!nfs4_has_session(clp)) { 352 if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
344 dprintk("%s: No session\n", __func__); 353 task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
354 if (task)
355 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
345 return; 356 return;
346 } 357 }
358
359 if (ses->fc_slot_table.highest_used_slotid != -1)
360 return;
361
362 dprintk("%s COMPLETE: Session Drained\n", __func__);
363 complete(&ses->complete);
364}
365
366static void nfs41_sequence_free_slot(const struct nfs_client *clp,
367 struct nfs4_sequence_res *res)
368{
369 struct nfs4_slot_table *tbl;
370
347 tbl = &clp->cl_session->fc_slot_table; 371 tbl = &clp->cl_session->fc_slot_table;
348 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) { 372 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
349 dprintk("%s: No slot\n", __func__);
350 /* just wake up the next guy waiting since 373 /* just wake up the next guy waiting since
351 * we may have not consumed a slot after all */ 374 * we may have not consumed a slot after all */
352 rpc_wake_up_next(&tbl->slot_tbl_waitq); 375 dprintk("%s: No slot\n", __func__);
353 return; 376 return;
354 } 377 }
378
379 spin_lock(&tbl->slot_tbl_lock);
355 nfs4_free_slot(tbl, res->sr_slotid); 380 nfs4_free_slot(tbl, res->sr_slotid);
381 nfs41_check_drain_session_complete(clp->cl_session);
382 spin_unlock(&tbl->slot_tbl_lock);
356 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 383 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
357} 384}
358 385
@@ -377,10 +404,10 @@ static void nfs41_sequence_done(struct nfs_client *clp,
377 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) 404 if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
378 goto out; 405 goto out;
379 406
380 tbl = &clp->cl_session->fc_slot_table; 407 /* Check the SEQUENCE operation status */
381 slot = tbl->slots + res->sr_slotid;
382
383 if (res->sr_status == 0) { 408 if (res->sr_status == 0) {
409 tbl = &clp->cl_session->fc_slot_table;
410 slot = tbl->slots + res->sr_slotid;
384 /* Update the slot's sequence and clientid lease timer */ 411 /* Update the slot's sequence and clientid lease timer */
385 ++slot->seq_nr; 412 ++slot->seq_nr;
386 timestamp = res->sr_renewal_time; 413 timestamp = res->sr_renewal_time;
@@ -388,7 +415,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
388 if (time_before(clp->cl_last_renewal, timestamp)) 415 if (time_before(clp->cl_last_renewal, timestamp))
389 clp->cl_last_renewal = timestamp; 416 clp->cl_last_renewal = timestamp;
390 spin_unlock(&clp->cl_lock); 417 spin_unlock(&clp->cl_lock);
391 return; 418 /* Check sequence flags */
419 nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
392 } 420 }
393out: 421out:
394 /* The session may be reset by one of the error handlers. */ 422 /* The session may be reset by one of the error handlers. */
@@ -407,7 +435,7 @@ out:
407 * Note: must be called with under the slot_tbl_lock. 435 * Note: must be called with under the slot_tbl_lock.
408 */ 436 */
409static u8 437static u8
410nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) 438nfs4_find_slot(struct nfs4_slot_table *tbl)
411{ 439{
412 int slotid; 440 int slotid;
413 u8 ret_id = NFS4_MAX_SLOT_TABLE; 441 u8 ret_id = NFS4_MAX_SLOT_TABLE;
@@ -429,24 +457,6 @@ out:
429 return ret_id; 457 return ret_id;
430} 458}
431 459
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, 460static int nfs41_setup_sequence(struct nfs4_session *session,
451 struct nfs4_sequence_args *args, 461 struct nfs4_sequence_args *args,
452 struct nfs4_sequence_res *res, 462 struct nfs4_sequence_res *res,
@@ -455,7 +465,6 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
455{ 465{
456 struct nfs4_slot *slot; 466 struct nfs4_slot *slot;
457 struct nfs4_slot_table *tbl; 467 struct nfs4_slot_table *tbl;
458 int status = 0;
459 u8 slotid; 468 u8 slotid;
460 469
461 dprintk("--> %s\n", __func__); 470 dprintk("--> %s\n", __func__);
@@ -468,24 +477,27 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
468 tbl = &session->fc_slot_table; 477 tbl = &session->fc_slot_table;
469 478
470 spin_lock(&tbl->slot_tbl_lock); 479 spin_lock(&tbl->slot_tbl_lock);
471 if (test_bit(NFS4CLNT_SESSION_SETUP, &session->clp->cl_state)) { 480 if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state) &&
472 if (tbl->highest_used_slotid != -1) { 481 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
473 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 482 /*
474 spin_unlock(&tbl->slot_tbl_lock); 483 * The state manager will wait until the slot table is empty.
475 dprintk("<-- %s: Session reset: draining\n", __func__); 484 * Schedule the reset thread
476 return -EAGAIN; 485 */
477 } 486 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
487 spin_unlock(&tbl->slot_tbl_lock);
488 dprintk("%s Schedule Session Reset\n", __func__);
489 return -EAGAIN;
490 }
478 491
479 /* The slot table is empty; start the reset thread */ 492 if (!rpc_queue_empty(&tbl->slot_tbl_waitq) &&
480 dprintk("%s Session Reset\n", __func__); 493 !rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
494 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
481 spin_unlock(&tbl->slot_tbl_lock); 495 spin_unlock(&tbl->slot_tbl_lock);
482 status = nfs4_recover_session(session); 496 dprintk("%s enforce FIFO order\n", __func__);
483 if (status) 497 return -EAGAIN;
484 return status;
485 spin_lock(&tbl->slot_tbl_lock);
486 } 498 }
487 499
488 slotid = nfs4_find_slot(tbl, task); 500 slotid = nfs4_find_slot(tbl);
489 if (slotid == NFS4_MAX_SLOT_TABLE) { 501 if (slotid == NFS4_MAX_SLOT_TABLE) {
490 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL); 502 rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
491 spin_unlock(&tbl->slot_tbl_lock); 503 spin_unlock(&tbl->slot_tbl_lock);
@@ -494,6 +506,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
494 } 506 }
495 spin_unlock(&tbl->slot_tbl_lock); 507 spin_unlock(&tbl->slot_tbl_lock);
496 508
509 rpc_task_set_priority(task, RPC_PRIORITY_NORMAL);
497 slot = tbl->slots + slotid; 510 slot = tbl->slots + slotid;
498 args->sa_session = session; 511 args->sa_session = session;
499 args->sa_slotid = slotid; 512 args->sa_slotid = slotid;
@@ -527,7 +540,7 @@ int nfs4_setup_sequence(struct nfs_client *clp,
527 goto out; 540 goto out;
528 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply, 541 ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
529 task); 542 task);
530 if (ret != -EAGAIN) { 543 if (ret && ret != -EAGAIN) {
531 /* terminate rpc task */ 544 /* terminate rpc task */
532 task->tk_status = ret; 545 task->tk_status = ret;
533 task->tk_action = NULL; 546 task->tk_action = NULL;
@@ -556,12 +569,17 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
556 rpc_call_start(task); 569 rpc_call_start(task);
557} 570}
558 571
572static void nfs41_call_priv_sync_prepare(struct rpc_task *task, void *calldata)
573{
574 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
575 nfs41_call_sync_prepare(task, calldata);
576}
577
559static void nfs41_call_sync_done(struct rpc_task *task, void *calldata) 578static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
560{ 579{
561 struct nfs41_call_sync_data *data = calldata; 580 struct nfs41_call_sync_data *data = calldata;
562 581
563 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status); 582 nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
564 nfs41_sequence_free_slot(data->clp, data->seq_res);
565} 583}
566 584
567struct rpc_call_ops nfs41_call_sync_ops = { 585struct rpc_call_ops nfs41_call_sync_ops = {
@@ -569,12 +587,18 @@ struct rpc_call_ops nfs41_call_sync_ops = {
569 .rpc_call_done = nfs41_call_sync_done, 587 .rpc_call_done = nfs41_call_sync_done,
570}; 588};
571 589
590struct rpc_call_ops nfs41_call_priv_sync_ops = {
591 .rpc_call_prepare = nfs41_call_priv_sync_prepare,
592 .rpc_call_done = nfs41_call_sync_done,
593};
594
572static int nfs4_call_sync_sequence(struct nfs_client *clp, 595static int nfs4_call_sync_sequence(struct nfs_client *clp,
573 struct rpc_clnt *clnt, 596 struct rpc_clnt *clnt,
574 struct rpc_message *msg, 597 struct rpc_message *msg,
575 struct nfs4_sequence_args *args, 598 struct nfs4_sequence_args *args,
576 struct nfs4_sequence_res *res, 599 struct nfs4_sequence_res *res,
577 int cache_reply) 600 int cache_reply,
601 int privileged)
578{ 602{
579 int ret; 603 int ret;
580 struct rpc_task *task; 604 struct rpc_task *task;
@@ -592,6 +616,8 @@ static int nfs4_call_sync_sequence(struct nfs_client *clp,
592 }; 616 };
593 617
594 res->sr_slotid = NFS4_MAX_SLOT_TABLE; 618 res->sr_slotid = NFS4_MAX_SLOT_TABLE;
619 if (privileged)
620 task_setup.callback_ops = &nfs41_call_priv_sync_ops;
595 task = rpc_run_task(&task_setup); 621 task = rpc_run_task(&task_setup);
596 if (IS_ERR(task)) 622 if (IS_ERR(task))
597 ret = PTR_ERR(task); 623 ret = PTR_ERR(task);
@@ -609,7 +635,7 @@ int _nfs4_call_sync_session(struct nfs_server *server,
609 int cache_reply) 635 int cache_reply)
610{ 636{
611 return nfs4_call_sync_sequence(server->nfs_client, server->client, 637 return nfs4_call_sync_sequence(server->nfs_client, server->client,
612 msg, args, res, cache_reply); 638 msg, args, res, cache_reply, 0);
613} 639}
614 640
615#endif /* CONFIG_NFS_V4_1 */ 641#endif /* CONFIG_NFS_V4_1 */
@@ -637,15 +663,6 @@ static void nfs4_sequence_done(const struct nfs_server *server,
637#endif /* CONFIG_NFS_V4_1 */ 663#endif /* CONFIG_NFS_V4_1 */
638} 664}
639 665
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) 666static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
650{ 667{
651 struct nfs_inode *nfsi = NFS_I(dir); 668 struct nfs_inode *nfsi = NFS_I(dir);
@@ -720,9 +737,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
720 p->o_arg.bitmask = server->attr_bitmask; 737 p->o_arg.bitmask = server->attr_bitmask;
721 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; 738 p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
722 if (flags & O_EXCL) { 739 if (flags & O_EXCL) {
723 u32 *s = (u32 *) p->o_arg.u.verifier.data; 740 if (nfs4_has_persistent_session(server->nfs_client)) {
724 s[0] = jiffies; 741 /* GUARDED */
725 s[1] = current->pid; 742 p->o_arg.u.attrs = &p->attrs;
743 memcpy(&p->attrs, attrs, sizeof(p->attrs));
744 } else { /* EXCLUSIVE4_1 */
745 u32 *s = (u32 *) p->o_arg.u.verifier.data;
746 s[0] = jiffies;
747 s[1] = current->pid;
748 }
726 } else if (flags & O_CREAT) { 749 } else if (flags & O_CREAT) {
727 p->o_arg.u.attrs = &p->attrs; 750 p->o_arg.u.attrs = &p->attrs;
728 memcpy(&p->attrs, attrs, sizeof(p->attrs)); 751 memcpy(&p->attrs, attrs, sizeof(p->attrs));
@@ -776,13 +799,16 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
776 goto out; 799 goto out;
777 switch (mode & (FMODE_READ|FMODE_WRITE)) { 800 switch (mode & (FMODE_READ|FMODE_WRITE)) {
778 case FMODE_READ: 801 case FMODE_READ:
779 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; 802 ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
803 && state->n_rdonly != 0;
780 break; 804 break;
781 case FMODE_WRITE: 805 case FMODE_WRITE:
782 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; 806 ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0
807 && state->n_wronly != 0;
783 break; 808 break;
784 case FMODE_READ|FMODE_WRITE: 809 case FMODE_READ|FMODE_WRITE:
785 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; 810 ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0
811 && state->n_rdwr != 0;
786 } 812 }
787out: 813out:
788 return ret; 814 return ret;
@@ -1047,7 +1073,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, fmode_t fmod
1047 memset(&opendata->o_res, 0, sizeof(opendata->o_res)); 1073 memset(&opendata->o_res, 0, sizeof(opendata->o_res));
1048 memset(&opendata->c_res, 0, sizeof(opendata->c_res)); 1074 memset(&opendata->c_res, 0, sizeof(opendata->c_res));
1049 nfs4_init_opendata_res(opendata); 1075 nfs4_init_opendata_res(opendata);
1050 ret = _nfs4_proc_open(opendata); 1076 ret = _nfs4_recover_proc_open(opendata);
1051 if (ret != 0) 1077 if (ret != 0)
1052 return ret; 1078 return ret;
1053 newstate = nfs4_opendata_to_nfs4_state(opendata); 1079 newstate = nfs4_opendata_to_nfs4_state(opendata);
@@ -1183,6 +1209,14 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state
1183 case -ENOENT: 1209 case -ENOENT:
1184 case -ESTALE: 1210 case -ESTALE:
1185 goto out; 1211 goto out;
1212 case -NFS4ERR_BADSESSION:
1213 case -NFS4ERR_BADSLOT:
1214 case -NFS4ERR_BAD_HIGH_SLOT:
1215 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1216 case -NFS4ERR_DEADSESSION:
1217 nfs4_schedule_state_recovery(
1218 server->nfs_client);
1219 goto out;
1186 case -NFS4ERR_STALE_CLIENTID: 1220 case -NFS4ERR_STALE_CLIENTID:
1187 case -NFS4ERR_STALE_STATEID: 1221 case -NFS4ERR_STALE_STATEID:
1188 case -NFS4ERR_EXPIRED: 1222 case -NFS4ERR_EXPIRED:
@@ -1330,14 +1364,20 @@ out_no_action:
1330 1364
1331} 1365}
1332 1366
1367static void nfs4_recover_open_prepare(struct rpc_task *task, void *calldata)
1368{
1369 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
1370 nfs4_open_prepare(task, calldata);
1371}
1372
1333static void nfs4_open_done(struct rpc_task *task, void *calldata) 1373static void nfs4_open_done(struct rpc_task *task, void *calldata)
1334{ 1374{
1335 struct nfs4_opendata *data = calldata; 1375 struct nfs4_opendata *data = calldata;
1336 1376
1337 data->rpc_status = task->tk_status; 1377 data->rpc_status = task->tk_status;
1338 1378
1339 nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res, 1379 nfs4_sequence_done(data->o_arg.server, &data->o_res.seq_res,
1340 task->tk_status); 1380 task->tk_status);
1341 1381
1342 if (RPC_ASSASSINATED(task)) 1382 if (RPC_ASSASSINATED(task))
1343 return; 1383 return;
@@ -1388,10 +1428,13 @@ static const struct rpc_call_ops nfs4_open_ops = {
1388 .rpc_release = nfs4_open_release, 1428 .rpc_release = nfs4_open_release,
1389}; 1429};
1390 1430
1391/* 1431static const struct rpc_call_ops nfs4_recover_open_ops = {
1392 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata 1432 .rpc_call_prepare = nfs4_recover_open_prepare,
1393 */ 1433 .rpc_call_done = nfs4_open_done,
1394static int _nfs4_proc_open(struct nfs4_opendata *data) 1434 .rpc_release = nfs4_open_release,
1435};
1436
1437static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
1395{ 1438{
1396 struct inode *dir = data->dir->d_inode; 1439 struct inode *dir = data->dir->d_inode;
1397 struct nfs_server *server = NFS_SERVER(dir); 1440 struct nfs_server *server = NFS_SERVER(dir);
@@ -1418,21 +1461,57 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
1418 data->rpc_done = 0; 1461 data->rpc_done = 0;
1419 data->rpc_status = 0; 1462 data->rpc_status = 0;
1420 data->cancelled = 0; 1463 data->cancelled = 0;
1464 if (isrecover)
1465 task_setup_data.callback_ops = &nfs4_recover_open_ops;
1421 task = rpc_run_task(&task_setup_data); 1466 task = rpc_run_task(&task_setup_data);
1422 if (IS_ERR(task)) 1467 if (IS_ERR(task))
1423 return PTR_ERR(task); 1468 return PTR_ERR(task);
1424 status = nfs4_wait_for_completion_rpc_task(task); 1469 status = nfs4_wait_for_completion_rpc_task(task);
1425 if (status != 0) { 1470 if (status != 0) {
1426 data->cancelled = 1; 1471 data->cancelled = 1;
1427 smp_wmb(); 1472 smp_wmb();
1428 } else 1473 } else
1429 status = data->rpc_status; 1474 status = data->rpc_status;
1430 rpc_put_task(task); 1475 rpc_put_task(task);
1476
1477 return status;
1478}
1479
1480static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
1481{
1482 struct inode *dir = data->dir->d_inode;
1483 struct nfs_openres *o_res = &data->o_res;
1484 int status;
1485
1486 status = nfs4_run_open_task(data, 1);
1431 if (status != 0 || !data->rpc_done) 1487 if (status != 0 || !data->rpc_done)
1432 return status; 1488 return status;
1433 1489
1434 if (o_res->fh.size == 0) 1490 nfs_refresh_inode(dir, o_res->dir_attr);
1435 _nfs4_proc_lookup(dir, o_arg->name, &o_res->fh, o_res->f_attr); 1491
1492 if (o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
1493 status = _nfs4_proc_open_confirm(data);
1494 if (status != 0)
1495 return status;
1496 }
1497
1498 return status;
1499}
1500
1501/*
1502 * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
1503 */
1504static int _nfs4_proc_open(struct nfs4_opendata *data)
1505{
1506 struct inode *dir = data->dir->d_inode;
1507 struct nfs_server *server = NFS_SERVER(dir);
1508 struct nfs_openargs *o_arg = &data->o_arg;
1509 struct nfs_openres *o_res = &data->o_res;
1510 int status;
1511
1512 status = nfs4_run_open_task(data, 0);
1513 if (status != 0 || !data->rpc_done)
1514 return status;
1436 1515
1437 if (o_arg->open_flags & O_CREAT) { 1516 if (o_arg->open_flags & O_CREAT) {
1438 update_changeattr(dir, &o_res->cinfo); 1517 update_changeattr(dir, &o_res->cinfo);
@@ -1488,7 +1567,7 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
1488 return ret; 1567 return ret;
1489} 1568}
1490 1569
1491static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) 1570static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
1492{ 1571{
1493 struct nfs_server *server = NFS_SERVER(state->inode); 1572 struct nfs_server *server = NFS_SERVER(state->inode);
1494 struct nfs4_exception exception = { }; 1573 struct nfs4_exception exception = { };
@@ -1496,10 +1575,16 @@ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4
1496 1575
1497 do { 1576 do {
1498 err = _nfs4_open_expired(ctx, state); 1577 err = _nfs4_open_expired(ctx, state);
1499 if (err != -NFS4ERR_DELAY) 1578 switch (err) {
1500 break; 1579 default:
1501 nfs4_handle_exception(server, err, &exception); 1580 goto out;
1581 case -NFS4ERR_GRACE:
1582 case -NFS4ERR_DELAY:
1583 nfs4_handle_exception(server, err, &exception);
1584 err = 0;
1585 }
1502 } while (exception.retry); 1586 } while (exception.retry);
1587out:
1503 return err; 1588 return err;
1504} 1589}
1505 1590
@@ -1712,6 +1797,18 @@ static void nfs4_free_closedata(void *data)
1712 kfree(calldata); 1797 kfree(calldata);
1713} 1798}
1714 1799
1800static void nfs4_close_clear_stateid_flags(struct nfs4_state *state,
1801 fmode_t fmode)
1802{
1803 spin_lock(&state->owner->so_lock);
1804 if (!(fmode & FMODE_READ))
1805 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1806 if (!(fmode & FMODE_WRITE))
1807 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1808 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1809 spin_unlock(&state->owner->so_lock);
1810}
1811
1715static void nfs4_close_done(struct rpc_task *task, void *data) 1812static void nfs4_close_done(struct rpc_task *task, void *data)
1716{ 1813{
1717 struct nfs4_closedata *calldata = data; 1814 struct nfs4_closedata *calldata = data;
@@ -1728,6 +1825,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1728 case 0: 1825 case 0:
1729 nfs_set_open_stateid(state, &calldata->res.stateid, 0); 1826 nfs_set_open_stateid(state, &calldata->res.stateid, 0);
1730 renew_lease(server, calldata->timestamp); 1827 renew_lease(server, calldata->timestamp);
1828 nfs4_close_clear_stateid_flags(state,
1829 calldata->arg.fmode);
1731 break; 1830 break;
1732 case -NFS4ERR_STALE_STATEID: 1831 case -NFS4ERR_STALE_STATEID:
1733 case -NFS4ERR_OLD_STATEID: 1832 case -NFS4ERR_OLD_STATEID:
@@ -1736,12 +1835,10 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
1736 if (calldata->arg.fmode == 0) 1835 if (calldata->arg.fmode == 0)
1737 break; 1836 break;
1738 default: 1837 default:
1739 if (nfs4_async_handle_error(task, server, state) == -EAGAIN) { 1838 if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
1740 nfs4_restart_rpc(task, server->nfs_client); 1839 rpc_restart_call_prepare(task);
1741 return;
1742 }
1743 } 1840 }
1744 nfs4_sequence_free_slot(server->nfs_client, &calldata->res.seq_res); 1841 nfs_release_seqid(calldata->arg.seqid);
1745 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 1842 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
1746} 1843}
1747 1844
@@ -1749,38 +1846,39 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
1749{ 1846{
1750 struct nfs4_closedata *calldata = data; 1847 struct nfs4_closedata *calldata = data;
1751 struct nfs4_state *state = calldata->state; 1848 struct nfs4_state *state = calldata->state;
1752 int clear_rd, clear_wr, clear_rdwr; 1849 int call_close = 0;
1753 1850
1754 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) 1851 if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
1755 return; 1852 return;
1756 1853
1757 clear_rd = clear_wr = clear_rdwr = 0; 1854 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
1855 calldata->arg.fmode = FMODE_READ|FMODE_WRITE;
1758 spin_lock(&state->owner->so_lock); 1856 spin_lock(&state->owner->so_lock);
1759 /* Calculate the change in open mode */ 1857 /* Calculate the change in open mode */
1760 if (state->n_rdwr == 0) { 1858 if (state->n_rdwr == 0) {
1761 if (state->n_rdonly == 0) { 1859 if (state->n_rdonly == 0) {
1762 clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1860 call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
1763 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1861 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1862 calldata->arg.fmode &= ~FMODE_READ;
1764 } 1863 }
1765 if (state->n_wronly == 0) { 1864 if (state->n_wronly == 0) {
1766 clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1865 call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
1767 clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); 1866 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
1867 calldata->arg.fmode &= ~FMODE_WRITE;
1768 } 1868 }
1769 } 1869 }
1770 spin_unlock(&state->owner->so_lock); 1870 spin_unlock(&state->owner->so_lock);
1771 if (!clear_rd && !clear_wr && !clear_rdwr) { 1871
1872 if (!call_close) {
1772 /* Note: exit _without_ calling nfs4_close_done */ 1873 /* Note: exit _without_ calling nfs4_close_done */
1773 task->tk_action = NULL; 1874 task->tk_action = NULL;
1774 return; 1875 return;
1775 } 1876 }
1877
1878 if (calldata->arg.fmode == 0)
1879 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
1880
1776 nfs_fattr_init(calldata->res.fattr); 1881 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; 1882 calldata->timestamp = jiffies;
1785 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client, 1883 if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
1786 &calldata->arg.seq_args, &calldata->res.seq_res, 1884 &calldata->arg.seq_args, &calldata->res.seq_res,
@@ -1832,8 +1930,6 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
1832 calldata->state = state; 1930 calldata->state = state;
1833 calldata->arg.fh = NFS_FH(state->inode); 1931 calldata->arg.fh = NFS_FH(state->inode);
1834 calldata->arg.stateid = &state->open_stateid; 1932 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 */ 1933 /* Serialization for the sequence id */
1838 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid); 1934 calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
1839 if (calldata->arg.seqid == NULL) 1935 if (calldata->arg.seqid == NULL)
@@ -1981,7 +2077,7 @@ out_drop:
1981 return 0; 2077 return 0;
1982} 2078}
1983 2079
1984void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2080static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
1985{ 2081{
1986 if (ctx->state == NULL) 2082 if (ctx->state == NULL)
1987 return; 2083 return;
@@ -2532,7 +2628,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); 2628 nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
2533 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN) 2629 if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
2534 return 0; 2630 return 0;
2535 nfs4_sequence_free_slot(res->server->nfs_client, &res->seq_res);
2536 update_changeattr(dir, &res->cinfo); 2631 update_changeattr(dir, &res->cinfo);
2537 nfs_post_op_update_inode(dir, &res->dir_attr); 2632 nfs_post_op_update_inode(dir, &res->dir_attr);
2538 return 1; 2633 return 1;
@@ -2971,11 +3066,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
2971 3066
2972 dprintk("--> %s\n", __func__); 3067 dprintk("--> %s\n", __func__);
2973 3068
2974 /* nfs4_sequence_free_slot called in the read rpc_call_done */
2975 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status); 3069 nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
2976 3070
2977 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) { 3071 if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
2978 nfs4_restart_rpc(task, server->nfs_client); 3072 nfs_restart_rpc(task, server->nfs_client);
2979 return -EAGAIN; 3073 return -EAGAIN;
2980 } 3074 }
2981 3075
@@ -2995,12 +3089,11 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
2995{ 3089{
2996 struct inode *inode = data->inode; 3090 struct inode *inode = data->inode;
2997 3091
2998 /* slot is freed in nfs_writeback_done */
2999 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res, 3092 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3000 task->tk_status); 3093 task->tk_status);
3001 3094
3002 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) { 3095 if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
3003 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3096 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3004 return -EAGAIN; 3097 return -EAGAIN;
3005 } 3098 }
3006 if (task->tk_status >= 0) { 3099 if (task->tk_status >= 0) {
@@ -3028,11 +3121,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, 3121 nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
3029 task->tk_status); 3122 task->tk_status);
3030 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) { 3123 if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
3031 nfs4_restart_rpc(task, NFS_SERVER(inode)->nfs_client); 3124 nfs_restart_rpc(task, NFS_SERVER(inode)->nfs_client);
3032 return -EAGAIN; 3125 return -EAGAIN;
3033 } 3126 }
3034 nfs4_sequence_free_slot(NFS_SERVER(inode)->nfs_client,
3035 &data->res.seq_res);
3036 nfs_refresh_inode(inode, data->res.fattr); 3127 nfs_refresh_inode(inode, data->res.fattr);
3037 return 0; 3128 return 0;
3038} 3129}
@@ -3350,7 +3441,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
3350 case -NFS4ERR_SEQ_MISORDERED: 3441 case -NFS4ERR_SEQ_MISORDERED:
3351 dprintk("%s ERROR %d, Reset session\n", __func__, 3442 dprintk("%s ERROR %d, Reset session\n", __func__,
3352 task->tk_status); 3443 task->tk_status);
3353 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); 3444 nfs4_schedule_state_recovery(clp);
3354 task->tk_status = 0; 3445 task->tk_status = 0;
3355 return -EAGAIN; 3446 return -EAGAIN;
3356#endif /* CONFIG_NFS_V4_1 */ 3447#endif /* CONFIG_NFS_V4_1 */
@@ -3483,12 +3574,23 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
3483{ 3574{
3484 struct nfs4_delegreturndata *data = calldata; 3575 struct nfs4_delegreturndata *data = calldata;
3485 3576
3486 nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res, 3577 nfs4_sequence_done(data->res.server, &data->res.seq_res,
3487 task->tk_status); 3578 task->tk_status);
3488 3579
3489 data->rpc_status = task->tk_status; 3580 switch (task->tk_status) {
3490 if (data->rpc_status == 0) 3581 case -NFS4ERR_STALE_STATEID:
3582 case -NFS4ERR_EXPIRED:
3583 case 0:
3491 renew_lease(data->res.server, data->timestamp); 3584 renew_lease(data->res.server, data->timestamp);
3585 break;
3586 default:
3587 if (nfs4_async_handle_error(task, data->res.server, NULL) ==
3588 -EAGAIN) {
3589 nfs_restart_rpc(task, data->res.server->nfs_client);
3590 return;
3591 }
3592 }
3593 data->rpc_status = task->tk_status;
3492} 3594}
3493 3595
3494static void nfs4_delegreturn_release(void *calldata) 3596static void nfs4_delegreturn_release(void *calldata)
@@ -3741,11 +3843,9 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
3741 break; 3843 break;
3742 default: 3844 default:
3743 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) 3845 if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
3744 nfs4_restart_rpc(task, 3846 nfs_restart_rpc(task,
3745 calldata->server->nfs_client); 3847 calldata->server->nfs_client);
3746 } 3848 }
3747 nfs4_sequence_free_slot(calldata->server->nfs_client,
3748 &calldata->res.seq_res);
3749} 3849}
3750 3850
3751static void nfs4_locku_prepare(struct rpc_task *task, void *data) 3851static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3921,14 +4021,20 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
3921 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); 4021 dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
3922} 4022}
3923 4023
4024static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
4025{
4026 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4027 nfs4_lock_prepare(task, calldata);
4028}
4029
3924static void nfs4_lock_done(struct rpc_task *task, void *calldata) 4030static void nfs4_lock_done(struct rpc_task *task, void *calldata)
3925{ 4031{
3926 struct nfs4_lockdata *data = calldata; 4032 struct nfs4_lockdata *data = calldata;
3927 4033
3928 dprintk("%s: begin!\n", __func__); 4034 dprintk("%s: begin!\n", __func__);
3929 4035
3930 nfs4_sequence_done_free_slot(data->server, &data->res.seq_res, 4036 nfs4_sequence_done(data->server, &data->res.seq_res,
3931 task->tk_status); 4037 task->tk_status);
3932 4038
3933 data->rpc_status = task->tk_status; 4039 data->rpc_status = task->tk_status;
3934 if (RPC_ASSASSINATED(task)) 4040 if (RPC_ASSASSINATED(task))
@@ -3976,7 +4082,13 @@ static const struct rpc_call_ops nfs4_lock_ops = {
3976 .rpc_release = nfs4_lock_release, 4082 .rpc_release = nfs4_lock_release,
3977}; 4083};
3978 4084
3979static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) 4085static const struct rpc_call_ops nfs4_recover_lock_ops = {
4086 .rpc_call_prepare = nfs4_recover_lock_prepare,
4087 .rpc_call_done = nfs4_lock_done,
4088 .rpc_release = nfs4_lock_release,
4089};
4090
4091static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
3980{ 4092{
3981 struct nfs4_lockdata *data; 4093 struct nfs4_lockdata *data;
3982 struct rpc_task *task; 4094 struct rpc_task *task;
@@ -4000,8 +4112,11 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
4000 return -ENOMEM; 4112 return -ENOMEM;
4001 if (IS_SETLKW(cmd)) 4113 if (IS_SETLKW(cmd))
4002 data->arg.block = 1; 4114 data->arg.block = 1;
4003 if (reclaim != 0) 4115 if (recovery_type > NFS_LOCK_NEW) {
4004 data->arg.reclaim = 1; 4116 if (recovery_type == NFS_LOCK_RECLAIM)
4117 data->arg.reclaim = NFS_LOCK_RECLAIM;
4118 task_setup_data.callback_ops = &nfs4_recover_lock_ops;
4119 }
4005 msg.rpc_argp = &data->arg, 4120 msg.rpc_argp = &data->arg,
4006 msg.rpc_resp = &data->res, 4121 msg.rpc_resp = &data->res,
4007 task_setup_data.callback_data = data; 4122 task_setup_data.callback_data = data;
@@ -4028,7 +4143,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
4028 /* Cache the lock if possible... */ 4143 /* Cache the lock if possible... */
4029 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4144 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4030 return 0; 4145 return 0;
4031 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 4146 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM);
4032 if (err != -NFS4ERR_DELAY) 4147 if (err != -NFS4ERR_DELAY)
4033 break; 4148 break;
4034 nfs4_handle_exception(server, err, &exception); 4149 nfs4_handle_exception(server, err, &exception);
@@ -4048,11 +4163,17 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
4048 do { 4163 do {
4049 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) 4164 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
4050 return 0; 4165 return 0;
4051 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 4166 err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_EXPIRED);
4052 if (err != -NFS4ERR_DELAY) 4167 switch (err) {
4053 break; 4168 default:
4054 nfs4_handle_exception(server, err, &exception); 4169 goto out;
4170 case -NFS4ERR_GRACE:
4171 case -NFS4ERR_DELAY:
4172 nfs4_handle_exception(server, err, &exception);
4173 err = 0;
4174 }
4055 } while (exception.retry); 4175 } while (exception.retry);
4176out:
4056 return err; 4177 return err;
4057} 4178}
4058 4179
@@ -4078,7 +4199,7 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
4078 status = do_vfs_lock(request->fl_file, request); 4199 status = do_vfs_lock(request->fl_file, request);
4079 goto out_unlock; 4200 goto out_unlock;
4080 } 4201 }
4081 status = _nfs4_do_setlk(state, cmd, request, 0); 4202 status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
4082 if (status != 0) 4203 if (status != 0)
4083 goto out_unlock; 4204 goto out_unlock;
4084 /* Note: we always want to sleep here! */ 4205 /* Note: we always want to sleep here! */
@@ -4161,7 +4282,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4161 if (err != 0) 4282 if (err != 0)
4162 goto out; 4283 goto out;
4163 do { 4284 do {
4164 err = _nfs4_do_setlk(state, F_SETLK, fl, 0); 4285 err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
4165 switch (err) { 4286 switch (err) {
4166 default: 4287 default:
4167 printk(KERN_ERR "%s: unhandled error %d.\n", 4288 printk(KERN_ERR "%s: unhandled error %d.\n",
@@ -4172,6 +4293,11 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
4172 case -NFS4ERR_EXPIRED: 4293 case -NFS4ERR_EXPIRED:
4173 case -NFS4ERR_STALE_CLIENTID: 4294 case -NFS4ERR_STALE_CLIENTID:
4174 case -NFS4ERR_STALE_STATEID: 4295 case -NFS4ERR_STALE_STATEID:
4296 case -NFS4ERR_BADSESSION:
4297 case -NFS4ERR_BADSLOT:
4298 case -NFS4ERR_BAD_HIGH_SLOT:
4299 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
4300 case -NFS4ERR_DEADSESSION:
4175 nfs4_schedule_state_recovery(server->nfs_client); 4301 nfs4_schedule_state_recovery(server->nfs_client);
4176 goto out; 4302 goto out;
4177 case -ERESTARTSYS: 4303 case -ERESTARTSYS:
@@ -4296,7 +4422,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
4296 * NFS4ERR_BADSESSION in the sequence operation, and will therefore 4422 * NFS4ERR_BADSESSION in the sequence operation, and will therefore
4297 * be in some phase of session reset. 4423 * be in some phase of session reset.
4298 */ 4424 */
4299static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) 4425int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4300{ 4426{
4301 nfs4_verifier verifier; 4427 nfs4_verifier verifier;
4302 struct nfs41_exchange_id_args args = { 4428 struct nfs41_exchange_id_args args = {
@@ -4318,6 +4444,9 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
4318 dprintk("--> %s\n", __func__); 4444 dprintk("--> %s\n", __func__);
4319 BUG_ON(clp == NULL); 4445 BUG_ON(clp == NULL);
4320 4446
4447 /* Remove server-only flags */
4448 args.flags &= ~EXCHGID4_FLAG_CONFIRMED_R;
4449
4321 p = (u32 *)verifier.data; 4450 p = (u32 *)verifier.data;
4322 *p++ = htonl((u32)clp->cl_boot_time.tv_sec); 4451 *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
4323 *p = htonl((u32)clp->cl_boot_time.tv_nsec); 4452 *p = htonl((u32)clp->cl_boot_time.tv_nsec);
@@ -4361,11 +4490,12 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
4361 (struct nfs4_get_lease_time_data *)calldata; 4490 (struct nfs4_get_lease_time_data *)calldata;
4362 4491
4363 dprintk("--> %s\n", __func__); 4492 dprintk("--> %s\n", __func__);
4493 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
4364 /* just setup sequence, do not trigger session recovery 4494 /* just setup sequence, do not trigger session recovery
4365 since we're invoked within one */ 4495 since we're invoked within one */
4366 ret = nfs41_setup_sequence(data->clp->cl_session, 4496 ret = nfs41_setup_sequence(data->clp->cl_session,
4367 &data->args->la_seq_args, 4497 &data->args->la_seq_args,
4368 &data->res->lr_seq_res, 0, task); 4498 &data->res->lr_seq_res, 0, task);
4369 4499
4370 BUG_ON(ret == -EAGAIN); 4500 BUG_ON(ret == -EAGAIN);
4371 rpc_call_start(task); 4501 rpc_call_start(task);
@@ -4389,10 +4519,9 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
4389 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); 4519 dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
4390 rpc_delay(task, NFS4_POLL_RETRY_MIN); 4520 rpc_delay(task, NFS4_POLL_RETRY_MIN);
4391 task->tk_status = 0; 4521 task->tk_status = 0;
4392 nfs4_restart_rpc(task, data->clp); 4522 nfs_restart_rpc(task, data->clp);
4393 return; 4523 return;
4394 } 4524 }
4395 nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
4396 dprintk("<-- %s\n", __func__); 4525 dprintk("<-- %s\n", __func__);
4397} 4526}
4398 4527
@@ -4465,7 +4594,6 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, int max_slots,
4465 spin_lock(&tbl->slot_tbl_lock); 4594 spin_lock(&tbl->slot_tbl_lock);
4466 for (i = 0; i < max_slots; ++i) 4595 for (i = 0; i < max_slots; ++i)
4467 tbl->slots[i].seq_nr = ivalue; 4596 tbl->slots[i].seq_nr = ivalue;
4468 tbl->highest_used_slotid = -1;
4469 spin_unlock(&tbl->slot_tbl_lock); 4597 spin_unlock(&tbl->slot_tbl_lock);
4470 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__, 4598 dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
4471 tbl, tbl->slots, tbl->max_slots); 4599 tbl, tbl->slots, tbl->max_slots);
@@ -4515,7 +4643,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
4515static int nfs4_init_slot_table(struct nfs4_slot_table *tbl, 4643static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4516 int max_slots, int ivalue) 4644 int max_slots, int ivalue)
4517{ 4645{
4518 int i;
4519 struct nfs4_slot *slot; 4646 struct nfs4_slot *slot;
4520 int ret = -ENOMEM; 4647 int ret = -ENOMEM;
4521 4648
@@ -4526,18 +4653,9 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4526 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL); 4653 slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
4527 if (!slot) 4654 if (!slot)
4528 goto out; 4655 goto out;
4529 for (i = 0; i < max_slots; ++i)
4530 slot[i].seq_nr = ivalue;
4531 ret = 0; 4656 ret = 0;
4532 4657
4533 spin_lock(&tbl->slot_tbl_lock); 4658 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; 4659 tbl->max_slots = max_slots;
4542 tbl->slots = slot; 4660 tbl->slots = slot;
4543 tbl->highest_used_slotid = -1; /* no slot is currently used */ 4661 tbl->highest_used_slotid = -1; /* no slot is currently used */
@@ -4547,10 +4665,6 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
4547out: 4665out:
4548 dprintk("<-- %s: return %d\n", __func__, ret); 4666 dprintk("<-- %s: return %d\n", __func__, ret);
4549 return ret; 4667 return ret;
4550
4551out_free:
4552 kfree(slot);
4553 goto out;
4554} 4668}
4555 4669
4556/* 4670/*
@@ -4558,17 +4672,24 @@ out_free:
4558 */ 4672 */
4559static int nfs4_init_slot_tables(struct nfs4_session *session) 4673static int nfs4_init_slot_tables(struct nfs4_session *session)
4560{ 4674{
4561 int status; 4675 struct nfs4_slot_table *tbl;
4676 int status = 0;
4562 4677
4563 status = nfs4_init_slot_table(&session->fc_slot_table, 4678 tbl = &session->fc_slot_table;
4564 session->fc_attrs.max_reqs, 1); 4679 if (tbl->slots == NULL) {
4565 if (status) 4680 status = nfs4_init_slot_table(tbl,
4566 return status; 4681 session->fc_attrs.max_reqs, 1);
4682 if (status)
4683 return status;
4684 }
4567 4685
4568 status = nfs4_init_slot_table(&session->bc_slot_table, 4686 tbl = &session->bc_slot_table;
4569 session->bc_attrs.max_reqs, 0); 4687 if (tbl->slots == NULL) {
4570 if (status) 4688 status = nfs4_init_slot_table(tbl,
4571 nfs4_destroy_slot_tables(session); 4689 session->bc_attrs.max_reqs, 0);
4690 if (status)
4691 nfs4_destroy_slot_tables(session);
4692 }
4572 4693
4573 return status; 4694 return status;
4574} 4695}
@@ -4582,7 +4703,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4582 if (!session) 4703 if (!session)
4583 return NULL; 4704 return NULL;
4584 4705
4585 set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state);
4586 /* 4706 /*
4587 * The create session reply races with the server back 4707 * The create session reply races with the server back
4588 * channel probe. Mark the client NFS_CS_SESSION_INITING 4708 * channel probe. Mark the client NFS_CS_SESSION_INITING
@@ -4590,12 +4710,15 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
4590 * nfs_client struct 4710 * nfs_client struct
4591 */ 4711 */
4592 clp->cl_cons_state = NFS_CS_SESSION_INITING; 4712 clp->cl_cons_state = NFS_CS_SESSION_INITING;
4713 init_completion(&session->complete);
4593 4714
4594 tbl = &session->fc_slot_table; 4715 tbl = &session->fc_slot_table;
4716 tbl->highest_used_slotid = -1;
4595 spin_lock_init(&tbl->slot_tbl_lock); 4717 spin_lock_init(&tbl->slot_tbl_lock);
4596 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table"); 4718 rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
4597 4719
4598 tbl = &session->bc_slot_table; 4720 tbl = &session->bc_slot_table;
4721 tbl->highest_used_slotid = -1;
4599 spin_lock_init(&tbl->slot_tbl_lock); 4722 spin_lock_init(&tbl->slot_tbl_lock);
4600 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table"); 4723 rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
4601 4724
@@ -4747,11 +4870,10 @@ static int _nfs4_proc_create_session(struct nfs_client *clp)
4747 * It is the responsibility of the caller to verify the session is 4870 * It is the responsibility of the caller to verify the session is
4748 * expired before calling this routine. 4871 * expired before calling this routine.
4749 */ 4872 */
4750int nfs4_proc_create_session(struct nfs_client *clp, int reset) 4873int nfs4_proc_create_session(struct nfs_client *clp)
4751{ 4874{
4752 int status; 4875 int status;
4753 unsigned *ptr; 4876 unsigned *ptr;
4754 struct nfs_fsinfo fsinfo;
4755 struct nfs4_session *session = clp->cl_session; 4877 struct nfs4_session *session = clp->cl_session;
4756 4878
4757 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); 4879 dprintk("--> %s clp=%p session=%p\n", __func__, clp, session);
@@ -4760,35 +4882,19 @@ int nfs4_proc_create_session(struct nfs_client *clp, int reset)
4760 if (status) 4882 if (status)
4761 goto out; 4883 goto out;
4762 4884
4763 /* Init or reset the fore channel */ 4885 /* Init and reset the fore channel */
4764 if (reset) 4886 status = nfs4_init_slot_tables(session);
4765 status = nfs4_reset_slot_tables(session); 4887 dprintk("slot table initialization returned %d\n", status);
4766 else 4888 if (status)
4767 status = nfs4_init_slot_tables(session); 4889 goto out;
4768 dprintk("fore channel slot table initialization returned %d\n", status); 4890 status = nfs4_reset_slot_tables(session);
4891 dprintk("slot table reset returned %d\n", status);
4769 if (status) 4892 if (status)
4770 goto out; 4893 goto out;
4771 4894
4772 ptr = (unsigned *)&session->sess_id.data[0]; 4895 ptr = (unsigned *)&session->sess_id.data[0];
4773 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__, 4896 dprintk("%s client>seqid %d sessionid %u:%u:%u:%u\n", __func__,
4774 clp->cl_seqid, ptr[0], ptr[1], ptr[2], ptr[3]); 4897 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: 4898out:
4793 dprintk("<-- %s\n", __func__); 4899 dprintk("<-- %s\n", __func__);
4794 return status; 4900 return status;
@@ -4827,13 +4933,24 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
4827int nfs4_init_session(struct nfs_server *server) 4933int nfs4_init_session(struct nfs_server *server)
4828{ 4934{
4829 struct nfs_client *clp = server->nfs_client; 4935 struct nfs_client *clp = server->nfs_client;
4936 struct nfs4_session *session;
4937 unsigned int rsize, wsize;
4830 int ret; 4938 int ret;
4831 4939
4832 if (!nfs4_has_session(clp)) 4940 if (!nfs4_has_session(clp))
4833 return 0; 4941 return 0;
4834 4942
4835 clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; 4943 rsize = server->rsize;
4836 clp->cl_session->fc_attrs.max_resp_sz = server->rsize; 4944 if (rsize == 0)
4945 rsize = NFS_MAX_FILE_IO_SIZE;
4946 wsize = server->wsize;
4947 if (wsize == 0)
4948 wsize = NFS_MAX_FILE_IO_SIZE;
4949
4950 session = clp->cl_session;
4951 session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
4952 session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
4953
4837 ret = nfs4_recover_expired_lease(server); 4954 ret = nfs4_recover_expired_lease(server);
4838 if (!ret) 4955 if (!ret)
4839 ret = nfs4_check_client_ready(clp); 4956 ret = nfs4_check_client_ready(clp);
@@ -4858,7 +4975,7 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
4858 args.sa_cache_this = 0; 4975 args.sa_cache_this = 0;
4859 4976
4860 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args, 4977 return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
4861 &res, 0); 4978 &res, args.sa_cache_this, 1);
4862} 4979}
4863 4980
4864void nfs41_sequence_call_done(struct rpc_task *task, void *data) 4981void nfs41_sequence_call_done(struct rpc_task *task, void *data)
@@ -4872,11 +4989,10 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data)
4872 4989
4873 if (_nfs4_async_handle_error(task, NULL, clp, NULL) 4990 if (_nfs4_async_handle_error(task, NULL, clp, NULL)
4874 == -EAGAIN) { 4991 == -EAGAIN) {
4875 nfs4_restart_rpc(task, clp); 4992 nfs_restart_rpc(task, clp);
4876 return; 4993 return;
4877 } 4994 }
4878 } 4995 }
4879 nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp);
4880 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); 4996 dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
4881 4997
4882 kfree(task->tk_msg.rpc_argp); 4998 kfree(task->tk_msg.rpc_argp);
@@ -4931,6 +5047,110 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
4931 &nfs41_sequence_ops, (void *)clp); 5047 &nfs41_sequence_ops, (void *)clp);
4932} 5048}
4933 5049
5050struct nfs4_reclaim_complete_data {
5051 struct nfs_client *clp;
5052 struct nfs41_reclaim_complete_args arg;
5053 struct nfs41_reclaim_complete_res res;
5054};
5055
5056static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
5057{
5058 struct nfs4_reclaim_complete_data *calldata = data;
5059
5060 rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
5061 if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
5062 &calldata->res.seq_res, 0, task))
5063 return;
5064
5065 rpc_call_start(task);
5066}
5067
5068static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
5069{
5070 struct nfs4_reclaim_complete_data *calldata = data;
5071 struct nfs_client *clp = calldata->clp;
5072 struct nfs4_sequence_res *res = &calldata->res.seq_res;
5073
5074 dprintk("--> %s\n", __func__);
5075 nfs41_sequence_done(clp, res, task->tk_status);
5076 switch (task->tk_status) {
5077 case 0:
5078 case -NFS4ERR_COMPLETE_ALREADY:
5079 break;
5080 case -NFS4ERR_BADSESSION:
5081 case -NFS4ERR_DEADSESSION:
5082 /*
5083 * Handle the session error, but do not retry the operation, as
5084 * we have no way of telling whether the clientid had to be
5085 * reset before we got our reply. If reset, a new wave of
5086 * reclaim operations will follow, containing their own reclaim
5087 * complete. We don't want our retry to get on the way of
5088 * recovery by incorrectly indicating to the server that we're
5089 * done reclaiming state since the process had to be restarted.
5090 */
5091 _nfs4_async_handle_error(task, NULL, clp, NULL);
5092 break;
5093 default:
5094 if (_nfs4_async_handle_error(
5095 task, NULL, clp, NULL) == -EAGAIN) {
5096 rpc_restart_call_prepare(task);
5097 return;
5098 }
5099 }
5100
5101 dprintk("<-- %s\n", __func__);
5102}
5103
5104static void nfs4_free_reclaim_complete_data(void *data)
5105{
5106 struct nfs4_reclaim_complete_data *calldata = data;
5107
5108 kfree(calldata);
5109}
5110
5111static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
5112 .rpc_call_prepare = nfs4_reclaim_complete_prepare,
5113 .rpc_call_done = nfs4_reclaim_complete_done,
5114 .rpc_release = nfs4_free_reclaim_complete_data,
5115};
5116
5117/*
5118 * Issue a global reclaim complete.
5119 */
5120static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
5121{
5122 struct nfs4_reclaim_complete_data *calldata;
5123 struct rpc_task *task;
5124 struct rpc_message msg = {
5125 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
5126 };
5127 struct rpc_task_setup task_setup_data = {
5128 .rpc_client = clp->cl_rpcclient,
5129 .rpc_message = &msg,
5130 .callback_ops = &nfs4_reclaim_complete_call_ops,
5131 .flags = RPC_TASK_ASYNC,
5132 };
5133 int status = -ENOMEM;
5134
5135 dprintk("--> %s\n", __func__);
5136 calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
5137 if (calldata == NULL)
5138 goto out;
5139 calldata->clp = clp;
5140 calldata->arg.one_fs = 0;
5141 calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
5142
5143 msg.rpc_argp = &calldata->arg;
5144 msg.rpc_resp = &calldata->res;
5145 task_setup_data.callback_data = calldata;
5146 task = rpc_run_task(&task_setup_data);
5147 if (IS_ERR(task))
5148 status = PTR_ERR(task);
5149 rpc_put_task(task);
5150out:
5151 dprintk("<-- %s status=%d\n", __func__, status);
5152 return status;
5153}
4934#endif /* CONFIG_NFS_V4_1 */ 5154#endif /* CONFIG_NFS_V4_1 */
4935 5155
4936struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = { 5156struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
@@ -4948,8 +5168,9 @@ struct nfs4_state_recovery_ops nfs41_reboot_recovery_ops = {
4948 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT, 5168 .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
4949 .recover_open = nfs4_open_reclaim, 5169 .recover_open = nfs4_open_reclaim,
4950 .recover_lock = nfs4_lock_reclaim, 5170 .recover_lock = nfs4_lock_reclaim,
4951 .establish_clid = nfs4_proc_exchange_id, 5171 .establish_clid = nfs41_init_clientid,
4952 .get_clid_cred = nfs4_get_exchange_id_cred, 5172 .get_clid_cred = nfs4_get_exchange_id_cred,
5173 .reclaim_complete = nfs41_proc_reclaim_complete,
4953}; 5174};
4954#endif /* CONFIG_NFS_V4_1 */ 5175#endif /* CONFIG_NFS_V4_1 */
4955 5176
@@ -4968,7 +5189,7 @@ struct nfs4_state_recovery_ops nfs41_nograce_recovery_ops = {
4968 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, 5189 .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE,
4969 .recover_open = nfs4_open_expired, 5190 .recover_open = nfs4_open_expired,
4970 .recover_lock = nfs4_lock_expired, 5191 .recover_lock = nfs4_lock_expired,
4971 .establish_clid = nfs4_proc_exchange_id, 5192 .establish_clid = nfs41_init_clientid,
4972 .get_clid_cred = nfs4_get_exchange_id_cred, 5193 .get_clid_cred = nfs4_get_exchange_id_cred,
4973}; 5194};
4974#endif /* CONFIG_NFS_V4_1 */ 5195#endif /* CONFIG_NFS_V4_1 */