Skip to content

Commit 04fa2c6

Browse files
androsadamsonamschuma-ntap
authored andcommitted
NFS pnfs data server multipath session trunking
Try all multipath addresses for a data server. The first address that successfully connects and creates a session is the DS mount address. All subsequent addresses are tested for session trunking and added as aliases. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent ad0849a commit 04fa2c6

File tree

4 files changed

+86
-14
lines changed

4 files changed

+86
-14
lines changed

fs/nfs/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,9 @@ extern int nfs40_walk_client_list(struct nfs_client *clp,
572572
extern int nfs41_walk_client_list(struct nfs_client *clp,
573573
struct nfs_client **result,
574574
struct rpc_cred *cred);
575+
extern int nfs4_test_session_trunk(struct rpc_clnt *,
576+
struct rpc_xprt *,
577+
void *);
575578

576579
static inline struct inode *nfs_igrab_and_active(struct inode *inode)
577580
{

fs/nfs/nfs4_fs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct nfs4_minor_version_ops {
5959
struct nfs4_lock_state *);
6060
struct nfs_seqid *
6161
(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
62+
int (*session_trunk)(struct rpc_clnt *, struct rpc_xprt *, void *);
6263
const struct rpc_call_ops *call_sync_ops;
6364
const struct nfs4_state_recovery_ops *reboot_recovery_ops;
6465
const struct nfs4_state_recovery_ops *nograce_recovery_ops;
@@ -203,6 +204,11 @@ struct nfs4_state_recovery_ops {
203204
struct rpc_cred *);
204205
};
205206

207+
struct nfs4_add_xprt_data {
208+
struct nfs_client *clp;
209+
struct rpc_cred *cred;
210+
};
211+
206212
struct nfs4_state_maintenance_ops {
207213
int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *, unsigned);
208214
struct rpc_cred * (*get_state_renewal_cred_locked)(struct nfs_client *);

fs/nfs/nfs4proc.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7353,6 +7353,37 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
73537353
return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
73547354
}
73557355

7356+
/**
7357+
* nfs4_test_session_trunk
7358+
*
7359+
* This is an add_xprt_test() test function called from
7360+
* rpc_clnt_setup_test_and_add_xprt.
7361+
*
7362+
* The rpc_xprt_switch is referrenced by rpc_clnt_setup_test_and_add_xprt
7363+
* and is dereferrenced in nfs4_exchange_id_release
7364+
*
7365+
* Upon success, add the new transport to the rpc_clnt
7366+
*
7367+
* @clnt: struct rpc_clnt to get new transport
7368+
* @xprt: the rpc_xprt to test
7369+
* @data: call data for _nfs4_proc_exchange_id.
7370+
*/
7371+
int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
7372+
void *data)
7373+
{
7374+
struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
7375+
u32 sp4_how;
7376+
7377+
dprintk("--> %s try %s\n", __func__,
7378+
xprt->address_strings[RPC_DISPLAY_ADDR]);
7379+
7380+
sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
7381+
7382+
/* Test connection for session trunking. Async exchange_id call */
7383+
return _nfs4_proc_exchange_id(adata->clp, adata->cred, sp4_how, xprt);
7384+
}
7385+
EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
7386+
73567387
static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
73577388
struct rpc_cred *cred)
73587389
{
@@ -8944,6 +8975,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
89448975
.find_root_sec = nfs41_find_root_sec,
89458976
.free_lock_state = nfs41_free_lock_state,
89468977
.alloc_seqid = nfs_alloc_no_seqid,
8978+
.session_trunk = nfs4_test_session_trunk,
89478979
.call_sync_ops = &nfs41_call_sync_ops,
89488980
.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
89498981
.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
@@ -8973,6 +9005,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
89739005
.free_lock_state = nfs41_free_lock_state,
89749006
.call_sync_ops = &nfs41_call_sync_ops,
89759007
.alloc_seqid = nfs_alloc_no_seqid,
9008+
.session_trunk = nfs4_test_session_trunk,
89769009
.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
89779010
.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
89789011
.state_renewal_ops = &nfs41_state_renewal_ops,

fs/nfs/pnfs_nfs.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -690,32 +690,62 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
690690
dprintk("%s: DS %s: trying address %s\n",
691691
__func__, ds->ds_remotestr, da->da_remotestr);
692692

693-
clp = nfs4_set_ds_client(mds_srv,
694-
(struct sockaddr *)&da->da_addr,
695-
da->da_addrlen, IPPROTO_TCP,
696-
timeo, retrans, minor_version,
697-
au_flavor);
698-
if (!IS_ERR(clp))
699-
break;
693+
if (!IS_ERR(clp) && clp->cl_mvops->session_trunk) {
694+
struct xprt_create xprt_args = {
695+
.ident = XPRT_TRANSPORT_TCP,
696+
.net = clp->cl_net,
697+
.dstaddr = (struct sockaddr *)&da->da_addr,
698+
.addrlen = da->da_addrlen,
699+
.servername = clp->cl_hostname,
700+
};
701+
struct nfs4_add_xprt_data xprtdata = {
702+
.clp = clp,
703+
.cred = nfs4_get_clid_cred(clp),
704+
};
705+
struct rpc_add_xprt_test rpcdata = {
706+
.add_xprt_test = clp->cl_mvops->session_trunk,
707+
.data = &xprtdata,
708+
};
709+
710+
/**
711+
* Test this address for session trunking and
712+
* add as an alias
713+
*/
714+
rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
715+
rpc_clnt_setup_test_and_add_xprt,
716+
&rpcdata);
717+
if (xprtdata.cred)
718+
put_rpccred(xprtdata.cred);
719+
} else {
720+
clp = nfs4_set_ds_client(mds_srv,
721+
(struct sockaddr *)&da->da_addr,
722+
da->da_addrlen, IPPROTO_TCP,
723+
timeo, retrans, minor_version,
724+
au_flavor);
725+
if (IS_ERR(clp))
726+
continue;
727+
728+
status = nfs4_init_ds_session(clp,
729+
mds_srv->nfs_client->cl_lease_time);
730+
if (status) {
731+
nfs_put_client(clp);
732+
clp = ERR_PTR(-EIO);
733+
continue;
734+
}
735+
736+
}
700737
}
701738

702739
if (IS_ERR(clp)) {
703740
status = PTR_ERR(clp);
704741
goto out;
705742
}
706743

707-
status = nfs4_init_ds_session(clp, mds_srv->nfs_client->cl_lease_time);
708-
if (status)
709-
goto out_put;
710-
711744
smp_wmb();
712745
ds->ds_clp = clp;
713746
dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
714747
out:
715748
return status;
716-
out_put:
717-
nfs_put_client(clp);
718-
goto out;
719749
}
720750

721751
/*

0 commit comments

Comments
 (0)