From: Andy Adamson <[email protected]>
Signed-off-by: Andy Adamson <[email protected]>
---
fs/nfs/client.c | 6 ++----
fs/nfs/internal.h | 5 ++---
fs/nfs/nfs4client.c | 3 +--
include/linux/nfs_xdr.h | 2 +-
4 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 340b1ef..2dceee4 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -501,8 +501,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
&nn->nfs_client_list);
spin_unlock(&nn->nfs_client_lock);
new->cl_flags = cl_init->init_flags;
- return rpc_ops->init_client(new, timeparms, ip_addr,
- authflavour);
+ return rpc_ops->init_client(new, timeparms, ip_addr);
}
spin_unlock(&nn->nfs_client_lock);
@@ -694,13 +693,12 @@ EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
* @clp: nfs_client to initialise
* @timeparms: timeout parameters for underlying RPC transport
* @ip_addr: IP presentation address (not used)
- * @authflavor: authentication flavor for underlying RPC transport
*
* Returns pointer to an NFS client, or an ERR_PTR value.
*/
struct nfs_client *nfs_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms,
- const char *ip_addr, rpc_authflavor_t authflavour)
+ const char *ip_addr)
{
int error;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3c8373f..9b694f1 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -267,7 +267,7 @@ extern struct rpc_procinfo nfs4_procedures[];
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms,
- const char *ip_addr, rpc_authflavor_t authflavour);
+ const char *ip_addr);
/* dir.c */
extern int nfs_access_cache_shrinker(struct shrinker *shrink,
@@ -451,8 +451,7 @@ extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
extern void __nfs4_read_done_cb(struct nfs_read_data *);
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms,
- const char *ip_addr,
- rpc_authflavor_t authflavour);
+ const char *ip_addr);
extern int nfs40_walk_client_list(struct nfs_client *clp,
struct nfs_client **result,
struct rpc_cred *cred);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 90dce91..767a5e3 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -187,8 +187,7 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
*/
struct nfs_client *nfs4_init_client(struct nfs_client *clp,
const struct rpc_timeout *timeparms,
- const char *ip_addr,
- rpc_authflavor_t authflavour)
+ const char *ip_addr)
{
char buf[INET6_ADDRSTRLEN + 1];
struct nfs_client *old;
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8651574..ddc3e32 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1442,7 +1442,7 @@ struct nfs_rpc_ops {
struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *);
struct nfs_client *
(*init_client) (struct nfs_client *, const struct rpc_timeout *,
- const char *, rpc_authflavor_t);
+ const char *);
void (*free_client) (struct nfs_client *);
struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
--
1.8.3.1
T24gTW9uLCAyMDEzLTA3LTIyIGF0IDIwOjI0ICswMDAwLCBBZGFtc29uLCBBbmR5IHdyb3RlOg0K
PiBPbiBKdWwgMjIsIDIwMTMsIGF0IDI6NTAgUE0sICJNeWtsZWJ1c3QsIFRyb25kIiA8VHJvbmQu
TXlrbGVidXN0QG5ldGFwcC5jb20+DQo+ICB3cm90ZToNCj4gDQo+ID4gT24gRnJpLCAyMDEzLTA3
LTE5IGF0IDE3OjA2IC0wNDAwLCBhbmRyb3NAbmV0YXBwLmNvbSB3cm90ZToNCj4gPj4gRnJvbTog
QW5keSBBZGFtc29uIDxhbmRyb3NAbmV0YXBwLmNvbT4NCj4gPj4gDQo+ID4+IHBORlMgZGF0YSBz
ZXJ2ZXJzIGFyZSBub3QgbW91bnRlZCBpbiB0aGUgbm9ybWFsIHNlbnNlIGFzIHRoZXJlIGlzIG5v
IGFzc29jaWF0ZWQNCj4gPj4gbmZzX3NlcnZlciBzdHJ1Y3R1cmUuDQo+ID4+IENvbW1pdCA0ZWRh
YTMwOCAiTkZTOiBVc2UgImtyYjVpIiB0byBlc3RhYmxpc2ggTkZTdjQgc3RhdGUgd2hlbmV2ZXIg
cG9zc2libGUiDQo+ID4+IHVzZXMgdGhlIG5mc19jbGllbnQgY2xfcnBjY2xpZW50IGZvciBhbGwg
c3RhdGUgbWFuYWdlbWVudCBvcGVyYXRpb25zLCBhbmQNCj4gPj4gd2lsbCB1c2Uga3JiNWkgb3Ig
YXV0aF9zeXMgd2l0aCBubyByZWdhcmQgdG8gdGhlIG1vdW50IGNvbW1hbmQgYXV0aGZsYXZvcg0K
PiA+PiBjaG9pY2UuICBGb3Igbm9ybWFsIG1vdW50ZWQgc2VydmVycywgdGhlIG5mc19zZXJ2ZXIg
Y2xpZW50IGF1dGhmbGF2b3IgaXMgdXNlZA0KPiA+PiBmb3IgYWxsIG5vbi1zdGF0ZSBtYW5hZ2Vt
ZW50IG9wZXJhdGlvbnMNCj4gPj4gDQo+ID4+IERhdGEgc2VydmVycyBhbHNvIG5lZWQgdG8gdXNl
IHRoZSBzYW1lIGF1dGhmbGF2b3IgYXMgdGhlIE1EUyBtb3VudCBmb3INCj4gPj4gbm9uLXN0YXRl
IG1hbmFnZW1lbnQgb3BlcmF0aW9ucy4gQWRkIGEgc3RydXQgcnBjX2NsbnQgdG8gc3RydWN0IG5m
c19jbGllbnQgZm9yDQo+ID4+IGRhdGEgc2VydmVyIGNvbm5lY3Rpb25zLg0KPiA+IA0KPiA+IElz
IHRoYXQgc3VmZmljaWVudD8gQXMgZmFyIGFzIEkgY2FuIHRlbGwsIHRoZXJlIGlzIG5vdGhpbmcg
dGhhdCBzdGF0ZXMNCj4gPiB0aGF0IHRoZSBkYXRhIHNlcnZlcnMgbXVzdCB1c2UgdGhlIHNhbWUg
c2VjdXJpdHkgbWVjaGFuaXNtIGZvciBhbGwgdGhlDQo+ID4gZmlsZXM/DQo+ID4gSW4gZmFjdCwg
c2VjdGlvbiAxMy4xMiBzcGVjaWZpY2FsbHkgbWVudGlvbnMgdGhhdCB0aGUgZGF0YSBzZXJ2ZXJz
IGhhdmUNCj4gPiB0byBzdXBwb3J0IFNFQ0lORk9fTk9fTkFNRSB0byBhbGxvdyBjbGllbnRzIHRv
IGZpZ3VyZSBvdXQgd2hhdCB0byB1c2UNCj4gPiBmb3IgYSBnaXZlbiBEUyBmaWxlaGFuZGxlLg0K
PiANCj4gR29vZCBwb2ludC4gIFdlIGRvbid0IHN1cHBvcnQgcGVyLWZpbGUgc2VjdXJpdHksIGJ1
dCB3ZSBkbyBzdXBwb3J0IHBlciBmc2lkIHNlY3VyaXR5IGFuZCB0aGUgRFMgc2hvdWxkIGZvbGxv
dyBzdWl0Lg0KPiANCj4gQSBub24tcE5GUyBORlN2NC4xIG1vdW50IGNhbiBzd2l0Y2ggYXV0aCBm
bGF2b3JzIG9uIGZzaWQgYm91bmRhcmllcyAtIHVuZGVyIHRoZSBjb3ZlciBtb3VudCwgY3JlYXRl
IG5mc19zZXJ2ZXIgd2l0aCBpdCdzIG93biBycGNfY2xudCBhbmQgYSBkaWZmZXJlbnQgc2VjdXJp
dHkgZmxhdm9yLiBTbyB3aGF0IHRvIGRvIGluIHRoZSBEUyBjYXNlIHdoZXJlIHRoZSBEUyBleHBv
cnRzIG1vcmUgdGhhbiBvbmUgZnNpZCwgZWFjaCB3aXRoIGEgZGlmZmVyZW50IHNlY3VyaXR5IGZs
YXZvcj8NCj4gDQo+IEkgZGlzY3Vzc2VkIHRoaXMgd2l0aCBEcm9zIHdobyBpcyBhbHNvIGRvaW5n
IHNvbWUgd29yayBvbiB0aGUgU0VDSU5GTyBjb2RlLiBBcyBhIGZpcnN0IHBhc3MsIGl0IHdvdWxk
IG1ha2Ugc2Vuc2UgdG8gdXNlIHRoZSBzZWN1cml0eSBmbGF2b3IgdGhhdCB0aGUgTURTIHNlcnZl
ci0+Y2xpZW50IHVzZXMgZm9yIERTIGFjY2VzcywgYW5kIHJlcGxhY2UgdGhlIHNpbmdsZSBkYXRh
IHNlcnZlciBycGNfY2xudCB3aXRoIGFuIGFycmF5IG9mIHJwY19jbG50cyBvbmUgZm9yIGVhY2gg
Zmxhdm9yIChzeXMsIGtyYjUsIGtyYjVpLCBrcmI1cCkgIHRoYXQgZ2V0IGFsbG9jYXRlZCAoZm9y
IHRoZSBEUy1vbmx5IGNhc2UpIHdoZW4gZmlyc3QgbmVlZGVkIGFuZCBjYWNoZWQuDQo+IA0KPiBG
b3IgdGhlIE1EUyArIERTIGNhc2UgdGhpcyBjYWNoZSBjb3VsZCBhbHNvIGJlIHVzZWQgYnkgdGhl
IE1EUyBuZnNfc2VydmVyLT5jbGllbnRzLg0KDQpZb3UgZG9uJ3Qgd2FudCB0byB1cyB0aG9zZSBy
cGNfY2xpZW50cyBkaXJlY3RseSBpbiB0aGUNCm5mc19zZXJ2ZXItPmNsaWVudC4gSW5zdGVhZCB5
b3Ugd2FudCB0byBjbG9uZSB0aGVtLCBzbyB0aGF0IHRoZXkgY2FuIGJlDQpzaHV0IGRvd24gd2l0
aG91dCBhZmZlY3RpbmcgdGhlIGZ1bmN0aW9uaW5nIG9mIHRoZSBuZnNfY2xpZW50Lg0KDQpUaGF0
IHNhaWQsIGl0IHdvdWxkIGJlIGdyZWF0IHRvIGJlIGFibGUgdG8gc2hhcmUgdGhlIHNhbWUgYXV0
aCBjYWNoZQ0Kd2l0aCBhbGwgcnBjX2NsaWVudHMgdGhhdCB0aGF0IHRhbGsgdG8gdGhlIHNhbWUg
TkZTIHNlcnZlciBhbmQgdXNlIHRoZQ0Kc2FtZSBhdXRoIGZsYXZvdXIuDQoNCi0tIA0KVHJvbmQg
TXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXINCg0KTmV0QXBwDQpUcm9uZC5N
eWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20NCg==
T24gRnJpLCAyMDEzLTA3LTE5IGF0IDE3OjA2IC0wNDAwLCBhbmRyb3NAbmV0YXBwLmNvbSB3cm90
ZToNCj4gRnJvbTogQW5keSBBZGFtc29uIDxhbmRyb3NAbmV0YXBwLmNvbT4NCj4gDQo+IHBORlMg
ZGF0YSBzZXJ2ZXJzIGFyZSBub3QgbW91bnRlZCBpbiB0aGUgbm9ybWFsIHNlbnNlIGFzIHRoZXJl
IGlzIG5vIGFzc29jaWF0ZWQNCj4gbmZzX3NlcnZlciBzdHJ1Y3R1cmUuDQo+IENvbW1pdCA0ZWRh
YTMwOCAiTkZTOiBVc2UgImtyYjVpIiB0byBlc3RhYmxpc2ggTkZTdjQgc3RhdGUgd2hlbmV2ZXIg
cG9zc2libGUiDQo+IHVzZXMgdGhlIG5mc19jbGllbnQgY2xfcnBjY2xpZW50IGZvciBhbGwgc3Rh
dGUgbWFuYWdlbWVudCBvcGVyYXRpb25zLCBhbmQNCj4gd2lsbCB1c2Uga3JiNWkgb3IgYXV0aF9z
eXMgd2l0aCBubyByZWdhcmQgdG8gdGhlIG1vdW50IGNvbW1hbmQgYXV0aGZsYXZvcg0KPiBjaG9p
Y2UuICBGb3Igbm9ybWFsIG1vdW50ZWQgc2VydmVycywgdGhlIG5mc19zZXJ2ZXIgY2xpZW50IGF1
dGhmbGF2b3IgaXMgdXNlZA0KPiBmb3IgYWxsIG5vbi1zdGF0ZSBtYW5hZ2VtZW50IG9wZXJhdGlv
bnMNCj4gDQo+IERhdGEgc2VydmVycyBhbHNvIG5lZWQgdG8gdXNlIHRoZSBzYW1lIGF1dGhmbGF2
b3IgYXMgdGhlIE1EUyBtb3VudCBmb3INCj4gbm9uLXN0YXRlIG1hbmFnZW1lbnQgb3BlcmF0aW9u
cy4gQWRkIGEgc3RydXQgcnBjX2NsbnQgdG8gc3RydWN0IG5mc19jbGllbnQgZm9yDQo+IGRhdGEg
c2VydmVyIGNvbm5lY3Rpb25zLg0KDQpJcyB0aGF0IHN1ZmZpY2llbnQ/IEFzIGZhciBhcyBJIGNh
biB0ZWxsLCB0aGVyZSBpcyBub3RoaW5nIHRoYXQgc3RhdGVzDQp0aGF0IHRoZSBkYXRhIHNlcnZl
cnMgbXVzdCB1c2UgdGhlIHNhbWUgc2VjdXJpdHkgbWVjaGFuaXNtIGZvciBhbGwgdGhlDQpmaWxl
cz8NCkluIGZhY3QsIHNlY3Rpb24gMTMuMTIgc3BlY2lmaWNhbGx5IG1lbnRpb25zIHRoYXQgdGhl
IGRhdGEgc2VydmVycyBoYXZlDQp0byBzdXBwb3J0IFNFQ0lORk9fTk9fTkFNRSB0byBhbGxvdyBj
bGllbnRzIHRvIGZpZ3VyZSBvdXQgd2hhdCB0byB1c2UNCmZvciBhIGdpdmVuIERTIGZpbGVoYW5k
bGUuDQoNCi0tIA0KVHJvbmQgTXlrbGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXIN
Cg0KTmV0QXBwDQpUcm9uZC5NeWtsZWJ1c3RAbmV0YXBwLmNvbQ0Kd3d3Lm5ldGFwcC5jb20NCg==
On Jul 22, 2013, at 2:50 PM, "Myklebust, Trond" <[email protected]>
wrote:
> On Fri, 2013-07-19 at 17:06 -0400, [email protected] wrote:
>> From: Andy Adamson <[email protected]>
>>
>> pNFS data servers are not mounted in the normal sense as there is no associated
>> nfs_server structure.
>> Commit 4edaa308 "NFS: Use "krb5i" to establish NFSv4 state whenever possible"
>> uses the nfs_client cl_rpcclient for all state management operations, and
>> will use krb5i or auth_sys with no regard to the mount command authflavor
>> choice. For normal mounted servers, the nfs_server client authflavor is used
>> for all non-state management operations
>>
>> Data servers also need to use the same authflavor as the MDS mount for
>> non-state management operations. Add a strut rpc_clnt to struct nfs_client for
>> data server connections.
>
> Is that sufficient? As far as I can tell, there is nothing that states
> that the data servers must use the same security mechanism for all the
> files?
> In fact, section 13.12 specifically mentions that the data servers have
> to support SECINFO_NO_NAME to allow clients to figure out what to use
> for a given DS filehandle.
Good point. We don't support per-file security, but we do support per fsid security and the DS should follow suit.
A non-pNFS NFSv4.1 mount can switch auth flavors on fsid boundaries - under the cover mount, create nfs_server with it's own rpc_clnt and a different security flavor. So what to do in the DS case where the DS exports more than one fsid, each with a different security flavor?
I discussed this with Dros who is also doing some work on the SECINFO code. As a first pass, it would make sense to use the security flavor that the MDS server->client uses for DS access, and replace the single data server rpc_clnt with an array of rpc_clnts one for each flavor (sys, krb5, krb5i, krb5p) that get allocated (for the DS-only case) when first needed and cached.
For the MDS + DS case this cache could also be used by the MDS nfs_server->clients.
Is this what you had in mind?
-->Andy
>
> --
> Trond Myklebust
> Linux NFS client maintainer
>
> NetApp
> [email protected]
> http://www.netapp.com
From: Andy Adamson <[email protected]>
pNFS data servers are not mounted in the normal sense as there is no associated
nfs_server structure.
Commit 4edaa308 "NFS: Use "krb5i" to establish NFSv4 state whenever possible"
uses the nfs_client cl_rpcclient for all state management operations, and
will use krb5i or auth_sys with no regard to the mount command authflavor
choice. For normal mounted servers, the nfs_server client authflavor is used
for all non-state management operations
Data servers also need to use the same authflavor as the MDS mount for
non-state management operations. Add a strut rpc_clnt to struct nfs_client for
data server connections.
Signed-off-by: Andy Adamson <[email protected]>
---
fs/nfs/client.c | 16 +++++++++++++---
fs/nfs/nfs4filelayout.c | 6 +++---
fs/nfs/nfs4filelayoutdev.c | 16 +++++++++++++++-
include/linux/nfs_fs_sb.h | 1 +
4 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 2dceee4..b803bad 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -177,6 +177,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
INIT_LIST_HEAD(&clp->cl_superblocks);
clp->cl_rpcclient = ERR_PTR(-EINVAL);
+ clp->cl_dsrpcclient = ERR_PTR(-EINVAL);
clp->cl_proto = cl_init->proto;
clp->cl_net = get_net(cl_init->net);
@@ -595,8 +596,13 @@ int nfs_create_rpc_client(struct nfs_client *clp,
if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
- if (!IS_ERR(clp->cl_rpcclient))
- return 0;
+ if (is_ds_client(clp)) {
+ if (IS_ERR(clp->cl_rpcclient) || !IS_ERR(clp->cl_dsrpcclient))
+ return 0;
+ } else {
+ if (!IS_ERR(clp->cl_rpcclient))
+ return 0;
+ }
clnt = rpc_create(&args);
if (IS_ERR(clnt)) {
@@ -605,7 +611,11 @@ int nfs_create_rpc_client(struct nfs_client *clp,
return PTR_ERR(clnt);
}
- clp->cl_rpcclient = clnt;
+ if (is_ds_client(clp))
+ clp->cl_dsrpcclient = clnt;
+ else
+ clp->cl_rpcclient = clnt;
+
return 0;
}
EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 17ed87e..3fe1491 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -552,7 +552,7 @@ filelayout_read_pagelist(struct nfs_read_data *data)
data->mds_offset = offset;
/* Perform an asynchronous read to ds */
- nfs_initiate_read(ds->ds_clp->cl_rpcclient, data,
+ nfs_initiate_read(ds->ds_clp->cl_dsrpcclient, data,
&filelayout_read_call_ops, RPC_TASK_SOFTCONN);
return PNFS_ATTEMPTED;
}
@@ -591,7 +591,7 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
data->args.offset = filelayout_get_dserver_offset(lseg, offset);
/* Perform an asynchronous write */
- nfs_initiate_write(ds->ds_clp->cl_rpcclient, data,
+ nfs_initiate_write(ds->ds_clp->cl_dsrpcclient, data,
&filelayout_write_call_ops, sync,
RPC_TASK_SOFTCONN);
return PNFS_ATTEMPTED;
@@ -1119,7 +1119,7 @@ static int filelayout_initiate_commit(struct nfs_commit_data *data, int how)
fh = select_ds_fh_from_commit(lseg, data->ds_commit_index);
if (fh)
data->args.fh = fh;
- return nfs_initiate_commit(ds->ds_clp->cl_rpcclient, data,
+ return nfs_initiate_commit(ds->ds_clp->cl_dsrpcclient, data,
&filelayout_commit_call_ops, how,
RPC_TASK_SOFTCONN);
}
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 95604f6..46f1b13 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -159,10 +159,11 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
{
struct nfs_client *clp = ERR_PTR(-EIO);
struct nfs4_pnfs_ds_addr *da;
+ struct rpc_timeout ds_timeout;
int status = 0;
dprintk("--> %s DS %s au_flavor %d\n", __func__, ds->ds_remotestr,
- mds_srv->nfs_client->cl_rpcclient->cl_auth->au_flavor);
+ mds_srv->client->cl_auth->au_flavor);
list_for_each_entry(da, &ds->ds_addrs, da_node) {
dprintk("%s: DS %s: trying address %s\n",
@@ -185,7 +186,20 @@ nfs4_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds)
if (status)
goto out_put;
+ nfs_init_timeout_values(&ds_timeout, IPPROTO_TCP, dataserver_timeo,
+ dataserver_retrans);
+ spin_lock(&clp->cl_lock);
+ status = nfs_create_rpc_client(clp, &ds_timeout,
+ mds_srv->client->cl_auth->au_flavor);
+ spin_unlock(&clp->cl_lock);
+
+ if (IS_ERR(clp->cl_dsrpcclient))
+ status = PTR_ERR(clp->cl_dsrpcclient);
+ if (status < 0)
+ goto out_put;
+
ds->ds_clp = clp;
+
dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr);
out:
return status;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d221243..81c99a5 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -56,6 +56,7 @@ struct nfs_client {
struct rpc_cred *cl_machine_cred;
#if IS_ENABLED(CONFIG_NFS_V4)
+ struct rpc_clnt * cl_dsrpcclient; /* pNFS Data Server */
u64 cl_clientid; /* constant */
nfs4_verifier cl_confirm; /* Clientid verifier */
unsigned long cl_state;
--
1.8.3.1