aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayoutdev.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2011-05-31 18:48:58 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-12 13:40:27 -0400
commit7e574f0d3911c5cc60d4d2b57fee975c462d6cd0 (patch)
tree473ec4787d8f76ae0867ef92c09223989aa6abb8 /fs/nfs/nfs4filelayoutdev.c
parentNFS: Parse and store all multipath DS addresses (diff)
downloadlinux-dev-7e574f0d3911c5cc60d4d2b57fee975c462d6cd0.tar.xz
linux-dev-7e574f0d3911c5cc60d4d2b57fee975c462d6cd0.zip
NFS: pnfs: loop over multipath addrs on connect
Don't just use the first addr in the multipath list - instead, loop over addresses when calling nfs4_set_ds_client() (which calls connect) until it is successful. Although this is not real multipath support, it's a quick fix to handle when an MDS sends a list of addresses for a DS and some of the addr families are unsupported or misconfigured (like no routable ipv6 addr assigned). This will attempt all paths to the DS before giving up, instead of immediately falling back to the MDS. As before, an error encountered after a successful connect() will cause all i/o to fall back to the MDS. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayoutdev.c')
-rw-r--r--fs/nfs/nfs4filelayoutdev.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 610808a96f25..61c173b0aab3 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -169,7 +169,7 @@ _data_server_match_all_addrs_locked(struct list_head *dsaddrs1,
static int
nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
{
- struct nfs_client *clp;
+ struct nfs_client *clp = ERR_PTR(-EIO);
struct nfs4_pnfs_ds_addr *da;
int status = 0;
@@ -178,13 +178,17 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
BUG_ON(list_empty(&ds->ds_addrs));
- da = list_first_entry(&ds->ds_addrs, struct nfs4_pnfs_ds_addr, da_node);
- dprintk("%s: using the first address for DS %s: %s\n",
- __func__, ds->ds_remotestr, da->da_remotestr);
+ list_for_each_entry(da, &ds->ds_addrs, da_node) {
+ dprintk("%s: DS %s: trying address %s\n",
+ __func__, ds->ds_remotestr, da->da_remotestr);
- clp = nfs4_set_ds_client(mds_srv->nfs_client,
+ clp = nfs4_set_ds_client(mds_srv->nfs_client,
(struct sockaddr *)&da->da_addr,
da->da_addrlen, IPPROTO_TCP);
+ if (!IS_ERR(clp))
+ break;
+ }
+
if (IS_ERR(clp)) {
status = PTR_ERR(clp);
goto out;