aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-11-20 14:45:48 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-12-05 18:30:42 -0500
commit97e548a93de213b149eea025a97d88e28143b445 (patch)
tree7536bccb32193adf105bc1ede6462d6482589f4e
parent1b285ff16ab52fb401aed7ce70abed4bb65b30b5 (diff)
NFSv4.1: Support dynamic resizing of the session slot table
Allow the server to control the size of the session slot table by adjusting the value of sr_target_max_slots in the reply to the SEQUENCE operation. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4proc.c12
-rw-r--r--fs/nfs/nfs4state.c6
-rw-r--r--include/linux/nfs_fs_sb.h1
3 files changed, 14 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 62212231ce62..1792ece8b53c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -492,10 +492,17 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
492static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, 492static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl,
493 u32 target_highest_slotid) 493 u32 target_highest_slotid)
494{ 494{
495 unsigned int max_slotid, i;
496
495 if (tbl->target_highest_slotid == target_highest_slotid) 497 if (tbl->target_highest_slotid == target_highest_slotid)
496 return; 498 return;
497 tbl->target_highest_slotid = target_highest_slotid; 499 tbl->target_highest_slotid = target_highest_slotid;
498 tbl->generation++; 500 tbl->generation++;
501
502 max_slotid = min(tbl->max_slots - 1, tbl->target_highest_slotid);
503 for (i = tbl->max_slotid + 1; i <= max_slotid; i++)
504 rpc_wake_up_next(&tbl->slot_tbl_waitq);
505 tbl->max_slotid = max_slotid;
499} 506}
500 507
501void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, 508void nfs41_set_target_slotid(struct nfs4_slot_table *tbl,
@@ -622,8 +629,8 @@ static struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
622 dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n", 629 dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
623 __func__, tbl->used_slots[0], tbl->highest_used_slotid, 630 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
624 tbl->max_slots); 631 tbl->max_slots);
625 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots); 632 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1);
626 if (slotid >= tbl->max_slots) 633 if (slotid > tbl->max_slotid)
627 goto out; 634 goto out;
628 __set_bit(slotid, tbl->used_slots); 635 __set_bit(slotid, tbl->used_slots);
629 if (slotid > tbl->highest_used_slotid || 636 if (slotid > tbl->highest_used_slotid ||
@@ -5744,6 +5751,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
5744 tbl->highest_used_slotid = NFS4_NO_SLOT; 5751 tbl->highest_used_slotid = NFS4_NO_SLOT;
5745 tbl->target_highest_slotid = max_slots - 1; 5752 tbl->target_highest_slotid = max_slots - 1;
5746 tbl->server_highest_slotid = max_slots - 1; 5753 tbl->server_highest_slotid = max_slots - 1;
5754 tbl->max_slotid = max_slots - 1;
5747 for (i = 0; i < tbl->max_slots; i++) 5755 for (i = 0; i < tbl->max_slots; i++)
5748 tbl->slots[i].seq_nr = ivalue; 5756 tbl->slots[i].seq_nr = ivalue;
5749 spin_unlock(&tbl->slot_tbl_lock); 5757 spin_unlock(&tbl->slot_tbl_lock);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 842cb8c2f65d..1b7fa73c9436 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -254,15 +254,14 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
254{ 254{
255 struct nfs4_session *ses = clp->cl_session; 255 struct nfs4_session *ses = clp->cl_session;
256 struct nfs4_slot_table *tbl; 256 struct nfs4_slot_table *tbl;
257 int max_slots; 257 unsigned int i;
258 258
259 if (ses == NULL) 259 if (ses == NULL)
260 return; 260 return;
261 tbl = &ses->fc_slot_table; 261 tbl = &ses->fc_slot_table;
262 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) { 262 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
263 spin_lock(&tbl->slot_tbl_lock); 263 spin_lock(&tbl->slot_tbl_lock);
264 max_slots = tbl->max_slots; 264 for (i = 0; i <= tbl->max_slotid; i++) {
265 while (max_slots--) {
266 if (rpc_wake_up_first(&tbl->slot_tbl_waitq, 265 if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
267 nfs4_set_task_privileged, 266 nfs4_set_task_privileged,
268 NULL) == NULL) 267 NULL) == NULL)
@@ -2043,6 +2042,7 @@ static int nfs4_recall_slot(struct nfs_client *clp)
2043 old = fc_tbl->slots; 2042 old = fc_tbl->slots;
2044 fc_tbl->slots = new; 2043 fc_tbl->slots = new;
2045 fc_tbl->max_slots = fc_tbl->target_highest_slotid + 1; 2044 fc_tbl->max_slots = fc_tbl->target_highest_slotid + 1;
2045 fc_tbl->max_slotid = fc_tbl->target_highest_slotid;
2046 clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots; 2046 clp->cl_session->fc_attrs.max_reqs = fc_tbl->max_slots;
2047 spin_unlock(&fc_tbl->slot_tbl_lock); 2047 spin_unlock(&fc_tbl->slot_tbl_lock);
2048 2048
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 646e64bbff4c..30715508fade 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -215,6 +215,7 @@ struct nfs4_slot_table {
215 spinlock_t slot_tbl_lock; 215 spinlock_t slot_tbl_lock;
216 struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */ 216 struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
217 u32 max_slots; /* # slots in table */ 217 u32 max_slots; /* # slots in table */
218 u32 max_slotid; /* Max allowed slotid value */
218 u32 highest_used_slotid; /* sent to server on each SEQ. 219 u32 highest_used_slotid; /* sent to server on each SEQ.
219 * op for dynamic resizing */ 220 * op for dynamic resizing */
220 u32 target_highest_slotid; /* Server max_slot target */ 221 u32 target_highest_slotid; /* Server max_slot target */