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
parent14f9a6076f5388f3fd6341ad4b841337b28fc825 (diff)
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,
169static int 169static int
170nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds) 170nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
171{ 171{
172 struct nfs_client *clp; 172 struct nfs_client *clp = ERR_PTR(-EIO);
173 struct nfs4_pnfs_ds_addr *da; 173 struct nfs4_pnfs_ds_addr *da;
174 int status = 0; 174 int status = 0;
175 175
@@ -178,13 +178,17 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
178 178
179 BUG_ON(list_empty(&ds->ds_addrs)); 179 BUG_ON(list_empty(&ds->ds_addrs));
180 180
181 da = list_first_entry(&ds->ds_addrs, struct nfs4_pnfs_ds_addr, da_node); 181 list_for_each_entry(da, &ds->ds_addrs, da_node) {
182 dprintk("%s: using the first address for DS %s: %s\n", 182 dprintk("%s: DS %s: trying address %s\n",
183 __func__, ds->ds_remotestr, da->da_remotestr); 183 __func__, ds->ds_remotestr, da->da_remotestr);
184 184
185 clp = nfs4_set_ds_client(mds_srv->nfs_client, 185 clp = nfs4_set_ds_client(mds_srv->nfs_client,
186 (struct sockaddr *)&da->da_addr, 186 (struct sockaddr *)&da->da_addr,
187 da->da_addrlen, IPPROTO_TCP); 187 da->da_addrlen, IPPROTO_TCP);
188 if (!IS_ERR(clp))
189 break;
190 }
191
188 if (IS_ERR(clp)) { 192 if (IS_ERR(clp)) {
189 status = PTR_ERR(clp); 193 status = PTR_ERR(clp);
190 goto out; 194 goto out;