diff mbox

[Version,4,08/10] NFS test and add multipaths for session trunking

Message ID 1462993705-14673-9-git-send-email-andros@netapp.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andy Adamson May 11, 2016, 7:08 p.m. UTC
From: Andy Adamson <andros@netapp.com>

Test the multipath addresses returned by nfs4_get_pseudofs_replicas
for session trunking.

Signed-off-by: Andy Adamson <andros@netapp.com>
---
 fs/nfs/nfs4_fs.h           |   7 ++++
 fs/nfs/nfs4proc.c          | 100 ++++++++++++++++++++++++++++++++++++++++++++-
 net/sunrpc/xprtmultipath.c |   3 ++
 3 files changed, 109 insertions(+), 1 deletion(-)

Comments

Schumaker, Anna May 18, 2016, 6:23 p.m. UTC | #1
Hi Andy,

On 05/11/2016 03:08 PM, andros@netapp.com wrote:
> From: Andy Adamson <andros@netapp.com>
> 
> Test the multipath addresses returned by nfs4_get_pseudofs_replicas
> for session trunking.
> 
> Signed-off-by: Andy Adamson <andros@netapp.com>
> ---
>  fs/nfs/nfs4_fs.h           |   7 ++++
>  fs/nfs/nfs4proc.c          | 100 ++++++++++++++++++++++++++++++++++++++++++++-
>  net/sunrpc/xprtmultipath.c |   3 ++
>  3 files changed, 109 insertions(+), 1 deletion(-)
> 

<snip>

> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 8263ee8..827ae51 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -3303,6 +3304,59 @@ static int nfs4_proc_fs_locations_probe(struct nfs_server *server,
>  	return err;
>  }
>  
> +/**
> + * Test the multipath addresses returned by nfs4_get_pseudofs_replicas
> + * for session trunking.
> + *
> + * Add session trunking aliases to the cl_rpcclient
> + */
> +void nfs4_test_multipath(struct nfs4_fs_locations *locations,
> +			struct nfs_client *clp)
> +{
> +	struct nfs4_add_xprt_data xprtdata = {
> +		.clp = clp,
> +	};
> +	int i;
> +
> +	if (!clp->cl_mvops->session_trunk || locations == NULL ||
> +	    locations->nlocations <= 0)
> +		return;
> +
> +	xprtdata.cred = nfs4_get_clid_cred(clp);
> +
> +	for (i = 0; i < locations->nlocations; i++) {
> +		struct nfs4_fs_location *loc = &locations->locations[i];
> +		int i;
> +
> +		for (i = 0; i < loc->nservers; i++) {
> +			struct nfs4_string *server = &loc->servers[i];
> +			struct sockaddr_storage addr;
> +			size_t addrlen;
> +			struct xprt_create xprt_args = {
> +				.ident = XPRT_TRANSPORT_TCP,
> +				.net = clp->cl_net,
> +			};
> +
> +			addrlen = rpc_pton(clp->cl_net, server->data,
> +					server->len, (struct sockaddr *)&addr,
> +					sizeof(addr));
> +
> +			xprt_args.dstaddr = (struct sockaddr *)&addr;
> +			xprt_args.addrlen = addrlen;
> +			xprt_args.servername = server->data;
> +
> +			/**
> +			 * Check for session trunking. Add this address as
> +			 * an alias if session trunking is permitted.
> +			 */
> +			rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
> +					clp->cl_mvops->session_trunk,
> +					&xprtdata);
> +		}
> +	}
> +	if (xprtdata.cred)
> +		put_rpccred(xprtdata.cred);
> +}
>  
>  /**
>   * Probe the pseudo filesystem for an fs_locations replicas list.
> @@ -3330,7 +3384,8 @@ void nfs4_get_pseudofs_replicas(struct nfs_server *server,
>  	if (status != 0)
>  		goto out;
>  
> -	/* test replicas for session trunking here */
> +	/* test replicas for session trunking */
> +	nfs4_test_multipath(locations, server->nfs_client);
>  out:
>  	if (page)
>  		__free_page(page);
> @@ -7291,6 +7346,47 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
>  	return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
>  }
>  
> +/**
> + * nfs4_test_session_trunk - Test for session trunking with a
> + * synchronous exchange_id call. Upon success, add a new transport
> + * to the rpc_clnt
> + *
> + * @clnt: struct rpc_clnt to get new transport
> + * @xps:  the rpc_xprt_switch to hold the new transport
> + * @xprt: the rpc_xprt to test
> + * @data: call data for _nfs4_proc_exchange_id.
> + *
> + */
> +int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt_switch *xps,
> +			    struct rpc_xprt *xprt, void *data)
> +{
> +	struct nfs4_add_xprt_data *xdata = (struct nfs4_add_xprt_data *)data;
> +	u32 sp4_how;
> +	int status;
> +
> +	sp4_how = (xdata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
> +
> +	/* Ensure these stick around for the rpc call */
> +	xps = xprt_switch_get(xps);
> +	xprt = xprt_get(xprt);

I'm curious at what point during _nfs4_proc_exchange_id() these might get released?

Thanks,
Anna

> +
> +	/* Sync call */
> +	status = _nfs4_proc_exchange_id(xdata->clp, xdata->cred, sp4_how, xprt);
> +
> +	xprt_put(xprt);
> +	xprt_switch_put(xps);
> +
> +	if (status)
> +		pr_info("NFS:   %s: Session trunking failed for %s status %d\n",
> +			xdata->clp->cl_hostname,
> +			xprt->address_strings[RPC_DISPLAY_ADDR], status);
> +	else
> +		pr_info("NFS:   %s: Session trunking succeeded for %s\n",
> +			xdata->clp->cl_hostname,
> +			xprt->address_strings[RPC_DISPLAY_ADDR]);
> +	return status;
> +}
> +
>  static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
>  		struct rpc_cred *cred)
>  {
> @@ -8882,6 +8978,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
>  	.find_root_sec = nfs41_find_root_sec,
>  	.free_lock_state = nfs41_free_lock_state,
>  	.alloc_seqid = nfs_alloc_no_seqid,
> +	.session_trunk = nfs4_test_session_trunk,
>  	.call_sync_ops = &nfs41_call_sync_ops,
>  	.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
>  	.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
> @@ -8910,6 +9007,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
>  	.free_lock_state = nfs41_free_lock_state,
>  	.call_sync_ops = &nfs41_call_sync_ops,
>  	.alloc_seqid = nfs_alloc_no_seqid,
> +	.session_trunk = nfs4_test_session_trunk,
>  	.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
>  	.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
>  	.state_renewal_ops = &nfs41_state_renewal_ops,
> diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
> index e7fd769..360f64c 100644
> --- a/net/sunrpc/xprtmultipath.c
> +++ b/net/sunrpc/xprtmultipath.c
> @@ -53,6 +53,7 @@ void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
>  		xprt_switch_add_xprt_locked(xps, xprt);
>  	spin_unlock(&xps->xps_lock);
>  }
> +EXPORT_SYMBOL_GPL(rpc_xprt_switch_add_xprt);
>  
>  static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
>  		struct rpc_xprt *xprt)
> @@ -145,6 +146,7 @@ struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps)
>  		return xps;
>  	return NULL;
>  }
> +EXPORT_SYMBOL_GPL(xprt_switch_get);
>  
>  /**
>   * xprt_switch_put - Release a reference to a rpc_xprt_switch
> @@ -157,6 +159,7 @@ void xprt_switch_put(struct rpc_xprt_switch *xps)
>  	if (xps != NULL)
>  		kref_put(&xps->xps_kref, xprt_switch_free);
>  }
> +EXPORT_SYMBOL_GPL(xprt_switch_put);
>  
>  /**
>   * rpc_xprt_switch_set_roundrobin - Set a round-robin policy on rpc_xprt_switch
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Adamson, Andy May 19, 2016, 5:46 p.m. UTC | #2
DQo+IE9uIE1heSAxOCwgMjAxNiwgYXQgMjoyMyBQTSwgU2NodW1ha2VyLCBBbm5hIDxBbm5hLlNj
aHVtYWtlckBuZXRhcHAuY29tPiB3cm90ZToNCj4gDQo+IEhpIEFuZHksDQo+IA0KPiBPbiAwNS8x
MS8yMDE2IDAzOjA4IFBNLCBhbmRyb3NAbmV0YXBwLmNvbSB3cm90ZToNCj4+IEZyb206IEFuZHkg
QWRhbXNvbiA8YW5kcm9zQG5ldGFwcC5jb20+DQo+PiANCj4+IFRlc3QgdGhlIG11bHRpcGF0aCBh
ZGRyZXNzZXMgcmV0dXJuZWQgYnkgbmZzNF9nZXRfcHNldWRvZnNfcmVwbGljYXMNCj4+IGZvciBz
ZXNzaW9uIHRydW5raW5nLg0KPj4gDQo+PiBTaWduZWQtb2ZmLWJ5OiBBbmR5IEFkYW1zb24gPGFu
ZHJvc0BuZXRhcHAuY29tPg0KPj4gLS0tDQo+PiBmcy9uZnMvbmZzNF9mcy5oICAgICAgICAgICB8
ICAgNyArKysrDQo+PiBmcy9uZnMvbmZzNHByb2MuYyAgICAgICAgICB8IDEwMCArKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0NCj4+IG5ldC9zdW5ycGMveHBydG11
bHRpcGF0aC5jIHwgICAzICsrDQo+PiAzIGZpbGVzIGNoYW5nZWQsIDEwOSBpbnNlcnRpb25zKCsp
LCAxIGRlbGV0aW9uKC0pDQo+PiANCj4gDQo+IDxzbmlwPg0KPiANCj4+IGRpZmYgLS1naXQgYS9m
cy9uZnMvbmZzNHByb2MuYyBiL2ZzL25mcy9uZnM0cHJvYy5jDQo+PiBpbmRleCA4MjYzZWU4Li44
MjdhZTUxIDEwMDY0NA0KPj4gLS0tIGEvZnMvbmZzL25mczRwcm9jLmMNCj4+ICsrKyBiL2ZzL25m
cy9uZnM0cHJvYy5jDQo+PiBAQCAtMzMwMyw2ICszMzA0LDU5IEBAIHN0YXRpYyBpbnQgbmZzNF9w
cm9jX2ZzX2xvY2F0aW9uc19wcm9iZShzdHJ1Y3QgbmZzX3NlcnZlciAqc2VydmVyLA0KPj4gCXJl
dHVybiBlcnI7DQo+PiB9DQo+PiANCj4+ICsvKioNCj4+ICsgKiBUZXN0IHRoZSBtdWx0aXBhdGgg
YWRkcmVzc2VzIHJldHVybmVkIGJ5IG5mczRfZ2V0X3BzZXVkb2ZzX3JlcGxpY2FzDQo+PiArICog
Zm9yIHNlc3Npb24gdHJ1bmtpbmcuDQo+PiArICoNCj4+ICsgKiBBZGQgc2Vzc2lvbiB0cnVua2lu
ZyBhbGlhc2VzIHRvIHRoZSBjbF9ycGNjbGllbnQNCj4+ICsgKi8NCj4+ICt2b2lkIG5mczRfdGVz
dF9tdWx0aXBhdGgoc3RydWN0IG5mczRfZnNfbG9jYXRpb25zICpsb2NhdGlvbnMsDQo+PiArCQkJ
c3RydWN0IG5mc19jbGllbnQgKmNscCkNCj4+ICt7DQo+PiArCXN0cnVjdCBuZnM0X2FkZF94cHJ0
X2RhdGEgeHBydGRhdGEgPSB7DQo+PiArCQkuY2xwID0gY2xwLA0KPj4gKwl9Ow0KPj4gKwlpbnQg
aTsNCj4+ICsNCj4+ICsJaWYgKCFjbHAtPmNsX212b3BzLT5zZXNzaW9uX3RydW5rIHx8IGxvY2F0
aW9ucyA9PSBOVUxMIHx8DQo+PiArCSAgICBsb2NhdGlvbnMtPm5sb2NhdGlvbnMgPD0gMCkNCj4+
ICsJCXJldHVybjsNCj4+ICsNCj4+ICsJeHBydGRhdGEuY3JlZCA9IG5mczRfZ2V0X2NsaWRfY3Jl
ZChjbHApOw0KPj4gKw0KPj4gKwlmb3IgKGkgPSAwOyBpIDwgbG9jYXRpb25zLT5ubG9jYXRpb25z
OyBpKyspIHsNCj4+ICsJCXN0cnVjdCBuZnM0X2ZzX2xvY2F0aW9uICpsb2MgPSAmbG9jYXRpb25z
LT5sb2NhdGlvbnNbaV07DQo+PiArCQlpbnQgaTsNCj4+ICsNCj4+ICsJCWZvciAoaSA9IDA7IGkg
PCBsb2MtPm5zZXJ2ZXJzOyBpKyspIHsNCj4+ICsJCQlzdHJ1Y3QgbmZzNF9zdHJpbmcgKnNlcnZl
ciA9ICZsb2MtPnNlcnZlcnNbaV07DQo+PiArCQkJc3RydWN0IHNvY2thZGRyX3N0b3JhZ2UgYWRk
cjsNCj4+ICsJCQlzaXplX3QgYWRkcmxlbjsNCj4+ICsJCQlzdHJ1Y3QgeHBydF9jcmVhdGUgeHBy
dF9hcmdzID0gew0KPj4gKwkJCQkuaWRlbnQgPSBYUFJUX1RSQU5TUE9SVF9UQ1AsDQo+PiArCQkJ
CS5uZXQgPSBjbHAtPmNsX25ldCwNCj4+ICsJCQl9Ow0KPj4gKw0KPj4gKwkJCWFkZHJsZW4gPSBy
cGNfcHRvbihjbHAtPmNsX25ldCwgc2VydmVyLT5kYXRhLA0KPj4gKwkJCQkJc2VydmVyLT5sZW4s
IChzdHJ1Y3Qgc29ja2FkZHIgKikmYWRkciwNCj4+ICsJCQkJCXNpemVvZihhZGRyKSk7DQo+PiAr
DQo+PiArCQkJeHBydF9hcmdzLmRzdGFkZHIgPSAoc3RydWN0IHNvY2thZGRyICopJmFkZHI7DQo+
PiArCQkJeHBydF9hcmdzLmFkZHJsZW4gPSBhZGRybGVuOw0KPj4gKwkJCXhwcnRfYXJncy5zZXJ2
ZXJuYW1lID0gc2VydmVyLT5kYXRhOw0KPj4gKw0KPj4gKwkJCS8qKg0KPj4gKwkJCSAqIENoZWNr
IGZvciBzZXNzaW9uIHRydW5raW5nLiBBZGQgdGhpcyBhZGRyZXNzIGFzDQo+PiArCQkJICogYW4g
YWxpYXMgaWYgc2Vzc2lvbiB0cnVua2luZyBpcyBwZXJtaXR0ZWQuDQo+PiArCQkJICovDQo+PiAr
CQkJcnBjX2NsbnRfYWRkX3hwcnQoY2xwLT5jbF9ycGNjbGllbnQsICZ4cHJ0X2FyZ3MsDQo+PiAr
CQkJCQljbHAtPmNsX212b3BzLT5zZXNzaW9uX3RydW5rLA0KPj4gKwkJCQkJJnhwcnRkYXRhKTsN
Cj4+ICsJCX0NCj4+ICsJfQ0KPj4gKwlpZiAoeHBydGRhdGEuY3JlZCkNCj4+ICsJCXB1dF9ycGNj
cmVkKHhwcnRkYXRhLmNyZWQpOw0KPj4gK30NCj4+IA0KPj4gLyoqDQo+PiAgKiBQcm9iZSB0aGUg
cHNldWRvIGZpbGVzeXN0ZW0gZm9yIGFuIGZzX2xvY2F0aW9ucyByZXBsaWNhcyBsaXN0Lg0KPj4g
QEAgLTMzMzAsNyArMzM4NCw4IEBAIHZvaWQgbmZzNF9nZXRfcHNldWRvZnNfcmVwbGljYXMoc3Ry
dWN0IG5mc19zZXJ2ZXIgKnNlcnZlciwNCj4+IAlpZiAoc3RhdHVzICE9IDApDQo+PiAJCWdvdG8g
b3V0Ow0KPj4gDQo+PiAtCS8qIHRlc3QgcmVwbGljYXMgZm9yIHNlc3Npb24gdHJ1bmtpbmcgaGVy
ZSAqLw0KPj4gKwkvKiB0ZXN0IHJlcGxpY2FzIGZvciBzZXNzaW9uIHRydW5raW5nICovDQo+PiAr
CW5mczRfdGVzdF9tdWx0aXBhdGgobG9jYXRpb25zLCBzZXJ2ZXItPm5mc19jbGllbnQpOw0KPj4g
b3V0Og0KPj4gCWlmIChwYWdlKQ0KPj4gCQlfX2ZyZWVfcGFnZShwYWdlKTsNCj4+IEBAIC03Mjkx
LDYgKzczNDYsNDcgQEAgaW50IG5mczRfcHJvY19leGNoYW5nZV9pZChzdHJ1Y3QgbmZzX2NsaWVu
dCAqY2xwLCBzdHJ1Y3QgcnBjX2NyZWQgKmNyZWQpDQo+PiAJcmV0dXJuIF9uZnM0X3Byb2NfZXhj
aGFuZ2VfaWQoY2xwLCBjcmVkLCBTUDRfTk9ORSwgTlVMTCk7DQo+PiB9DQo+PiANCj4+ICsvKioN
Cj4+ICsgKiBuZnM0X3Rlc3Rfc2Vzc2lvbl90cnVuayAtIFRlc3QgZm9yIHNlc3Npb24gdHJ1bmtp
bmcgd2l0aCBhDQo+PiArICogc3luY2hyb25vdXMgZXhjaGFuZ2VfaWQgY2FsbC4gVXBvbiBzdWNj
ZXNzLCBhZGQgYSBuZXcgdHJhbnNwb3J0DQo+PiArICogdG8gdGhlIHJwY19jbG50DQo+PiArICoN
Cj4+ICsgKiBAY2xudDogc3RydWN0IHJwY19jbG50IHRvIGdldCBuZXcgdHJhbnNwb3J0DQo+PiAr
ICogQHhwczogIHRoZSBycGNfeHBydF9zd2l0Y2ggdG8gaG9sZCB0aGUgbmV3IHRyYW5zcG9ydA0K
Pj4gKyAqIEB4cHJ0OiB0aGUgcnBjX3hwcnQgdG8gdGVzdA0KPj4gKyAqIEBkYXRhOiBjYWxsIGRh
dGEgZm9yIF9uZnM0X3Byb2NfZXhjaGFuZ2VfaWQuDQo+PiArICoNCj4+ICsgKi8NCj4+ICtpbnQg
bmZzNF90ZXN0X3Nlc3Npb25fdHJ1bmsoc3RydWN0IHJwY19jbG50ICpjbG50LCBzdHJ1Y3QgcnBj
X3hwcnRfc3dpdGNoICp4cHMsDQo+PiArCQkJICAgIHN0cnVjdCBycGNfeHBydCAqeHBydCwgdm9p
ZCAqZGF0YSkNCj4+ICt7DQo+PiArCXN0cnVjdCBuZnM0X2FkZF94cHJ0X2RhdGEgKnhkYXRhID0g
KHN0cnVjdCBuZnM0X2FkZF94cHJ0X2RhdGEgKilkYXRhOw0KPj4gKwl1MzIgc3A0X2hvdzsNCj4+
ICsJaW50IHN0YXR1czsNCj4+ICsNCj4+ICsJc3A0X2hvdyA9ICh4ZGF0YS0+Y2xwLT5jbF9zcDRf
ZmxhZ3MgPT0gMCA/IFNQNF9OT05FIDogU1A0X01BQ0hfQ1JFRCk7DQo+PiArDQo+PiArCS8qIEVu
c3VyZSB0aGVzZSBzdGljayBhcm91bmQgZm9yIHRoZSBycGMgY2FsbCAqLw0KPj4gKwl4cHMgPSB4
cHJ0X3N3aXRjaF9nZXQoeHBzKTsNCj4+ICsJeHBydCA9IHhwcnRfZ2V0KHhwcnQpOw0KPiANCj4g
SSdtIGN1cmlvdXMgYXQgd2hhdCBwb2ludCBkdXJpbmcgX25mczRfcHJvY19leGNoYW5nZV9pZCgp
IHRoZXNlIG1pZ2h0IGdldCByZWxlYXNlZD8NCg0KSSB3YXMgY29uY2VybmVkIGFib3V0IHRoZSBj
bGllbnQgdGVhcmluZyBkb3duIHRoZSBzZXJ2ZXIgbW91bnQgd2hvc2UgcnBjX2NsbnQgc3RydWN0
IGhvc3RzIHRoZSB4cHJ0X3N3aXRjaCAob3Igb3RoZXJ3aXNlIHRlYXJpbmcgZG93biB0aGUgcnBj
X2NsbnQpIHdoaWxlIHRoZSBfbmZzNF9wcm9jX2V4Y2hhbmdlX2lkIGlzIGluIGZsaWdodC4NCg0K
QUZBSUNTIHRoYXQgaXMgdGhlIHNhbWUgY29uY2VybiB0aGF0IHRoZSBvdGhlciB1c2Ugb2YgcnBj
X2NsbnRfYWRkX3hwcnQoKSBpbiBfbmZzNF9wbmZzX3YzX2RzX2Nvbm5lY3QoKSBoYXMuDQoNCnJw
Y19jbG50X3Rlc3RfYW5kX2FkZF94cHJ0ICgpIHJlZmVyZW5jZXMgdGhlIHhwcnRfc3dpdGNoIGFu
ZCB0aGUgeHBydCwgYW5kIHJwY19jYl9hZGRfeHBydF9yZWxlYXNlKCkgZGVyZWZlcmVuY2VzIHRo
ZW0uDQoNCuKAlD5BbmR5DQoNCg0KPiANCj4gVGhhbmtzLA0KPiBBbm5hDQo+IA0KPj4gKw0KPj4g
KwkvKiBTeW5jIGNhbGwgKi8NCj4+ICsJc3RhdHVzID0gX25mczRfcHJvY19leGNoYW5nZV9pZCh4
ZGF0YS0+Y2xwLCB4ZGF0YS0+Y3JlZCwgc3A0X2hvdywgeHBydCk7DQo+PiArDQo+PiArCXhwcnRf
cHV0KHhwcnQpOw0KPj4gKwl4cHJ0X3N3aXRjaF9wdXQoeHBzKTsNCj4+ICsNCj4+ICsJaWYgKHN0
YXR1cykNCj4+ICsJCXByX2luZm8oIk5GUzogICAlczogU2Vzc2lvbiB0cnVua2luZyBmYWlsZWQg
Zm9yICVzIHN0YXR1cyAlZFxuIiwNCj4+ICsJCQl4ZGF0YS0+Y2xwLT5jbF9ob3N0bmFtZSwNCj4+
ICsJCQl4cHJ0LT5hZGRyZXNzX3N0cmluZ3NbUlBDX0RJU1BMQVlfQUREUl0sIHN0YXR1cyk7DQo+
PiArCWVsc2UNCj4+ICsJCXByX2luZm8oIk5GUzogICAlczogU2Vzc2lvbiB0cnVua2luZyBzdWNj
ZWVkZWQgZm9yICVzXG4iLA0KPj4gKwkJCXhkYXRhLT5jbHAtPmNsX2hvc3RuYW1lLA0KPj4gKwkJ
CXhwcnQtPmFkZHJlc3Nfc3RyaW5nc1tSUENfRElTUExBWV9BRERSXSk7DQo+PiArCXJldHVybiBz
dGF0dXM7DQo+PiArfQ0KPj4gKw0KPj4gc3RhdGljIGludCBfbmZzNF9wcm9jX2Rlc3Ryb3lfY2xp
ZW50aWQoc3RydWN0IG5mc19jbGllbnQgKmNscCwNCj4+IAkJc3RydWN0IHJwY19jcmVkICpjcmVk
KQ0KPj4gew0KPj4gQEAgLTg4ODIsNiArODk3OCw3IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3QgbmZz
NF9taW5vcl92ZXJzaW9uX29wcyBuZnNfdjRfMV9taW5vcl9vcHMgPSB7DQo+PiAJLmZpbmRfcm9v
dF9zZWMgPSBuZnM0MV9maW5kX3Jvb3Rfc2VjLA0KPj4gCS5mcmVlX2xvY2tfc3RhdGUgPSBuZnM0
MV9mcmVlX2xvY2tfc3RhdGUsDQo+PiAJLmFsbG9jX3NlcWlkID0gbmZzX2FsbG9jX25vX3NlcWlk
LA0KPj4gKwkuc2Vzc2lvbl90cnVuayA9IG5mczRfdGVzdF9zZXNzaW9uX3RydW5rLA0KPj4gCS5j
YWxsX3N5bmNfb3BzID0gJm5mczQxX2NhbGxfc3luY19vcHMsDQo+PiAJLnJlYm9vdF9yZWNvdmVy
eV9vcHMgPSAmbmZzNDFfcmVib290X3JlY292ZXJ5X29wcywNCj4+IAkubm9ncmFjZV9yZWNvdmVy
eV9vcHMgPSAmbmZzNDFfbm9ncmFjZV9yZWNvdmVyeV9vcHMsDQo+PiBAQCAtODkxMCw2ICs5MDA3
LDcgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBuZnM0X21pbm9yX3ZlcnNpb25fb3BzIG5mc192NF8y
X21pbm9yX29wcyA9IHsNCj4+IAkuZnJlZV9sb2NrX3N0YXRlID0gbmZzNDFfZnJlZV9sb2NrX3N0
YXRlLA0KPj4gCS5jYWxsX3N5bmNfb3BzID0gJm5mczQxX2NhbGxfc3luY19vcHMsDQo+PiAJLmFs
bG9jX3NlcWlkID0gbmZzX2FsbG9jX25vX3NlcWlkLA0KPj4gKwkuc2Vzc2lvbl90cnVuayA9IG5m
czRfdGVzdF9zZXNzaW9uX3RydW5rLA0KPj4gCS5yZWJvb3RfcmVjb3Zlcnlfb3BzID0gJm5mczQx
X3JlYm9vdF9yZWNvdmVyeV9vcHMsDQo+PiAJLm5vZ3JhY2VfcmVjb3Zlcnlfb3BzID0gJm5mczQx
X25vZ3JhY2VfcmVjb3Zlcnlfb3BzLA0KPj4gCS5zdGF0ZV9yZW5ld2FsX29wcyA9ICZuZnM0MV9z
dGF0ZV9yZW5ld2FsX29wcywNCj4+IGRpZmYgLS1naXQgYS9uZXQvc3VucnBjL3hwcnRtdWx0aXBh
dGguYyBiL25ldC9zdW5ycGMveHBydG11bHRpcGF0aC5jDQo+PiBpbmRleCBlN2ZkNzY5Li4zNjBm
NjRjIDEwMDY0NA0KPj4gLS0tIGEvbmV0L3N1bnJwYy94cHJ0bXVsdGlwYXRoLmMNCj4+ICsrKyBi
L25ldC9zdW5ycGMveHBydG11bHRpcGF0aC5jDQo+PiBAQCAtNTMsNiArNTMsNyBAQCB2b2lkIHJw
Y194cHJ0X3N3aXRjaF9hZGRfeHBydChzdHJ1Y3QgcnBjX3hwcnRfc3dpdGNoICp4cHMsDQo+PiAJ
CXhwcnRfc3dpdGNoX2FkZF94cHJ0X2xvY2tlZCh4cHMsIHhwcnQpOw0KPj4gCXNwaW5fdW5sb2Nr
KCZ4cHMtPnhwc19sb2NrKTsNCj4+IH0NCj4+ICtFWFBPUlRfU1lNQk9MX0dQTChycGNfeHBydF9z
d2l0Y2hfYWRkX3hwcnQpOw0KPj4gDQo+PiBzdGF0aWMgdm9pZCB4cHJ0X3N3aXRjaF9yZW1vdmVf
eHBydF9sb2NrZWQoc3RydWN0IHJwY194cHJ0X3N3aXRjaCAqeHBzLA0KPj4gCQlzdHJ1Y3QgcnBj
X3hwcnQgKnhwcnQpDQo+PiBAQCAtMTQ1LDYgKzE0Niw3IEBAIHN0cnVjdCBycGNfeHBydF9zd2l0
Y2ggKnhwcnRfc3dpdGNoX2dldChzdHJ1Y3QgcnBjX3hwcnRfc3dpdGNoICp4cHMpDQo+PiAJCXJl
dHVybiB4cHM7DQo+PiAJcmV0dXJuIE5VTEw7DQo+PiB9DQo+PiArRVhQT1JUX1NZTUJPTF9HUEwo
eHBydF9zd2l0Y2hfZ2V0KTsNCj4+IA0KPj4gLyoqDQo+PiAgKiB4cHJ0X3N3aXRjaF9wdXQgLSBS
ZWxlYXNlIGEgcmVmZXJlbmNlIHRvIGEgcnBjX3hwcnRfc3dpdGNoDQo+PiBAQCAtMTU3LDYgKzE1
OSw3IEBAIHZvaWQgeHBydF9zd2l0Y2hfcHV0KHN0cnVjdCBycGNfeHBydF9zd2l0Y2ggKnhwcykN
Cj4+IAlpZiAoeHBzICE9IE5VTEwpDQo+PiAJCWtyZWZfcHV0KCZ4cHMtPnhwc19rcmVmLCB4cHJ0
X3N3aXRjaF9mcmVlKTsNCj4+IH0NCj4+ICtFWFBPUlRfU1lNQk9MX0dQTCh4cHJ0X3N3aXRjaF9w
dXQpOw0KPj4gDQo+PiAvKioNCj4+ICAqIHJwY194cHJ0X3N3aXRjaF9zZXRfcm91bmRyb2JpbiAt
IFNldCBhIHJvdW5kLXJvYmluIHBvbGljeSBvbiBycGNfeHBydF9zd2l0Y2gNCj4+IA0KPiANCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index ff8cfcd..e886aa7 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -59,6 +59,8 @@  struct nfs4_minor_version_ops {
 			struct nfs4_lock_state *);
 	struct nfs_seqid *
 		(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
+	int	(*session_trunk)(struct rpc_clnt *, struct rpc_xprt_switch *,
+			struct rpc_xprt *, void *);
 	const struct rpc_call_ops *call_sync_ops;
 	const struct nfs4_state_recovery_ops *reboot_recovery_ops;
 	const struct nfs4_state_recovery_ops *nograce_recovery_ops;
@@ -214,6 +216,11 @@  struct nfs4_mig_recovery_ops {
 	int (*fsid_present)(struct inode *, struct rpc_cred *);
 };
 
+struct nfs4_add_xprt_data {
+	struct nfs_client	*clp;
+	struct rpc_cred		*cred;
+};
+
 extern const struct dentry_operations nfs4_dentry_operations;
 
 /* dir.c */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 8263ee8..827ae51 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -44,6 +44,7 @@ 
 #include <linux/printk.h>
 #include <linux/slab.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/addr.h>
 #include <linux/nfs.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
