aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-05-29 09:06:58 -0400
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:32 -0500
commit7405f9e195aab95e147cc225f203d11fa74b65a8 (patch)
tree4718b4f99523f3885a5fa2486a9d27fc0ba2f0cd /fs/nfs
parent6b7f3cf96364eaf597940cb5c68a682894829915 (diff)
nfs41: pull nfs4_ds_connect from file layout to generic pnfs
It can be reused by flexfiles layout client. Reviewed-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Tom Haynes <Thomas.Haynes@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/filelayout/filelayoutdev.c78
-rw-r--r--fs/nfs/pnfs.h3
-rw-r--r--fs/nfs/pnfs_nfs.c81
3 files changed, 89 insertions, 73 deletions
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c
index c7f6041a287f..27bdd8ce177e 100644
--- a/fs/nfs/filelayout/filelayoutdev.c
+++ b/fs/nfs/filelayout/filelayoutdev.c
@@ -41,51 +41,6 @@
41static unsigned int dataserver_timeo = NFS4_DEF_DS_TIMEO; 41static unsigned int dataserver_timeo = NFS4_DEF_DS_TIMEO;
42static unsigned int dataserver_retrans = NFS4_DEF_DS_RETRANS; 42static unsigned int dataserver_retrans = NFS4_DEF_DS_RETRANS;
43 43
44/*
45 * Create an rpc connection to the nfs4_pnfs_ds data server
46 * Currently only supports IPv4 and IPv6 addresses
47 */
48static int
49nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
50{
51 struct nfs_client *clp = ERR_PTR(-EIO);
52 struct nfs4_pnfs_ds_addr *da;
53 int status = 0;
54
55 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
56 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
57
58 list_for_each_entry(da, &ds->ds_addrs, da_node) {
59 dprintk("%s: DS %s: trying address %s\n",
60 __func__, ds->ds_remotestr, da->da_remotestr);
61
62 clp = nfs4_set_ds_client(mds_srv->nfs_client,
63 (struct sockaddr *)&da->da_addr,
64 da->da_addrlen, IPPROTO_TCP,
65 dataserver_timeo, dataserver_retrans);
66 if (!IS_ERR(clp))
67 break;
68 }
69
70 if (IS_ERR(clp)) {
71 status = PTR_ERR(clp);
72 goto out;
73 }
74
75 status = nfs4_init_ds_session(clp, mds_srv->nfs_client->cl_lease_time);
76 if (status)
77 goto out_put;
78
79 smp_wmb();
80 ds->ds_clp = clp;
81 dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
82out:
83 return status;
84out_put:
85 nfs_put_client(clp);
86 goto out;
87}
88
89void 44void
90nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) 45nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
91{ 46{
@@ -302,22 +257,7 @@ nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j)
302 return flseg->fh_array[i]; 257 return flseg->fh_array[i];
303} 258}
304 259
305static void nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds) 260/* Upon return, either ds is connected, or ds is NULL */
306{
307 might_sleep();
308 wait_on_bit_action(&ds->ds_state, NFS4DS_CONNECTING,
309 nfs_wait_bit_killable, TASK_KILLABLE);
310}
311
312static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
313{
314 smp_mb__before_atomic();
315 clear_bit(NFS4DS_CONNECTING, &ds->ds_state);
316 smp_mb__after_atomic();
317 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING);
318}
319
320
321struct nfs4_pnfs_ds * 261struct nfs4_pnfs_ds *
322nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) 262nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
323{ 263{
@@ -325,6 +265,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
325 struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx]; 265 struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
326 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); 266 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
327 struct nfs4_pnfs_ds *ret = ds; 267 struct nfs4_pnfs_ds *ret = ds;
268 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode);
328 269
329 if (ds == NULL) { 270 if (ds == NULL) {
330 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", 271 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
@@ -336,18 +277,9 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
336 if (ds->ds_clp) 277 if (ds->ds_clp)
337 goto out_test_devid; 278 goto out_test_devid;
338 279
339 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 280 nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
340 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); 281 dataserver_retrans);
341 int err; 282
342
343 err = nfs4_ds_connect(s, ds);
344 if (err)
345 nfs4_mark_deviceid_unavailable(devid);
346 nfs4_clear_ds_conn_bit(ds);
347 } else {
348 /* Either ds is connected, or ds is NULL */
349 nfs4_wait_ds_connect(ds);
350 }
351out_test_devid: 283out_test_devid:
352 if (filelayout_test_devid_unavailable(devid)) 284 if (filelayout_test_devid_unavailable(devid))
353 ret = NULL; 285 ret = NULL;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 403d7bb67c41..9a8937c31d97 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -312,6 +312,9 @@ void pnfs_generic_write_commit_done(struct rpc_task *task, void *data);
312void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); 312void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
313struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, 313struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
314 gfp_t gfp_flags); 314 gfp_t gfp_flags);
315void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
316 struct nfs4_deviceid_node *devid, unsigned int timeo,
317 unsigned int retrans);
315struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, 318struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
316 struct xdr_stream *xdr, 319 struct xdr_stream *xdr,
317 gfp_t gfp_flags); 320 gfp_t gfp_flags);
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index 81ec449138a8..5a92e76c6c53 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -11,6 +11,7 @@
11#include <linux/nfs_page.h> 11#include <linux/nfs_page.h>
12#include <linux/sunrpc/addr.h> 12#include <linux/sunrpc/addr.h>
13 13
14#include "nfs4session.h"
14#include "internal.h" 15#include "internal.h"
15#include "pnfs.h" 16#include "pnfs.h"
16 17
@@ -534,6 +535,86 @@ out:
534} 535}
535EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_add); 536EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_add);
536 537
538static void nfs4_wait_ds_connect(struct nfs4_pnfs_ds *ds)
539{
540 might_sleep();
541 wait_on_bit(&ds->ds_state, NFS4DS_CONNECTING,
542 TASK_KILLABLE);
543}
544
545static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
546{
547 smp_mb__before_atomic();
548 clear_bit(NFS4DS_CONNECTING, &ds->ds_state);
549 smp_mb__after_atomic();
550 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING);
551}
552
553static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv,
554 struct nfs4_pnfs_ds *ds,
555 unsigned int timeo,
556 unsigned int retrans)
557{
558 struct nfs_client *clp = ERR_PTR(-EIO);
559 struct nfs4_pnfs_ds_addr *da;
560 int status = 0;
561
562 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
563 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
564
565 list_for_each_entry(da, &ds->ds_addrs, da_node) {
566 dprintk("%s: DS %s: trying address %s\n",
567 __func__, ds->ds_remotestr, da->da_remotestr);
568
569 clp = nfs4_set_ds_client(mds_srv->nfs_client,
570 (struct sockaddr *)&da->da_addr,
571 da->da_addrlen, IPPROTO_TCP,
572 timeo, retrans);
573 if (!IS_ERR(clp))
574 break;
575 }
576
577 if (IS_ERR(clp)) {
578 status = PTR_ERR(clp);
579 goto out;
580 }
581
582 status = nfs4_init_ds_session(clp, mds_srv->nfs_client->cl_lease_time);
583 if (status)
584 goto out_put;
585
586 smp_wmb();
587 ds->ds_clp = clp;
588 dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
589out:
590 return status;
591out_put:
592 nfs_put_client(clp);
593 goto out;
594}
595
596/*
597 * Create an rpc connection to the nfs4_pnfs_ds data server.
598 * Currently only supports IPv4 and IPv6 addresses.
599 * If connection fails, make devid unavailable.
600 */
601void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
602 struct nfs4_deviceid_node *devid, unsigned int timeo,
603 unsigned int retrans)
604{
605 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
606 int err = 0;
607
608 err = _nfs4_pnfs_ds_connect(mds_srv, ds, timeo, retrans);
609 if (err)
610 nfs4_mark_deviceid_unavailable(devid);
611 nfs4_clear_ds_conn_bit(ds);
612 } else {
613 nfs4_wait_ds_connect(ds);
614 }
615}
616EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect);
617
537/* 618/*
538 * Currently only supports ipv4, ipv6 and one multi-path address. 619 * Currently only supports ipv4, ipv6 and one multi-path address.
539 */ 620 */