mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
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>
This commit is contained in:
parent
0ca3f4825a
commit
c10e449827
@ -321,6 +321,7 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
|
|||||||
struct nfs_client **, struct rpc_cred *);
|
struct nfs_client **, struct rpc_cred *);
|
||||||
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
|
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
|
||||||
extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
|
extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
|
||||||
|
extern void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
|
static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
|
||||||
|
@ -389,6 +389,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
|
|||||||
{
|
{
|
||||||
struct nfs4_session *session;
|
struct nfs4_session *session;
|
||||||
struct nfs4_slot_table *tbl;
|
struct nfs4_slot_table *tbl;
|
||||||
|
bool send_new_highest_used_slotid = false;
|
||||||
|
|
||||||
if (!res->sr_slot) {
|
if (!res->sr_slot) {
|
||||||
/* just wake up the next guy waiting since
|
/* just wake up the next guy waiting since
|
||||||
@ -400,12 +401,25 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
|
|||||||
session = tbl->session;
|
session = tbl->session;
|
||||||
|
|
||||||
spin_lock(&tbl->slot_tbl_lock);
|
spin_lock(&tbl->slot_tbl_lock);
|
||||||
|
/* Be nice to the server: try to ensure that the last transmitted
|
||||||
|
* value for highest_user_slotid <= target_highest_slotid
|
||||||
|
*/
|
||||||
|
if (tbl->highest_used_slotid > tbl->target_highest_slotid)
|
||||||
|
send_new_highest_used_slotid = true;
|
||||||
|
|
||||||
nfs4_free_slot(tbl, res->sr_slot);
|
nfs4_free_slot(tbl, res->sr_slot);
|
||||||
if (!nfs4_session_draining(session))
|
|
||||||
rpc_wake_up_first(&tbl->slot_tbl_waitq,
|
if (tbl->highest_used_slotid != NFS4_NO_SLOT)
|
||||||
nfs4_set_task_privileged, NULL);
|
send_new_highest_used_slotid = false;
|
||||||
|
if (!nfs4_session_draining(session)) {
|
||||||
|
if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
|
||||||
|
nfs4_set_task_privileged, NULL) != NULL)
|
||||||
|
send_new_highest_used_slotid = false;
|
||||||
|
}
|
||||||
spin_unlock(&tbl->slot_tbl_lock);
|
spin_unlock(&tbl->slot_tbl_lock);
|
||||||
res->sr_slot = NULL;
|
res->sr_slot = NULL;
|
||||||
|
if (send_new_highest_used_slotid)
|
||||||
|
nfs41_server_notify_highest_slotid_update(session->clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
|
static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)
|
||||||
|
@ -1961,6 +1961,11 @@ void nfs41_server_notify_target_slotid_update(struct nfs_client *clp)
|
|||||||
nfs41_ping_server(clp);
|
nfs41_ping_server(clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nfs41_server_notify_highest_slotid_update(struct nfs_client *clp)
|
||||||
|
{
|
||||||
|
nfs41_ping_server(clp);
|
||||||
|
}
|
||||||
|
|
||||||
static void nfs4_reset_all_state(struct nfs_client *clp)
|
static void nfs4_reset_all_state(struct nfs_client *clp)
|
||||||
{
|
{
|
||||||
if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
|
if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user