@@ -3303,6 +3304,59 @@  static int nfs4_proc_fs_locations_probe(struct nfs_server *server,
 	return err;
 }
 
+/**
+ * Test the multipath addresses returned by nfs4_get_pseudofs_replicas
+ * for session trunking.
+ *
+ * Add session trunking aliases to the cl_rpcclient
+ */
+void nfs4_test_multipath(struct nfs4_fs_locations *locations,
+			struct nfs_client *clp)
+{
+	struct nfs4_add_xprt_data xprtdata = {
+		.clp = clp,
+	};
+	int i;
+
+	if (!clp->cl_mvops->session_trunk || locations == NULL ||
+	    locations->nlocations <= 0)
+		return;
+
+	xprtdata.cred = nfs4_get_clid_cred(clp);
+
+	for (i = 0; i < locations->nlocations; i++) {
+		struct nfs4_fs_location *loc = &locations->locations[i];
+		int i;
+
+		for (i = 0; i < loc->nservers; i++) {
+			struct nfs4_string *server = &loc->servers[i];
+			struct sockaddr_storage addr;
+			size_t addrlen;
+			struct xprt_create xprt_args = {
+				.ident = XPRT_TRANSPORT_TCP,
+				.net = clp->cl_net,
+			};
+
+			addrlen = rpc_pton(clp->cl_net, server->data,
+					server->len, (struct sockaddr *)&addr,
+					sizeof(addr));
+
+			xprt_args.dstaddr = (struct sockaddr *)&addr;
+			xprt_args.addrlen = addrlen;
+			xprt_args.servername = server->data;
+
+			/**
+			 * Check for session trunking. Add this address as
+			 * an alias if session trunking is permitted.
+			 */
+			rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
+					clp->cl_mvops->session_trunk,
+					&xprtdata);
+		}
+	}
+	if (xprtdata.cred)
+		put_rpccred(xprtdata.cred);
+}
 
 /**
  * Probe the pseudo filesystem for an fs_locations replicas list.
@@ -3330,7 +3384,8 @@  void nfs4_get_pseudofs_replicas(struct nfs_server *server,
 	if (status != 0)
 		goto out;
 
-	/* test replicas for session trunking here */
+	/* test replicas for session trunking */
+	nfs4_test_multipath(locations, server->nfs_client);
 out:
 	if (page)
 		__free_page(page);
