Skip to content

Commit dff5853

Browse files
Olga KornievskaiaTrond Myklebust
authored andcommitted
NFSv4.1: fix handling of backchannel binding in BIND_CONN_TO_SESSION
Currently, if the client sends BIND_CONN_TO_SESSION with NFS4_CDFC4_FORE_OR_BOTH but only gets NFS4_CDFS4_FORE back it ignores that it wasn't able to enable a backchannel. To make sure, the client sends BIND_CONN_TO_SESSION as the first operation on the connections (ie., no other session compounds haven't been sent before), and if the client's request to bind the backchannel is not satisfied, then reset the connection and retry. Cc: [email protected] Signed-off-by: Olga Kornievskaia <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent 7c4310f commit dff5853

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

fs/nfs/nfs4proc.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7891,6 +7891,7 @@ static void
78917891
nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
78927892
{
78937893
struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp;
7894+
struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp;
78947895
struct nfs_client *clp = args->client;
78957896

78967897
switch (task->tk_status) {
@@ -7899,6 +7900,12 @@ nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata)
78997900
nfs4_schedule_session_recovery(clp->cl_session,
79007901
task->tk_status);
79017902
}
7903+
if (args->dir == NFS4_CDFC4_FORE_OR_BOTH &&
7904+
res->dir != NFS4_CDFS4_BOTH) {
7905+
rpc_task_close_connection(task);
7906+
if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES)
7907+
rpc_restart_call(task);
7908+
}
79027909
}
79037910

79047911
static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = {
@@ -7921,6 +7928,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
79217928
struct nfs41_bind_conn_to_session_args args = {
79227929
.client = clp,
79237930
.dir = NFS4_CDFC4_FORE_OR_BOTH,
7931+
.retries = 0,
79247932
};
79257933
struct nfs41_bind_conn_to_session_res res;
79267934
struct rpc_message msg = {

include/linux/nfs_xdr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,11 +1317,13 @@ struct nfs41_impl_id {
13171317
struct nfstime4 date;
13181318
};
13191319

1320+
#define MAX_BIND_CONN_TO_SESSION_RETRIES 3
13201321
struct nfs41_bind_conn_to_session_args {
13211322
struct nfs_client *client;
13221323
struct nfs4_sessionid sessionid;
13231324
u32 dir;
13241325
bool use_conn_in_rdma_mode;
1326+
int retries;
13251327
};
13261328

13271329
struct nfs41_bind_conn_to_session_res {

include/linux/sunrpc/clnt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,9 @@ static inline int rpc_reply_expected(struct rpc_task *task)
242242
(task->tk_msg.rpc_proc->p_decode != NULL);
243243
}
244244

245+
static inline void rpc_task_close_connection(struct rpc_task *task)
246+
{
247+
if (task->tk_xprt)
248+
xprt_force_disconnect(task->tk_xprt);
249+
}
245250
#endif /* _LINUX_SUNRPC_CLNT_H */

0 commit comments

Comments
 (0)