diff options
-rw-r--r-- | fs/nfs/callback_proc.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 25 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 7 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 4 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 5 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
6 files changed, 36 insertions, 9 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 0be08b964f38..0ef047b7d28d 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -576,7 +576,7 @@ __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy, | |||
576 | if (args->crsa_target_max_slots == fc_tbl->max_slots) | 576 | if (args->crsa_target_max_slots == fc_tbl->max_slots) |
577 | goto out; | 577 | goto out; |
578 | 578 | ||
579 | fc_tbl->target_max_slots = args->crsa_target_max_slots; | 579 | fc_tbl->target_highest_slotid = args->crsa_target_max_slots; |
580 | nfs41_handle_recall_slot(cps->clp); | 580 | nfs41_handle_recall_slot(cps->clp); |
581 | out: | 581 | out: |
582 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); | 582 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 197ef3e4e1f7..d91abaa522e8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -488,6 +488,28 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) | |||
488 | res->sr_slot = NULL; | 488 | res->sr_slot = NULL; |
489 | } | 489 | } |
490 | 490 | ||
491 | /* Update the client's idea of target_highest_slotid */ | ||
492 | static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, | ||
493 | u32 target_highest_slotid) | ||
494 | { | ||
495 | if (tbl->target_highest_slotid == target_highest_slotid) | ||
496 | return; | ||
497 | tbl->target_highest_slotid = target_highest_slotid; | ||
498 | tbl->generation++; | ||
499 | } | ||
500 | |||
501 | static void nfs41_update_target_slotid(struct nfs4_slot_table *tbl, | ||
502 | struct nfs4_slot *slot, | ||
503 | struct nfs4_sequence_res *res) | ||
504 | { | ||
505 | spin_lock(&tbl->slot_tbl_lock); | ||
506 | if (tbl->generation != slot->generation) | ||
507 | goto out; | ||
508 | nfs41_set_target_slotid_locked(tbl, res->sr_target_highest_slotid); | ||
509 | out: | ||
510 | spin_unlock(&tbl->slot_tbl_lock); | ||
511 | } | ||
512 | |||
491 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) | 513 | static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) |
492 | { | 514 | { |
493 | struct nfs4_session *session; | 515 | struct nfs4_session *session; |
@@ -522,6 +544,7 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * | |||
522 | /* Check sequence flags */ | 544 | /* Check sequence flags */ |
523 | if (res->sr_status_flags != 0) | 545 | if (res->sr_status_flags != 0) |
524 | nfs4_schedule_lease_recovery(clp); | 546 | nfs4_schedule_lease_recovery(clp); |
547 | nfs41_update_target_slotid(slot->table, slot, res); | ||
525 | break; | 548 | break; |
526 | case -NFS4ERR_DELAY: | 549 | case -NFS4ERR_DELAY: |
527 | /* The server detected a resend of the RPC call and | 550 | /* The server detected a resend of the RPC call and |
@@ -583,6 +606,7 @@ static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl) | |||
583 | tbl->highest_used_slotid = slotid; | 606 | tbl->highest_used_slotid = slotid; |
584 | ret = &tbl->slots[slotid]; | 607 | ret = &tbl->slots[slotid]; |
585 | ret->renewal_time = jiffies; | 608 | ret->renewal_time = jiffies; |
609 | ret->generation = tbl->generation; | ||
586 | 610 | ||
587 | out: | 611 | out: |
588 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", | 612 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", |
@@ -5693,6 +5717,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, | |||
5693 | tbl->max_slots = max_slots; | 5717 | tbl->max_slots = max_slots; |
5694 | } | 5718 | } |
5695 | tbl->highest_used_slotid = NFS4_NO_SLOT; | 5719 | tbl->highest_used_slotid = NFS4_NO_SLOT; |
5720 | tbl->target_highest_slotid = max_slots - 1; | ||
5696 | for (i = 0; i < tbl->max_slots; i++) | 5721 | for (i = 0; i < tbl->max_slots; i++) |
5697 | tbl->slots[i].seq_nr = ivalue; | 5722 | tbl->slots[i].seq_nr = ivalue; |
5698 | spin_unlock(&tbl->slot_tbl_lock); | 5723 | spin_unlock(&tbl->slot_tbl_lock); |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 9495789c425b..842cb8c2f65d 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -2033,17 +2033,16 @@ static int nfs4_recall_slot(struct nfs_client *clp) | |||
2033 | return 0; | 2033 | return 0; |
2034 | nfs4_begin_drain_session(clp); | 2034 | nfs4_begin_drain_session(clp); |
2035 | fc_tbl = &clp->cl_session->fc_slot_table; | 2035 | fc_tbl = &clp->cl_session->fc_slot_table; |
2036 | new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_max_slots, GFP_NOFS); | 2036 | new = nfs4_alloc_slots(fc_tbl, fc_tbl->target_highest_slotid + 1, GFP_NOFS); |
2037 | if (!new) | 2037 | if (!new) |
2038 | return -ENOMEM; | 2038 | return -ENOMEM; |
2039 | 2039 | ||
2040 | spin_lock(&fc_tbl->slot_tbl_lock); | 2040 | spin_lock(&fc_tbl->slot_tbl_lock); |
2041 | for (i = 0; i < fc_tbl->target_max_slots; i++) | 2041 | for (i = 0; i <= fc_tbl->target_highest_slotid; i++) |
2042 | new[i].seq_nr = fc_tbl->slots[i].seq_nr; | 2042 | new[i].seq_nr = fc_tbl->slots[i].seq_nr; |
2043 | old = fc_tbl->slots; | 2043 | old = fc_tbl->slots; |
2044 | fc_tbl->slots = new; | 2044 | fc_tbl->slots = new; |
2045 | fc_tbl->max_slots = fc_tbl->target_max_slots; | 2045 | fc_tbl->max_slots = fc_tbl->target_highest_slotid + 1; |
2046 | fc_tbl->target_max_slots = 0; | ||
2047 | clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots; | 2046 | clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots; |
2048 | spin_unlock(&fc_tbl->slot_tbl_lock); | 2047 | spin_unlock(&fc_tbl->slot_tbl_lock); |
2049 | 2048 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 27b0fec1a6b0..05d34f1fcc19 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -5552,8 +5552,8 @@ static int decode_sequence(struct xdr_stream *xdr, | |||
5552 | } | 5552 | } |
5553 | /* highest slot id - currently not processed */ | 5553 | /* highest slot id - currently not processed */ |
5554 | dummy = be32_to_cpup(p++); | 5554 | dummy = be32_to_cpup(p++); |
5555 | /* target highest slot id - currently not processed */ | 5555 | /* target highest slot id */ |
5556 | dummy = be32_to_cpup(p++); | 5556 | res->sr_target_highest_slotid = be32_to_cpup(p++); |
5557 | /* result flags */ | 5557 | /* result flags */ |
5558 | res->sr_status_flags = be32_to_cpup(p); | 5558 | res->sr_status_flags = be32_to_cpup(p); |
5559 | status = 0; | 5559 | status = 0; |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b0412873d29c..57d406997def 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -217,8 +217,9 @@ struct nfs4_slot_table { | |||
217 | u32 max_slots; /* # slots in table */ | 217 | u32 max_slots; /* # slots in table */ |
218 | u32 highest_used_slotid; /* sent to server on each SEQ. | 218 | u32 highest_used_slotid; /* sent to server on each SEQ. |
219 | * op for dynamic resizing */ | 219 | * op for dynamic resizing */ |
220 | u32 target_max_slots; /* Set by CB_RECALL_SLOT as | 220 | u32 target_highest_slotid; /* Server max_slot target */ |
221 | * the new max_slots */ | 221 | unsigned long generation; /* Generation counter for |
222 | target_highest_slotid */ | ||
222 | struct completion complete; | 223 | struct completion complete; |
223 | }; | 224 | }; |
224 | 225 | ||
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index deb31bbbb857..08c47db7417f 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -188,6 +188,7 @@ struct nfs4_channel_attrs { | |||
188 | /* nfs41 sessions slot seqid */ | 188 | /* nfs41 sessions slot seqid */ |
189 | struct nfs4_slot { | 189 | struct nfs4_slot { |
190 | struct nfs4_slot_table *table; | 190 | struct nfs4_slot_table *table; |
191 | unsigned long generation; | ||
191 | unsigned long renewal_time; | 192 | unsigned long renewal_time; |
192 | u32 slot_nr; | 193 | u32 slot_nr; |
193 | u32 seq_nr; | 194 | u32 seq_nr; |
@@ -202,6 +203,7 @@ struct nfs4_sequence_res { | |||
202 | struct nfs4_slot *sr_slot; /* slot used to send request */ | 203 | struct nfs4_slot *sr_slot; /* slot used to send request */ |
203 | int sr_status; /* sequence operation status */ | 204 | int sr_status; /* sequence operation status */ |
204 | u32 sr_status_flags; | 205 | u32 sr_status_flags; |
206 | u32 sr_target_highest_slotid; | ||
205 | }; | 207 | }; |
206 | 208 | ||
207 | struct nfs4_get_lease_time_args { | 209 | struct nfs4_get_lease_time_args { |