aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/nfs4proc.c25
-rw-r--r--fs/nfs/nfs4state.c7
-rw-r--r--fs/nfs/nfs4xdr.c4
-rw-r--r--include/linux/nfs_fs_sb.h5
-rw-r--r--include/linux/nfs_xdr.h2
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);
581out: 581out:
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 */
492static 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
501static 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);
509out:
510 spin_unlock(&tbl->slot_tbl_lock);
511}
512
491static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 513static 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
587out: 611out:
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 */
189struct nfs4_slot { 189struct 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
207struct nfs4_get_lease_time_args { 209struct nfs4_get_lease_time_args {