From: Peng Tao <tao.peng@xxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxx> Signed-off-by: Lance Shelton <lance.shelton@xxxxxxxxxxxxxxx> Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> --- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) 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); -- 2.44.0