aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c32
-rw-r--r--fs/nfs/nfs4session.c1
-rw-r--r--fs/nfs/nfs4session.h1
3 files changed, 25 insertions, 9 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index afb428e63b52..493f0f41c554 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -420,17 +420,9 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
420 struct nfs4_session *session; 420 struct nfs4_session *session;
421 struct nfs4_slot *slot; 421 struct nfs4_slot *slot;
422 struct nfs_client *clp; 422 struct nfs_client *clp;
423 bool interrupted = false;
423 int ret = 1; 424 int ret = 1;
424 425
425 /*
426 * sr_status remains 1 if an RPC level error occurred. The server
427 * may or may not have processed the sequence operation..
428 * Proceed as if the server received and processed the sequence
429 * operation.
430 */
431 if (res->sr_status == 1)
432 res->sr_status = NFS_OK;
433
434 /* don't increment the sequence number if the task wasn't sent */ 426 /* don't increment the sequence number if the task wasn't sent */
435 if (!RPC_WAS_SENT(task)) 427 if (!RPC_WAS_SENT(task))
436 goto out; 428 goto out;
@@ -438,6 +430,11 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
438 slot = res->sr_slot; 430 slot = res->sr_slot;
439 session = slot->table->session; 431 session = slot->table->session;
440 432
433 if (slot->interrupted) {
434 slot->interrupted = 0;
435 interrupted = true;
436 }
437
441 /* Check the SEQUENCE operation status */ 438 /* Check the SEQUENCE operation status */
442 switch (res->sr_status) { 439 switch (res->sr_status) {
443 case 0: 440 case 0:
@@ -450,6 +447,15 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
450 nfs4_schedule_lease_recovery(clp); 447 nfs4_schedule_lease_recovery(clp);
451 nfs41_update_target_slotid(slot->table, slot, res); 448 nfs41_update_target_slotid(slot->table, slot, res);
452 break; 449 break;
450 case 1:
451 /*
452 * sr_status remains 1 if an RPC level error occurred.
453 * The server may or may not have processed the sequence
454 * operation..
455 * Mark the slot as having hosted an interrupted RPC call.
456 */
457 slot->interrupted = 1;
458 goto out;
453 case -NFS4ERR_DELAY: 459 case -NFS4ERR_DELAY:
454 /* The server detected a resend of the RPC call and 460 /* The server detected a resend of the RPC call and
455 * returned NFS4ERR_DELAY as per Section 2.10.6.2 461 * returned NFS4ERR_DELAY as per Section 2.10.6.2
@@ -468,6 +474,14 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *
468 goto retry_nowait; 474 goto retry_nowait;
469 case -NFS4ERR_SEQ_MISORDERED: 475 case -NFS4ERR_SEQ_MISORDERED:
470 /* 476 /*
477 * Was the last operation on this sequence interrupted?
478 * If so, retry after bumping the sequence number.
479 */
480 if (interrupted) {
481 ++slot->seq_nr;
482 goto retry_nowait;
483 }
484 /*
471 * Could this slot have been previously retired? 485 * Could this slot have been previously retired?
472 * If so, then the server may be expecting seq_nr = 1! 486 * If so, then the server may be expecting seq_nr = 1!
473 */ 487 */
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index 0e1cc1f4e51a..ebda5f4a031b 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -172,6 +172,7 @@ static void nfs4_reset_slot_table(struct nfs4_slot_table *tbl,
172 p = &tbl->slots; 172 p = &tbl->slots;
173 while (*p) { 173 while (*p) {
174 (*p)->seq_nr = ivalue; 174 (*p)->seq_nr = ivalue;
175 (*p)->interrupted = 0;
175 p = &(*p)->next; 176 p = &(*p)->next;
176 } 177 }
177 tbl->highest_used_slotid = NFS4_NO_SLOT; 178 tbl->highest_used_slotid = NFS4_NO_SLOT;
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index d17b08091d4b..6f3cb39386d4 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -21,6 +21,7 @@ struct nfs4_slot {
21 unsigned long generation; 21 unsigned long generation;
22 u32 slot_nr; 22 u32 slot_nr;
23 u32 seq_nr; 23 u32 seq_nr;
24 unsigned int interrupted : 1;
24}; 25};
25 26
26/* Sessions */ 27/* Sessions */