aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-11-26 16:16:54 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-12-05 18:30:47 -0500
commitc10e449827e6008ef5a4a71c0247c7eb73948e1b (patch)
tree7512d993fc182b24655d91ea930706451c0591e6 /fs/nfs
parent0ca3f4825ac92a10aa8f6534f765c44f22778dd3 (diff)
NFSv4.1: Ping server when our session table limits are too high
If the server requests a lower target_highest_slotid, then ensure that we ping it with at least one RPC call containing an appropriate SEQUENCE op. This ensures that the server won't need to send a recall callback in order to shrink the slot table. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4_fs.h1
-rw-r--r--fs/nfs/nfs4proc.c20
-rw-r--r--fs/nfs/nfs4state.c5
3 files changed, 23 insertions, 3 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 322bd0168ebf..8fe155ba16d1 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -321,6 +321,7 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
321 struct nfs_client **, struct rpc_cred *); 321 struct nfs_client **, struct rpc_cred *);
322extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); 322extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
323extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp); 323extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
324extern void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp);
324 325
325#else 326#else
326static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) 327static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0c35ab12a6b..ecd4ed3a4f65 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -389,6 +389,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
389{ 389{
390 struct nfs4_session *session; 390 struct nfs4_session *session;
391 struct nfs4_slot_table *tbl; 391 struct nfs4_slot_table *tbl;
392 bool send_new_highest_used_slotid = false;
392 393
393 if (!res->sr_slot) { 394 if (!res->sr_slot) {
394 /* just wake up the next guy waiting since 395 /* just wake up the next guy waiting since
@@ -400,12 +401,25 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
400 session = tbl->session; 401 session = tbl->session;
401 402
402 spin_lock(&tbl->slot_tbl_lock); 403 spin_lock(&tbl->slot_tbl_lock);
404 /* Be nice to the server: try to ensure that the last transmitted
405 * value for highest_user_slotid <= target_highest_slotid
406 */
407 if (tbl->highest_used_slotid > tbl->target_highest_slotid)
408 send_new_highest_used_slotid = true;
409
403 nfs4_free_slot(tbl, res->sr_slot); 410 nfs4_free_slot(tbl, res->sr_slot);
404 if (!nfs4_session_draining(session)) 411
405 rpc_wake_up_first(&tbl->slot_tbl_waitq, 412 if (tbl->highest_used_slotid != NFS4_NO_SLOT)
406 nfs4_set_task_privileged, NULL); 413 send_new_highest_used_slotid = false;
414 if (!nfs4_session_draining(session)) {
415 if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
416 nfs4_set_task_privileged, NULL) != NULL)
417 send_new_highest_used_slotid = false;
418 }
407 spin_unlock(&tbl->slot_tbl_lock); 419 spin_unlock(&tbl->slot_tbl_lock);
408 res->sr_slot = NULL; 420 res->sr_slot = NULL;
421 if (send_new_highest_used_slotid)
422 nfs41_server_notify_highest_slotid_update(session->clp);
409} 423}
410 424
411static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 425static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 1402283d152d..c137421f2123 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1961,6 +1961,11 @@ void nfs41_server_notify_target_slotid_update(struct nfs_client *clp)
1961 nfs41_ping_server(clp); 1961 nfs41_ping_server(clp);
1962} 1962}
1963 1963
1964void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp)
1965{
1966 nfs41_ping_server(clp);
1967}
1968
1964static void nfs4_reset_all_state(struct nfs_client *clp) 1969static void nfs4_reset_all_state(struct nfs_client *clp)
1965{ 1970{
1966 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { 1971 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {