diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-11-20 14:45:48 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-12-05 18:30:42 -0500 |
commit | 97e548a93de213b149eea025a97d88e28143b445 (patch) | |
tree | 7536bccb32193adf105bc1ede6462d6482589f4e | |
parent | 1b285ff16ab52fb401aed7ce70abed4bb65b30b5 (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.c | 12 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 6 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 |
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) | |||
492 | static void nfs41_set_target_slotid_locked(struct nfs4_slot_table *tbl, | 492 | static 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 | ||
501 | void nfs41_set_target_slotid(struct nfs4_slot_table *tbl, | 508 | void 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 */ |