summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2019-10-17 11:13:54 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2019-11-03 21:28:45 -0500
commite6237b6feb37582fbd6bd7a8336d1256a6b4b4f9 (patch)
treee58abfc21a4940c9191f9772605d7cf9c4c991e9 /fs
parent52f98f1a2ddd2bb561f2c7e3b19a81d816a63118 (diff)
downloadlinux-e6237b6feb37582fbd6bd7a8336d1256a6b4b4f9.tar.gz
linux-e6237b6feb37582fbd6bd7a8336d1256a6b4b4f9.tar.bz2
linux-e6237b6feb37582fbd6bd7a8336d1256a6b4b4f9.zip
NFSv4.1: Don't rebind to the same source port when reconnecting to the server
NFSv2, v3 and NFSv4 servers often have duplicate replay caches that look at the source port when deciding whether or not an RPC call is a replay of a previous call. This requires clients to perform strange TCP gymnastics in order to ensure that when they reconnect to the server, they bind to the same source port. NFSv4.1 and NFSv4.2 have sessions that provide proper replay semantics, that do not look at the source port of the connection. This patch therefore ensures they can ignore the rebind requirement. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/host.c3
-rw-r--r--fs/nfs/client.c3
-rw-r--r--fs/nfs/nfs4client.c5
3 files changed, 9 insertions, 2 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 7d46fafdbbe5..0afb6d59bad0 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -464,7 +464,8 @@ nlm_bind_host(struct nlm_host *host)
.version = host->h_version,
.authflavor = RPC_AUTH_UNIX,
.flags = (RPC_CLNT_CREATE_NOPING |
- RPC_CLNT_CREATE_AUTOBIND),
+ RPC_CLNT_CREATE_AUTOBIND |
+ RPC_CLNT_CREATE_REUSEPORT),
.cred = host->h_cred,
};
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index bd6575ee3b8e..02110a30a49e 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -523,6 +523,8 @@ int nfs_create_rpc_client(struct nfs_client *clp,
args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_NOPING;
+ if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
+ args.flags |= RPC_CLNT_CREATE_REUSEPORT;
if (!IS_ERR(clp->cl_rpcclient))
return 0;
@@ -670,6 +672,7 @@ static int nfs_init_server(struct nfs_server *server,
.timeparms = &timeparms,
.cred = server->cred,
.nconnect = data->nfs_server.nconnect,
+ .init_flags = (1UL << NFS_CS_REUSEPORT),
};
struct nfs_client *clp;
int error;
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index ebc960dd89ff..abd5af77fe94 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -879,8 +879,11 @@ static int nfs4_set_client(struct nfs_server *server,
};
struct nfs_client *clp;
- if (minorversion > 0 && proto == XPRT_TRANSPORT_TCP)
+ if (minorversion == 0)
+ __set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
+ else if (proto == XPRT_TRANSPORT_TCP)
cl_init.nconnect = nconnect;
+
if (server->flags & NFS_MOUNT_NORESVPORT)
__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
if (server->options & NFS_OPTION_MIGRATION)