5 #include <linux/module.h>
6 #include <linux/nfs_fs.h>
7 #include <linux/nfs_idmap.h>
18 #define NFSDBG_FACILITY NFSDBG_CLIENT
24 static int nfs_get_cb_ident_idr(
struct nfs_client *clp,
int minorversion)
29 if (clp->
rpc_ops->version != 4 || minorversion != 0)
35 ret =
idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident);
42 #ifdef CONFIG_NFS_V4_1
43 static void nfs4_shutdown_session(
struct nfs_client *clp)
45 if (nfs4_has_session(clp)) {
46 nfs4_destroy_session(clp->cl_session);
47 nfs4_destroy_clientid(clp);
52 static void nfs4_shutdown_session(
struct nfs_client *clp)
71 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
84 static void nfs4_destroy_callback(
struct nfs_client *clp)
90 static void nfs4_shutdown_client(
struct nfs_client *clp)
94 nfs4_shutdown_session(clp);
95 nfs4_destroy_callback(clp);
100 kfree(clp->cl_serverowner);
101 kfree(clp->cl_serverscope);
102 kfree(clp->cl_implid);
107 nfs4_shutdown_client(clp);
114 static int nfs4_init_callback(
struct nfs_client *clp)
118 if (clp->
rpc_ops->version == 4) {
119 struct rpc_xprt *xprt;
123 if (nfs4_has_session(clp)) {
132 dprintk(
"%s: failed to start callback. Error = %d\n",
144 static int nfs4_init_client_minor_version(
struct nfs_client *clp)
146 #if defined(CONFIG_NFS_V4_1)
147 if (clp->cl_mvops->minor_version) {
148 struct nfs4_session *session =
NULL;
154 session = nfs4_alloc_session(clp);
158 clp->cl_session = session;
169 return nfs4_init_callback(clp);
183 const struct rpc_timeout *timeparms,
185 rpc_authflavor_t authflavour)
193 dprintk(
"<-- nfs4_init_client() = 0 [already %p]\n", clp);
206 if (ip_addr ==
NULL) {
213 error =
rpc_ntop(sap, buf,
sizeof(buf));
216 ip_addr = (
const char *)buf;
218 strlcpy(clp->cl_ipaddr, ip_addr,
sizeof(clp->cl_ipaddr));
222 dprintk(
"%s: failed to create idmapper. Error = %d\n",
228 error = nfs4_init_client_minor_version(clp);
232 if (!nfs4_has_session(clp))
239 clp->cl_preserve_clid =
true;
250 dprintk(
"<-- nfs4_init_client() = xerror %d\n", error);
251 return ERR_PTR(error);
262 static void nfs4_swap_callback_idents(
struct nfs_client *keep,
266 unsigned int save = keep->cl_cb_ident;
268 if (keep->cl_cb_ident == drop->cl_cb_ident)
271 dprintk(
"%s: keeping callback ident %u and dropping ident %u\n",
272 __func__, keep->cl_cb_ident, drop->cl_cb_ident);
276 idr_replace(&nn->cb_ident_idr, keep, drop->cl_cb_ident);
277 keep->cl_cb_ident = drop->cl_cb_ident;
280 drop->cl_cb_ident = save;
300 struct rpc_cred *
cred)
304 struct nfs4_setclientid_res clid = {
305 .clientid =
new->cl_clientid,
306 .confirm =
new->cl_confirm,
317 if (pos->
rpc_ops != new->rpc_ops)
326 if (pos->cl_clientid != new->cl_clientid)
337 nfs4_swap_callback_idents(pos,
new);
341 dprintk(
"NFS: <-- %s using nfs_client = %p ({%d})\n",
347 dprintk(
"NFS: <-- %s status = %d, no result\n",
366 pr_err(
"NFS: %s Error: no matching nfs_client found\n", __func__);
370 #ifdef CONFIG_NFS_V4_1
376 if (a->cl_clientid != b->cl_clientid) {
377 dprintk(
"NFS: --> %s client ID %llx does not match %llx\n",
378 __func__, a->cl_clientid, b->cl_clientid);
381 dprintk(
"NFS: --> %s client ID %llx matches %llx\n",
382 __func__, a->cl_clientid, b->cl_clientid);
392 struct nfs41_server_owner *o1 = a->cl_serverowner;
393 struct nfs41_server_owner *
o2 = b->cl_serverowner;
395 if (o1->minor_id != o2->minor_id) {
396 dprintk(
"NFS: --> %s server owner minor IDs do not match\n",
401 if (o1->major_id_sz != o2->major_id_sz)
402 goto out_major_mismatch;
403 if (
memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0)
404 goto out_major_mismatch;
406 dprintk(
"NFS: --> %s server owners match\n", __func__);
410 dprintk(
"NFS: --> %s server owner major IDs do not match\n",
430 struct rpc_cred *
cred)
460 if (pos->
rpc_ops != new->rpc_ops)
469 if (!nfs4_match_clientids(pos,
new))
472 if (!nfs4_match_serverowners(pos,
new))
476 dprintk(
"NFS: <-- %s using nfs_client = %p ({%d})\n",
491 pr_err(
"NFS: %s Error: no matching nfs_client found\n", __func__);
496 static void nfs4_destroy_server(
struct nfs_server *server)
515 clp =
idr_find(&nn->cb_ident_idr, cb_ident);
522 #if defined(CONFIG_NFS_V4_1)
524 static bool nfs4_cb_match_client(
const struct sockaddr *
addr,
537 if (clp->
rpc_ops->version != 4 ||
542 if (!nfs_sockaddr_match_ipaddr(addr, clap))
564 if (nfs4_cb_match_client(addr, clp, 1) ==
false)
567 if (!nfs4_has_session(clp))
571 if (
memcmp(clp->cl_session->sess_id.data,
596 static int nfs4_set_client(
struct nfs_server *server,
597 const char *hostname,
599 const size_t addrlen,
601 rpc_authflavor_t authflavour,
602 int proto,
const struct rpc_timeout *timeparms,
603 u32 minorversion,
struct net *net)
617 dprintk(
"--> nfs4_set_client()\n");
625 error = PTR_ERR(clp);
639 dprintk(
"<-- nfs4_set_client() = 0 [new %p]\n", clp);
642 dprintk(
"<-- nfs4_set_client() = xerror %d\n", error);
657 const struct sockaddr *ds_addr,
int ds_addrlen,
658 int ds_proto,
unsigned int ds_timeo,
unsigned int ds_retrans)
662 .addrlen = ds_addrlen,
668 struct rpc_timeout ds_timeout;
680 dprintk(
"<-- %s %p\n", __func__, clp);
690 static void nfs4_session_set_rwsize(
struct nfs_server *server)
692 #ifdef CONFIG_NFS_V4_1
693 struct nfs4_session *sess;
700 server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
701 server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
703 if (server->
rsize > server_resp_sz)
704 server->
rsize = server_resp_sz;
705 if (server->
wsize > server_rqst_sz)
706 server->
wsize = server_rqst_sz;
710 static int nfs4_server_common_setup(
struct nfs_server *server,
729 error = nfs4_init_session(server);
738 dprintk(
"Server FSID: %llx:%llx\n",
739 (
unsigned long long) server->
fsid.major,
740 (
unsigned long long) server->
fsid.minor);
743 nfs4_session_set_rwsize(server);
754 server->
destroy = nfs4_destroy_server;
756 nfs_free_fattr(fattr);
763 static int nfs4_init_server(
struct nfs_server *server,
766 struct rpc_timeout timeparms;
769 dprintk(
"--> nfs4_init_server()\n");
782 error = nfs4_set_client(server,
799 if (nfs4_disable_idmapping && data->
auth_flavors[0] == RPC_AUTH_UNIX)
818 dprintk(
"<-- nfs4_init_server() = %d\n", error);
834 dprintk(
"--> nfs4_create_server()\n");
841 error = nfs4_init_server(server, mount_info->
parsed);
845 error = nfs4_server_common_setup(server, mount_info->
mntfh);
849 dprintk(
"<-- nfs4_create_server() = %p\n", server);
854 dprintk(
"<-- nfs4_create_server() = error %d\n", error);
855 return ERR_PTR(error);
868 dprintk(
"--> nfs4_create_referral_server()\n");
874 parent_server = NFS_SB(data->
sb);
883 error = nfs4_set_client(server, data->
hostname,
886 parent_client->cl_ipaddr,
889 parent_server->
client->cl_timeout,
890 parent_client->cl_mvops->minor_version,
899 error = nfs4_server_common_setup(server, mntfh);
903 dprintk(
"<-- nfs_create_referral_server() = %p\n", server);
908 dprintk(
"<-- nfs4_create_referral_server() = error %d\n", error);
909 return ERR_PTR(error);