aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-05-30 06:15:59 -0400
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:35 -0500
commit5f01d9539496577b9ee62e213f4122a2a209550c (patch)
treeb6313926f5567e019c1800f9c15f2f7475ac21f3 /fs
parent30626f9c32f0ad5e2c4173f10fb4b1358bbba6ec (diff)
nfs41: create NFSv3 DS connection if specified
Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Tom Haynes <Thomas.Haynes@primarydata.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/nfs4super.c3
-rw-r--r--fs/nfs/pnfs.h7
-rw-r--r--fs/nfs/pnfs_nfs.c88
3 files changed, 93 insertions, 5 deletions
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 6f340f02f2ba..48cea3c30e5d 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -346,6 +346,9 @@ out:
346 346
347static void __exit exit_nfs_v4(void) 347static void __exit exit_nfs_v4(void)
348{ 348{
349 /* Not called in the _init(), conditionally loaded */
350 nfs4_pnfs_v3_ds_connect_unload();
351
349 unregister_nfs_version(&nfs_v4); 352 unregister_nfs_version(&nfs_v4);
350 nfs4_unregister_sysctl(); 353 nfs4_unregister_sysctl();
351 nfs_idmap_quit(); 354 nfs_idmap_quit();
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 70ffec135696..c39882191651 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -323,9 +323,10 @@ void pnfs_generic_write_commit_done(struct rpc_task *task, void *data);
323void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); 323void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds);
324struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, 324struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs,
325 gfp_t gfp_flags); 325 gfp_t gfp_flags);
326void nfs4_pnfs_v3_ds_connect_unload(void);
326void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 327void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
327 struct nfs4_deviceid_node *devid, unsigned int timeo, 328 struct nfs4_deviceid_node *devid, unsigned int timeo,
328 unsigned int retrans, u32 versoin, u32 minor_version, 329 unsigned int retrans, u32 version, u32 minor_version,
329 rpc_authflavor_t au_flavor); 330 rpc_authflavor_t au_flavor);
330struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, 331struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
331 struct xdr_stream *xdr, 332 struct xdr_stream *xdr,
@@ -615,6 +616,10 @@ static inline struct nfs4_threshold *pnfs_mdsthreshold_alloc(void)
615 return NULL; 616 return NULL;
616} 617}
617 618
619static inline void nfs4_pnfs_v3_ds_connect_unload(void)
620{
621}
622
618#endif /* CONFIG_NFS_V4_1 */ 623#endif /* CONFIG_NFS_V4_1 */
619 624
620#endif /* FS_NFS_PNFS_H */ 625#endif /* FS_NFS_PNFS_H */
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index ad211a4e1874..23c851d4c9a9 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -10,6 +10,7 @@
10#include <linux/nfs_fs.h> 10#include <linux/nfs_fs.h>
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#include <linux/module.h>
13 14
14#include "nfs4session.h" 15#include "nfs4session.h"
15#include "internal.h" 16#include "internal.h"
@@ -550,7 +551,75 @@ static void nfs4_clear_ds_conn_bit(struct nfs4_pnfs_ds *ds)
550 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING); 551 wake_up_bit(&ds->ds_state, NFS4DS_CONNECTING);
551} 552}
552 553
553static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, 554static struct nfs_client *(*get_v3_ds_connect)(
555 struct nfs_client *mds_clp,
556 const struct sockaddr *ds_addr,
557 int ds_addrlen,
558 int ds_proto,
559 unsigned int ds_timeo,
560 unsigned int ds_retrans,
561 rpc_authflavor_t au_flavor);
562
563static bool load_v3_ds_connect(void)
564{
565 if (!get_v3_ds_connect) {
566 get_v3_ds_connect = symbol_request(nfs3_set_ds_client);
567 WARN_ON_ONCE(!get_v3_ds_connect);
568 }
569
570 return(get_v3_ds_connect != NULL);
571}
572
573void __exit nfs4_pnfs_v3_ds_connect_unload(void)
574{
575 if (get_v3_ds_connect) {
576 symbol_put(nfs3_set_ds_client);
577 get_v3_ds_connect = NULL;
578 }
579}
580EXPORT_SYMBOL_GPL(nfs4_pnfs_v3_ds_connect_unload);
581
582static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
583 struct nfs4_pnfs_ds *ds,
584 unsigned int timeo,
585 unsigned int retrans,
586 rpc_authflavor_t au_flavor)
587{
588 struct nfs_client *clp = ERR_PTR(-EIO);
589 struct nfs4_pnfs_ds_addr *da;
590 int status = 0;
591
592 dprintk("--> %s DS %s au_flavor %d\n", __func__,
593 ds->ds_remotestr, au_flavor);
594
595 if (!load_v3_ds_connect())
596 goto out;
597
598 list_for_each_entry(da, &ds->ds_addrs, da_node) {
599 dprintk("%s: DS %s: trying address %s\n",
600 __func__, ds->ds_remotestr, da->da_remotestr);
601
602 clp = get_v3_ds_connect(mds_srv->nfs_client,
603 (struct sockaddr *)&da->da_addr,
604 da->da_addrlen, IPPROTO_TCP,
605 timeo, retrans, au_flavor);
606 if (!IS_ERR(clp))
607 break;
608 }
609
610 if (IS_ERR(clp)) {
611 status = PTR_ERR(clp);
612 goto out;
613 }
614
615 smp_wmb();
616 ds->ds_clp = clp;
617 dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
618out:
619 return status;
620}
621
622static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
554 struct nfs4_pnfs_ds *ds, 623 struct nfs4_pnfs_ds *ds,
555 unsigned int timeo, 624 unsigned int timeo,
556 unsigned int retrans, 625 unsigned int retrans,
@@ -562,7 +631,7 @@ static int _nfs4_pnfs_ds_connect(struct nfs_server *mds_srv,
562 int status = 0; 631 int status = 0;
563 632
564 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr, 633 dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
565 mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor); 634 au_flavor);
566 635
567 list_for_each_entry(da, &ds->ds_addrs, da_node) { 636 list_for_each_entry(da, &ds->ds_addrs, da_node) {
568 dprintk("%s: DS %s: trying address %s\n", 637 dprintk("%s: DS %s: trying address %s\n",
@@ -609,8 +678,19 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
609 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 678 if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) {
610 int err = 0; 679 int err = 0;
611 680
612 err = _nfs4_pnfs_ds_connect(mds_srv, ds, timeo, retrans, 681 if (version == 3) {
613 minor_version, au_flavor); 682 err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo,
683 retrans, au_flavor);
684 } else if (version == 4) {
685 err = _nfs4_pnfs_v4_ds_connect(mds_srv, ds, timeo,
686 retrans, minor_version,
687 au_flavor);
688 } else {
689 dprintk("%s: unsupported DS version %d\n", __func__,
690 version);
691 err = -EPROTONOSUPPORT;
692 }
693
614 if (err) 694 if (err)
615 nfs4_mark_deviceid_unavailable(devid); 695 nfs4_mark_deviceid_unavailable(devid);
616 nfs4_clear_ds_conn_bit(ds); 696 nfs4_clear_ds_conn_bit(ds);