@@ -7291,6 +7346,47 @@  int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 	return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
 }
 
+/**
+ * nfs4_test_session_trunk - Test for session trunking with a
+ * synchronous exchange_id call. Upon success, add a new transport
+ * to the rpc_clnt
+ *
+ * @clnt: struct rpc_clnt to get new transport
+ * @xps:  the rpc_xprt_switch to hold the new transport
+ * @xprt: the rpc_xprt to test
+ * @data: call data for _nfs4_proc_exchange_id.
+ *
+ */
+int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt_switch *xps,
+			    struct rpc_xprt *xprt, void *data)
+{
+	struct nfs4_add_xprt_data *xdata = (struct nfs4_add_xprt_data *)data;
+	u32 sp4_how;
+	int status;
+
+	sp4_how = (xdata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
+
+	/* Ensure these stick around for the rpc call */
+	xps = xprt_switch_get(xps);
+	xprt = xprt_get(xprt);
+
+	/* Sync call */
+	status = _nfs4_proc_exchange_id(xdata->clp, xdata->cred, sp4_how, xprt);
+
+	xprt_put(xprt);
+	xprt_switch_put(xps);
+
+	if (status)
+		pr_info("NFS:   %s: Session trunking failed for %s status %d\n",
+			xdata->clp->cl_hostname,
+			xprt->address_strings[RPC_DISPLAY_ADDR], status);
+	else
+		pr_info("NFS:   %s: Session trunking succeeded for %s\n",
+			xdata->clp->cl_hostname,
+			xprt->address_strings[RPC_DISPLAY_ADDR]);
+	return status;
+}
+
 static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 		struct rpc_cred *cred)
 {
@@ -8882,6 +8978,7 @@  static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
 	.find_root_sec = nfs41_find_root_sec,
 	.free_lock_state = nfs41_free_lock_state,
 	.alloc_seqid = nfs_alloc_no_seqid,
+	.session_trunk = nfs4_test_session_trunk,
 	.call_sync_ops = &nfs41_call_sync_ops,
 	.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
 	.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
@@ -8910,6 +9007,7 @@  static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
 	.free_lock_state = nfs41_free_lock_state,
 	.call_sync_ops = &nfs41_call_sync_ops,
 	.alloc_seqid = nfs_alloc_no_seqid,
+	.session_trunk = nfs4_test_session_trunk,
 	.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
 	.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
 	.state_renewal_ops = &nfs41_state_renewal_ops,
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
index e7fd769..360f64c 100644
--- a/net/sunrpc/xprtmultipath.c
+++ b/net/sunrpc/xprtmultipath.c
@@ -53,6 +53,7 @@  void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
 		xprt_switch_add_xprt_locked(xps, xprt);
 	spin_unlock(&xps->xps_lock);
 }
+EXPORT_SYMBOL_GPL(rpc_xprt_switch_add_xprt);
 
 static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
 		struct rpc_xprt *xprt)
@@ -145,6 +146,7 @@  struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps)
 		return xps;
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(xprt_switch_get);
 
 /**
  * xprt_switch_put - Release a reference to a rpc_xprt_switch
@@ -157,6 +159,7 @@  void xprt_switch_put(struct rpc_xprt_switch *xps)
 	if (xps != NULL)
 		kref_put(&xps->xps_kref, xprt_switch_free);
 }
+EXPORT_SYMBOL_GPL(xprt_switch_put);
 
 /**
  * rpc_xprt_switch_set_roundrobin - Set a round-robin policy on rpc_xprt_switch