Patch "NFSv4.1: fix pnfs MDS=DS session trunking" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    NFSv4.1: fix pnfs MDS=DS session trunking

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     nfsv4.1-fix-pnfs-mds-ds-session-trunking.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 2867234cbbfb40315c12bde4d7b744fd3754ad2f
Author: Olga Kornievskaia <kolga@xxxxxxxxxx>
Date:   Wed Aug 30 15:29:34 2023 -0400

    NFSv4.1: fix pnfs MDS=DS session trunking
    
    [ Upstream commit 806a3bc421a115fbb287c1efce63a48c54ee804b ]
    
    Currently, when GETDEVICEINFO returns multiple locations where each
    is a different IP but the server's identity is same as MDS, then
    nfs4_set_ds_client() finds the existing nfs_client structure which
    has the MDS's max_connect value (and if it's 1), then the 1st IP
    on the DS's list will get dropped due to MDS trunking rules. Other
    IPs would be added as they fall under the pnfs trunking rules.
    
    For the list of IPs the 1st goes thru calling nfs4_set_ds_client()
    which will eventually call nfs4_add_trunk() and call into
    rpc_clnt_test_and_add_xprt() which has the check for MDS trunking.
    The other IPs (after the 1st one), would call rpc_clnt_add_xprt()
    which doesn't go thru that check.
    
    nfs4_add_trunk() is called when MDS trunking is happening and it
    needs to enforce the usage of max_connect mount option of the
    1st mount. However, this shouldn't be applied to pnfs flow.
    
    Instead, this patch proposed to treat MDS=DS as DS trunking and
    make sure that MDS's max_connect limit does not apply to the
    1st IP returned in the GETDEVICEINFO list. It does so by
    marking the newly created client with a new flag NFS_CS_PNFS
    which then used to pass max_connect value to use into the
    rpc_clnt_test_and_add_xprt() instead of the existing rpc
    client's max_connect value set by the MDS connection.
    
    For example, mount was done without max_connect value set
    so MDS's rpc client has cl_max_connect=1. Upon calling into
    rpc_clnt_test_and_add_xprt() and using rpc client's value,
    the caller passes in max_connect value which is previously
    been set in the pnfs path (as a part of handling
    GETDEVICEINFO list of IPs) in nfs4_set_ds_client().
    
    However, when NFS_CS_PNFS flag is not set and we know we
    are doing MDS trunking, comparing a new IP of the same
    server, we then set the max_connect value to the
    existing MDS's value and pass that into
    rpc_clnt_test_and_add_xprt().
    
    Fixes: dc48e0abee24 ("SUNRPC enforce creation of no more than max_connect xprts")
    Signed-off-by: Olga Kornievskaia <kolga@xxxxxxxxxx>
    Signed-off-by: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index d3e2b0867dc11..84b345efcec00 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -416,6 +416,8 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old)
 		.net = old->cl_net,
 		.servername = old->cl_hostname,
 	};
+	int max_connect = test_bit(NFS_CS_PNFS, &clp->cl_flags) ?
+		clp->cl_max_connect : old->cl_max_connect;
 
 	if (clp->cl_proto != old->cl_proto)
 		return;
@@ -429,7 +431,7 @@ static void nfs4_add_trunk(struct nfs_client *clp, struct nfs_client *old)
 	xprt_args.addrlen = clp_salen;
 
 	rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args,
-			  rpc_clnt_test_and_add_xprt, NULL);
+			  rpc_clnt_test_and_add_xprt, &max_connect);
 }
 
 /**
@@ -996,6 +998,8 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
 		__set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
 
 	__set_bit(NFS_CS_DS, &cl_init.init_flags);
+	__set_bit(NFS_CS_PNFS, &cl_init.init_flags);
+	cl_init.max_connect = NFS_MAX_TRANSPORTS;
 	/*
 	 * Set an authflavor equual to the MDS value. Use the MDS nfs_client
 	 * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index ea2f7e6b1b0b5..ef8ba5fbc6503 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -48,6 +48,7 @@ struct nfs_client {
 #define NFS_CS_NOPING		6		/* - don't ping on connect */
 #define NFS_CS_DS		7		/* - Server is a DS */
 #define NFS_CS_REUSEPORT	8		/* - reuse src port on reconnect */
+#define NFS_CS_PNFS		9		/* - Server used for pnfs */
 	struct sockaddr_storage	cl_addr;	/* server identifier */
 	size_t			cl_addrlen;
 	char *			cl_hostname;	/* hostname of server */
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index ff6728e41e044..b3f6f67ed2521 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2890,19 +2890,22 @@ static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = {
  * @clnt: pointer to struct rpc_clnt
  * @xps: pointer to struct rpc_xprt_switch,
  * @xprt: pointer struct rpc_xprt
- * @dummy: unused
+ * @in_max_connect: pointer to the max_connect value for the passed in xprt transport
  */
 int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
 		struct rpc_xprt_switch *xps, struct rpc_xprt *xprt,
-		void *dummy)
+		void *in_max_connect)
 {
 	struct rpc_cb_add_xprt_calldata *data;
 	struct rpc_task *task;
+	int max_connect = clnt->cl_max_connect;
 
-	if (xps->xps_nunique_destaddr_xprts + 1 > clnt->cl_max_connect) {
+	if (in_max_connect)
+		max_connect = *(int *)in_max_connect;
+	if (xps->xps_nunique_destaddr_xprts + 1 > max_connect) {
 		rcu_read_lock();
 		pr_warn("SUNRPC: reached max allowed number (%d) did not add "
-			"transport to server: %s\n", clnt->cl_max_connect,
+			"transport to server: %s\n", max_connect,
 			rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR));
 		rcu_read_unlock();
 		return -EINVAL;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux