Blob Blame History Raw
From: NeilBrown <neilb@suse.com>
Subject: Fix problem with sharetransport= and NFSv4.
References: bsc#1114893
Patch-mainline: Never, upstream don't like sharetransport=

The sharetransport= mount option allows different mounts to use
different TCP connections (transports), which can sometimes help
performance.  Unfortunately the transport identifier was not included
in the client-id send in SETCLIENTID, so all transports looked the
same to the server.  This causes confusion.

So add the transport id into the client id string.

Signed-off-by: NeilBrown <neilb@suse.com>
Acked-by: NeilBrown <neilb@suse.com>

---
 fs/nfs/nfs4proc.c |   34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5370,6 +5370,8 @@ nfs4_init_nonuniform_client_string(struc
 		1 +
 		strlen(rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO)) +
 		1;
+	if (clp->cl_xprt_id != 0)
+		len += ilog2(clp->cl_xprt_id)/3 + 2;
 	rcu_read_unlock();
 
 	if (len > NFS4_OPAQUE_LIMIT + 1)
@@ -5385,10 +5387,17 @@ nfs4_init_nonuniform_client_string(struc
 		return -ENOMEM;
 
 	rcu_read_lock();
-	scnprintf(str, len, "Linux NFSv4.0 %s/%s %s",
-			clp->cl_ipaddr,
-			rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
-			rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO));
+	if (clp->cl_xprt_id != 0)
+		scnprintf(str, len, "Linux NFSv4.0 %s/%s %s %d",
+			  clp->cl_ipaddr,
+			  rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
+			  rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO),
+			  clp->cl_xprt_id);
+	else
+		scnprintf(str, len, "Linux NFSv4.0 %s/%s %s",
+			  clp->cl_ipaddr,
+			  rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
+			  rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO));
 	rcu_read_unlock();
 
 	clp->cl_owner_id = str;
@@ -5404,6 +5413,8 @@ nfs4_init_uniquifier_client_string(struc
 	len = 10 + 10 + 1 + 10 + 1 +
 		strlen(nfs4_client_id_uniquifier) + 1 +
 		strlen(clp->cl_rpcclient->cl_nodename) + 1;
+	if (clp->cl_xprt_id != 0)
+		len += ilog2(clp->cl_xprt_id)/3 + 2;
 
 	if (len > NFS4_OPAQUE_LIMIT + 1)
 		return -EINVAL;
@@ -5417,10 +5428,17 @@ nfs4_init_uniquifier_client_string(struc
 	if (!str)
 		return -ENOMEM;
 
-	scnprintf(str, len, "Linux NFSv%u.%u %s/%s",
-			clp->rpc_ops->version, clp->cl_minorversion,
-			nfs4_client_id_uniquifier,
-			clp->cl_rpcclient->cl_nodename);
+	if (clp->cl_xprt_id != 0)
+		scnprintf(str, len, "Linux NFSv%u.%u %s/%s %d",
+			  clp->rpc_ops->version, clp->cl_minorversion,
+			  nfs4_client_id_uniquifier,
+			  clp->cl_rpcclient->cl_nodename,
+			  clp->cl_xprt_id);
+	else
+		scnprintf(str, len, "Linux NFSv%u.%u %s/%s",
+			  clp->rpc_ops->version, clp->cl_minorversion,
+			  nfs4_client_id_uniquifier,
+			  clp->cl_rpcclient->cl_nodename);
 	clp->cl_owner_id = str;
 	return 0;
 }