diff mbox series

[for-6.11,12/29] nfs/flexfiles: check local DS when making DS connections

Message ID 20240607142646.20924-13-snitzer@kernel.org (mailing list archive)
State New
Headers show
Series nfs/nfsd: add support for localio bypass | expand

Commit Message

Mike Snitzer June 7, 2024, 2:26 p.m. UTC
From: Peng Tao <tao.peng@primarydata.com>

Do this by creating DS connection and check local IP address.
If it matches DS address (ignoring port), mark mirror_ds->local_ds
as true so that later we know if local DS IO is possible.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Lance Shelton <lance.shelton@hammerspace.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
 fs/nfs/flexfilelayout/flexfilelayoutdev.c | 25 +++++++++++++++++++++++
 1 file changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index e028f5a0ef5f..af329d9b7d1e 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -348,6 +348,22 @@  ff_layout_init_mirror_ds(struct pnfs_layout_hdr *lo,
 	return false;
 }
 
+static bool ff_layout_ds_is_local(struct nfs4_pnfs_ds *ds)
+{
+	struct nfs_local_addr *addr;
+	struct sockaddr *sap;
+	struct nfs4_pnfs_ds_addr *da;
+
+	list_for_each_entry(da, &ds->ds_addrs, da_node) {
+		sap = (struct sockaddr *)&da->da_addr;
+		list_for_each_entry(addr, &ds->ds_clp->cl_local_addrs, cl_addrs)
+			if (rpc_cmp_addr((struct sockaddr *)&addr->address, sap))
+				return true;
+	}
+
+	return false;
+}
+
 /**
  * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call
  * @lseg: the layout segment we're operating on
@@ -395,6 +411,15 @@  nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
 
 	/* connect success, check rsize/wsize limit */
 	if (!status) {
+		/*
+		 * ds_clp is put in destroy_ds().
+		 * keep ds_clp even if DS is local, so that if local IO cannot
+		 * proceed somehow, we can fall back to NFS whenever we want.
+		 */
+		if (ff_layout_ds_is_local(ds)) {
+			dprintk("%s: found local DS\n", __func__);
+			nfs_local_enable(ds->ds_clp);
+		}
 		max_payload =
 			nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
 				       NULL);