NFS: advertise only supported callback netids

NFSv4.0 clients use the SETCLIENTID operation to inform NFS servers
how to contact a client's callback service.  If a server cannot
contact a client's callback service, that server will not delegate
to that client, which results in a performance loss.

Our client advertises "rdma" as the callback netid when the forward
channel is "rdma".  But our client always starts only "tcp" and
"tcp6" callback services.

Instead of advertising the forward channel netid, advertise "tcp"
or "tcp6" as the callback netid, based on the value of the
clientaddr mount option, since those are what our client currently
supports.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=69171
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
Chuck Lever 2014-03-12 12:51:47 -04:00 коммит произвёл Trond Myklebust
Родитель 3a0799a94c
Коммит 706cb8db3b
1 изменённых файлов: 18 добавлений и 6 удалений

Просмотреть файл

@ -4881,6 +4881,20 @@ nfs4_init_uniform_client_string(const struct nfs_client *clp,
nodename);
}
/*
* nfs4_callback_up_net() starts only "tcp" and "tcp6" callback
* services. Advertise one based on the address family of the
* clientaddr.
*/
static unsigned int
nfs4_init_callback_netid(const struct nfs_client *clp, char *buf, size_t len)
{
if (strchr(clp->cl_ipaddr, ':') != NULL)
return scnprintf(buf, len, "tcp6");
else
return scnprintf(buf, len, "tcp");
}
/**
* nfs4_proc_setclientid - Negotiate client ID
* @clp: state data structure
@ -4922,12 +4936,10 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
setclientid.sc_name,
sizeof(setclientid.sc_name));
/* cb_client4 */
rcu_read_lock();
setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
sizeof(setclientid.sc_netid), "%s",
rpc_peeraddr2str(clp->cl_rpcclient,
RPC_DISPLAY_NETID));
rcu_read_unlock();
setclientid.sc_netid_len =
nfs4_init_callback_netid(clp,
setclientid.sc_netid,
sizeof(setclientid.sc_netid));
setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr,
sizeof(setclientid.sc_uaddr), "%s.%u.%u",
clp->cl_ipaddr, port >> 8, port & 255);