aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c685
1 files changed, 17 insertions, 668 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index f005b5bebdc7..65afa382c5e3 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -56,35 +56,6 @@
56#define NFSDBG_FACILITY NFSDBG_CLIENT 56#define NFSDBG_FACILITY NFSDBG_CLIENT
57 57
58static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); 58static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
59#ifdef CONFIG_NFS_V4
60
61/*
62 * Get a unique NFSv4.0 callback identifier which will be used
63 * by the V4.0 callback service to lookup the nfs_client struct
64 */
65static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
66{
67 int ret = 0;
68 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
69
70 if (clp->rpc_ops->version != 4 || minorversion != 0)
71 return ret;
72retry:
73 if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL))
74 return -ENOMEM;
75 spin_lock(&nn->nfs_client_lock);
76 ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident);
77 spin_unlock(&nn->nfs_client_lock);
78 if (ret == -EAGAIN)
79 goto retry;
80 return ret;
81}
82#endif /* CONFIG_NFS_V4 */
83
84/*
85 * Turn off NFSv4 uid/gid mapping when using AUTH_SYS
86 */
87static bool nfs4_disable_idmapping = true;
88 59
89/* 60/*
90 * RPC cruft for NFS 61 * RPC cruft for NFS
@@ -130,24 +101,13 @@ const struct rpc_program nfsacl_program = {
130}; 101};
131#endif /* CONFIG_NFS_V3_ACL */ 102#endif /* CONFIG_NFS_V3_ACL */
132 103
133struct nfs_client_initdata {
134 unsigned long init_flags;
135 const char *hostname;
136 const struct sockaddr *addr;
137 size_t addrlen;
138 const struct nfs_rpc_ops *rpc_ops;
139 int proto;
140 u32 minorversion;
141 struct net *net;
142};
143
144/* 104/*
145 * Allocate a shared client record 105 * Allocate a shared client record
146 * 106 *
147 * Since these are allocated/deallocated very rarely, we don't 107 * Since these are allocated/deallocated very rarely, we don't
148 * bother putting them in a slab cache... 108 * bother putting them in a slab cache...
149 */ 109 */
150static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) 110struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
151{ 111{
152 struct nfs_client *clp; 112 struct nfs_client *clp;
153 struct rpc_cred *cred; 113 struct rpc_cred *cred;
@@ -177,18 +137,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
177 clp->cl_proto = cl_init->proto; 137 clp->cl_proto = cl_init->proto;
178 clp->cl_net = get_net(cl_init->net); 138 clp->cl_net = get_net(cl_init->net);
179 139
180#ifdef CONFIG_NFS_V4
181 err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
182 if (err)
183 goto error_cleanup;
184
185 spin_lock_init(&clp->cl_lock);
186 INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
187 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
188 clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
189 clp->cl_minorversion = cl_init->minorversion;
190 clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
191#endif
192 cred = rpc_lookup_machine_cred("*"); 140 cred = rpc_lookup_machine_cred("*");
193 if (!IS_ERR(cred)) 141 if (!IS_ERR(cred))
194 clp->cl_machine_cred = cred; 142 clp->cl_machine_cred = cred;
@@ -203,45 +151,6 @@ error_0:
203} 151}
204 152
205#ifdef CONFIG_NFS_V4 153#ifdef CONFIG_NFS_V4
206#ifdef CONFIG_NFS_V4_1
207static void nfs4_shutdown_session(struct nfs_client *clp)
208{
209 if (nfs4_has_session(clp)) {
210 nfs4_destroy_session(clp->cl_session);
211 nfs4_destroy_clientid(clp);
212 }
213
214}
215#else /* CONFIG_NFS_V4_1 */
216static void nfs4_shutdown_session(struct nfs_client *clp)
217{
218}
219#endif /* CONFIG_NFS_V4_1 */
220
221/*
222 * Destroy the NFS4 callback service
223 */
224static void nfs4_destroy_callback(struct nfs_client *clp)
225{
226 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
227 nfs_callback_down(clp->cl_mvops->minor_version);
228}
229
230static void nfs4_shutdown_client(struct nfs_client *clp)
231{
232 if (__test_and_clear_bit(NFS_CS_RENEWD, &clp->cl_res_state))
233 nfs4_kill_renewd(clp);
234 nfs4_shutdown_session(clp);
235 nfs4_destroy_callback(clp);
236 if (__test_and_clear_bit(NFS_CS_IDMAP, &clp->cl_res_state))
237 nfs_idmap_delete(clp);
238
239 rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
240 kfree(clp->cl_serverowner);
241 kfree(clp->cl_serverscope);
242 kfree(clp->cl_implid);
243}
244
245/* idr_remove_all is not needed as all id's are removed by nfs_put_client */ 154/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
246void nfs_cleanup_cb_ident_idr(struct net *net) 155void nfs_cleanup_cb_ident_idr(struct net *net)
247{ 156{
@@ -264,16 +173,7 @@ static void pnfs_init_server(struct nfs_server *server)
264 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC"); 173 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
265} 174}
266 175
267static void nfs4_destroy_server(struct nfs_server *server)
268{
269 nfs4_purge_state_owners(server);
270}
271
272#else 176#else
273static void nfs4_shutdown_client(struct nfs_client *clp)
274{
275}
276
277void nfs_cleanup_cb_ident_idr(struct net *net) 177void nfs_cleanup_cb_ident_idr(struct net *net)
278{ 178{
279} 179}
@@ -291,12 +191,10 @@ static void pnfs_init_server(struct nfs_server *server)
291/* 191/*
292 * Destroy a shared client record 192 * Destroy a shared client record
293 */ 193 */
294static void nfs_free_client(struct nfs_client *clp) 194void nfs_free_client(struct nfs_client *clp)
295{ 195{
296 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version); 196 dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
297 197
298 nfs4_shutdown_client(clp);
299
300 nfs_fscache_release_client_cookie(clp); 198 nfs_fscache_release_client_cookie(clp);
301 199
302 /* -EIO all pending I/O */ 200 /* -EIO all pending I/O */
@@ -333,7 +231,7 @@ void nfs_put_client(struct nfs_client *clp)
333 231
334 BUG_ON(!list_empty(&clp->cl_superblocks)); 232 BUG_ON(!list_empty(&clp->cl_superblocks));
335 233
336 nfs_free_client(clp); 234 clp->rpc_ops->free_client(clp);
337 } 235 }
338} 236}
339EXPORT_SYMBOL_GPL(nfs_put_client); 237EXPORT_SYMBOL_GPL(nfs_put_client);
@@ -412,8 +310,8 @@ static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
412 * Test if two socket addresses represent the same actual socket, 310 * Test if two socket addresses represent the same actual socket,
413 * by comparing (only) relevant fields, excluding the port number. 311 * by comparing (only) relevant fields, excluding the port number.
414 */ 312 */
415static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, 313int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
416 const struct sockaddr *sa2) 314 const struct sockaddr *sa2)
417{ 315{
418 if (sa1->sa_family != sa2->sa_family) 316 if (sa1->sa_family != sa2->sa_family)
419 return 0; 317 return 0;
@@ -447,33 +345,6 @@ static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
447 return 0; 345 return 0;
448} 346}
449 347
450#if defined(CONFIG_NFS_V4_1)
451/* Common match routine for v4.0 and v4.1 callback services */
452static bool nfs4_cb_match_client(const struct sockaddr *addr,
453 struct nfs_client *clp, u32 minorversion)
454{
455 struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
456
457 /* Don't match clients that failed to initialise */
458 if (!(clp->cl_cons_state == NFS_CS_READY ||
459 clp->cl_cons_state == NFS_CS_SESSION_INITING))
460 return false;
461
462 smp_rmb();
463
464 /* Match the version and minorversion */
465 if (clp->rpc_ops->version != 4 ||
466 clp->cl_minorversion != minorversion)
467 return false;
468
469 /* Match only the IP address, not the port number */
470 if (!nfs_sockaddr_match_ipaddr(addr, clap))
471 return false;
472
473 return true;
474}
475#endif /* CONFIG_NFS_V4_1 */
476
477/* 348/*
478 * Find an nfs_client on the list that matches the initialisation data 349 * Find an nfs_client on the list that matches the initialisation data
479 * that is supplied. 350 * that is supplied.
@@ -552,7 +423,7 @@ nfs_found_client(const struct nfs_client_initdata *cl_init,
552 * Look up a client by IP address and protocol version 423 * Look up a client by IP address and protocol version
553 * - creates a new record if one doesn't yet exist 424 * - creates a new record if one doesn't yet exist
554 */ 425 */
555static struct nfs_client * 426struct nfs_client *
556nfs_get_client(const struct nfs_client_initdata *cl_init, 427nfs_get_client(const struct nfs_client_initdata *cl_init,
557 const struct rpc_timeout *timeparms, 428 const struct rpc_timeout *timeparms,
558 const char *ip_addr, 429 const char *ip_addr,
@@ -572,7 +443,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
572 if (clp) { 443 if (clp) {
573 spin_unlock(&nn->nfs_client_lock); 444 spin_unlock(&nn->nfs_client_lock);
574 if (new) 445 if (new)
575 nfs_free_client(new); 446 new->rpc_ops->free_client(new);
576 return nfs_found_client(cl_init, clp); 447 return nfs_found_client(cl_init, clp);
577 } 448 }
578 if (new) { 449 if (new) {
@@ -586,7 +457,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
586 457
587 spin_unlock(&nn->nfs_client_lock); 458 spin_unlock(&nn->nfs_client_lock);
588 459
589 new = nfs_alloc_client(cl_init); 460 new = cl_init->rpc_ops->alloc_client(cl_init);
590 } while (!IS_ERR(new)); 461 } while (!IS_ERR(new));
591 462
592 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n", 463 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
@@ -607,7 +478,7 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state)
607/* 478/*
608 * Initialise the timeout values for a connection 479 * Initialise the timeout values for a connection
609 */ 480 */
610static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, 481void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
611 unsigned int timeo, unsigned int retrans) 482 unsigned int timeo, unsigned int retrans)
612{ 483{
613 to->to_initval = timeo * HZ / 10; 484 to->to_initval = timeo * HZ / 10;
@@ -648,9 +519,9 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
648/* 519/*
649 * Create an RPC client handle 520 * Create an RPC client handle
650 */ 521 */
651static int nfs_create_rpc_client(struct nfs_client *clp, 522int nfs_create_rpc_client(struct nfs_client *clp,
652 const struct rpc_timeout *timeparms, 523 const struct rpc_timeout *timeparms,
653 rpc_authflavor_t flavor) 524 rpc_authflavor_t flavor)
654{ 525{
655 struct rpc_clnt *clnt = NULL; 526 struct rpc_clnt *clnt = NULL;
656 struct rpc_create_args args = { 527 struct rpc_create_args args = {
@@ -767,7 +638,7 @@ static inline void nfs_init_server_aclclient(struct nfs_server *server)
767/* 638/*
768 * Create a general RPC client 639 * Create a general RPC client
769 */ 640 */
770static int nfs_init_server_rpcclient(struct nfs_server *server, 641int nfs_init_server_rpcclient(struct nfs_server *server,
771 const struct rpc_timeout *timeo, 642 const struct rpc_timeout *timeo,
772 rpc_authflavor_t pseudoflavour) 643 rpc_authflavor_t pseudoflavour)
773{ 644{
@@ -975,7 +846,6 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
975 server->wsize = NFS_MAX_FILE_IO_SIZE; 846 server->wsize = NFS_MAX_FILE_IO_SIZE;
976 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 847 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
977 server->pnfs_blksize = fsinfo->blksize; 848 server->pnfs_blksize = fsinfo->blksize;
978 set_pnfs_layoutdriver(server, mntfh, fsinfo->layouttype);
979 849
980 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL); 850 server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
981 851
@@ -1001,7 +871,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
1001/* 871/*
1002 * Probe filesystem information, including the FSID on v2/v3 872 * Probe filesystem information, including the FSID on v2/v3
1003 */ 873 */
1004static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr) 874int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr)
1005{ 875{
1006 struct nfs_fsinfo fsinfo; 876 struct nfs_fsinfo fsinfo;
1007 struct nfs_client *clp = server->nfs_client; 877 struct nfs_client *clp = server->nfs_client;
@@ -1045,7 +915,7 @@ out_error:
1045/* 915/*
1046 * Copy useful information when duplicating a server record 916 * Copy useful information when duplicating a server record
1047 */ 917 */
1048static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source) 918void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
1049{ 919{
1050 target->flags = source->flags; 920 target->flags = source->flags;
1051 target->rsize = source->rsize; 921 target->rsize = source->rsize;
@@ -1058,7 +928,7 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve
1058 target->options = source->options; 928 target->options = source->options;
1059} 929}
1060 930
1061static void nfs_server_insert_lists(struct nfs_server *server) 931void nfs_server_insert_lists(struct nfs_server *server)
1062{ 932{
1063 struct nfs_client *clp = server->nfs_client; 933 struct nfs_client *clp = server->nfs_client;
1064 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); 934 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
@@ -1092,7 +962,7 @@ static void nfs_server_remove_lists(struct nfs_server *server)
1092/* 962/*
1093 * Allocate and initialise a server record 963 * Allocate and initialise a server record
1094 */ 964 */
1095static struct nfs_server *nfs_alloc_server(void) 965struct nfs_server *nfs_alloc_server(void)
1096{ 966{
1097 struct nfs_server *server; 967 struct nfs_server *server;
1098 968
@@ -1138,7 +1008,6 @@ void nfs_free_server(struct nfs_server *server)
1138 dprintk("--> nfs_free_server()\n"); 1008 dprintk("--> nfs_free_server()\n");
1139 1009
1140 nfs_server_remove_lists(server); 1010 nfs_server_remove_lists(server);
1141 unset_pnfs_layoutdriver(server);
1142 1011
1143 if (server->destroy != NULL) 1012 if (server->destroy != NULL)
1144 server->destroy(server); 1013 server->destroy(server);
@@ -1226,522 +1095,6 @@ error:
1226 return ERR_PTR(error); 1095 return ERR_PTR(error);
1227} 1096}
1228 1097
1229#ifdef CONFIG_NFS_V4
1230/*
1231 * NFSv4.0 callback thread helper
1232 *
1233 * Find a client by callback identifier
1234 */
1235struct nfs_client *
1236nfs4_find_client_ident(struct net *net, int cb_ident)
1237{
1238 struct nfs_client *clp;
1239 struct nfs_net *nn = net_generic(net, nfs_net_id);
1240
1241 spin_lock(&nn->nfs_client_lock);
1242 clp = idr_find(&nn->cb_ident_idr, cb_ident);
1243 if (clp)
1244 atomic_inc(&clp->cl_count);
1245 spin_unlock(&nn->nfs_client_lock);
1246 return clp;
1247}
1248
1249#if defined(CONFIG_NFS_V4_1)
1250/*
1251 * NFSv4.1 callback thread helper
1252 * For CB_COMPOUND calls, find a client by IP address, protocol version,
1253 * minorversion, and sessionID
1254 *
1255 * Returns NULL if no such client
1256 */
1257struct nfs_client *
1258nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
1259 struct nfs4_sessionid *sid)
1260{
1261 struct nfs_client *clp;
1262 struct nfs_net *nn = net_generic(net, nfs_net_id);
1263
1264 spin_lock(&nn->nfs_client_lock);
1265 list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
1266 if (nfs4_cb_match_client(addr, clp, 1) == false)
1267 continue;
1268
1269 if (!nfs4_has_session(clp))
1270 continue;
1271
1272 /* Match sessionid*/
1273 if (memcmp(clp->cl_session->sess_id.data,
1274 sid->data, NFS4_MAX_SESSIONID_LEN) != 0)
1275 continue;
1276
1277 atomic_inc(&clp->cl_count);
1278 spin_unlock(&nn->nfs_client_lock);
1279 return clp;
1280 }
1281 spin_unlock(&nn->nfs_client_lock);
1282 return NULL;
1283}
1284
1285#else /* CONFIG_NFS_V4_1 */
1286
1287struct nfs_client *
1288nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
1289 struct nfs4_sessionid *sid)
1290{
1291 return NULL;
1292}
1293#endif /* CONFIG_NFS_V4_1 */
1294
1295/*
1296 * Initialize the NFS4 callback service
1297 */
1298static int nfs4_init_callback(struct nfs_client *clp)
1299{
1300 int error;
1301
1302 if (clp->rpc_ops->version == 4) {
1303 struct rpc_xprt *xprt;
1304
1305 xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
1306
1307 if (nfs4_has_session(clp)) {
1308 error = xprt_setup_backchannel(xprt,
1309 NFS41_BC_MIN_CALLBACKS);
1310 if (error < 0)
1311 return error;
1312 }
1313
1314 error = nfs_callback_up(clp->cl_mvops->minor_version, xprt);
1315 if (error < 0) {
1316 dprintk("%s: failed to start callback. Error = %d\n",
1317 __func__, error);
1318 return error;
1319 }
1320 __set_bit(NFS_CS_CALLBACK, &clp->cl_res_state);
1321 }
1322 return 0;
1323}
1324
1325/*
1326 * Initialize the minor version specific parts of an NFS4 client record
1327 */
1328static int nfs4_init_client_minor_version(struct nfs_client *clp)
1329{
1330#if defined(CONFIG_NFS_V4_1)
1331 if (clp->cl_mvops->minor_version) {
1332 struct nfs4_session *session = NULL;
1333 /*
1334 * Create the session and mark it expired.
1335 * When a SEQUENCE operation encounters the expired session
1336 * it will do session recovery to initialize it.
1337 */
1338 session = nfs4_alloc_session(clp);
1339 if (!session)
1340 return -ENOMEM;
1341
1342 clp->cl_session = session;
1343 /*
1344 * The create session reply races with the server back
1345 * channel probe. Mark the client NFS_CS_SESSION_INITING
1346 * so that the client back channel can find the
1347 * nfs_client struct
1348 */
1349 nfs_mark_client_ready(clp, NFS_CS_SESSION_INITING);
1350 }
1351#endif /* CONFIG_NFS_V4_1 */
1352
1353 return nfs4_init_callback(clp);
1354}
1355
1356/**
1357 * nfs4_init_client - Initialise an NFS4 client record
1358 *
1359 * @clp: nfs_client to initialise
1360 * @timeparms: timeout parameters for underlying RPC transport
1361 * @ip_addr: callback IP address in presentation format
1362 * @authflavor: authentication flavor for underlying RPC transport
1363 *
1364 * Returns pointer to an NFS client, or an ERR_PTR value.
1365 */
1366struct nfs_client *nfs4_init_client(struct nfs_client *clp,
1367 const struct rpc_timeout *timeparms,
1368 const char *ip_addr,
1369 rpc_authflavor_t authflavour)
1370{
1371 char buf[INET6_ADDRSTRLEN + 1];
1372 int error;
1373
1374 if (clp->cl_cons_state == NFS_CS_READY) {
1375 /* the client is initialised already */
1376 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
1377 return clp;
1378 }
1379
1380 /* Check NFS protocol revision and initialize RPC op vector */
1381 clp->rpc_ops = &nfs_v4_clientops;
1382
1383 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
1384 error = nfs_create_rpc_client(clp, timeparms, authflavour);
1385 if (error < 0)
1386 goto error;
1387
1388 /* If no clientaddr= option was specified, find a usable cb address */
1389 if (ip_addr == NULL) {
1390 struct sockaddr_storage cb_addr;
1391 struct sockaddr *sap = (struct sockaddr *)&cb_addr;
1392
1393 error = rpc_localaddr(clp->cl_rpcclient, sap, sizeof(cb_addr));
1394 if (error < 0)
1395 goto error;
1396 error = rpc_ntop(sap, buf, sizeof(buf));
1397 if (error < 0)
1398 goto error;
1399 ip_addr = (const char *)buf;
1400 }
1401 strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
1402
1403 error = nfs_idmap_new(clp);
1404 if (error < 0) {
1405 dprintk("%s: failed to create idmapper. Error = %d\n",
1406 __func__, error);
1407 goto error;
1408 }
1409 __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
1410
1411 error = nfs4_init_client_minor_version(clp);
1412 if (error < 0)
1413 goto error;
1414
1415 if (!nfs4_has_session(clp))
1416 nfs_mark_client_ready(clp, NFS_CS_READY);
1417 return clp;
1418
1419error:
1420 nfs_mark_client_ready(clp, error);
1421 nfs_put_client(clp);
1422 dprintk("<-- nfs4_init_client() = xerror %d\n", error);
1423 return ERR_PTR(error);
1424}
1425
1426/*
1427 * Set up an NFS4 client
1428 */
1429static int nfs4_set_client(struct nfs_server *server,
1430 const char *hostname,
1431 const struct sockaddr *addr,
1432 const size_t addrlen,
1433 const char *ip_addr,
1434 rpc_authflavor_t authflavour,
1435 int proto, const struct rpc_timeout *timeparms,
1436 u32 minorversion, struct net *net)
1437{
1438 struct nfs_client_initdata cl_init = {
1439 .hostname = hostname,
1440 .addr = addr,
1441 .addrlen = addrlen,
1442 .rpc_ops = &nfs_v4_clientops,
1443 .proto = proto,
1444 .minorversion = minorversion,
1445 .net = net,
1446 };
1447 struct nfs_client *clp;
1448 int error;
1449
1450 dprintk("--> nfs4_set_client()\n");
1451
1452 if (server->flags & NFS_MOUNT_NORESVPORT)
1453 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
1454
1455 /* Allocate or find a client reference we can use */
1456 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour);
1457 if (IS_ERR(clp)) {
1458 error = PTR_ERR(clp);
1459 goto error;
1460 }
1461
1462 /*
1463 * Query for the lease time on clientid setup or renewal
1464 *
1465 * Note that this will be set on nfs_clients that were created
1466 * only for the DS role and did not set this bit, but now will
1467 * serve a dual role.
1468 */
1469 set_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state);
1470
1471 server->nfs_client = clp;
1472 dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);
1473 return 0;
1474error:
1475 dprintk("<-- nfs4_set_client() = xerror %d\n", error);
1476 return error;
1477}
1478
1479/*
1480 * Set up a pNFS Data Server client.
1481 *
1482 * Return any existing nfs_client that matches server address,port,version
1483 * and minorversion.
1484 *
1485 * For a new nfs_client, use a soft mount (default), a low retrans and a
1486 * low timeout interval so that if a connection is lost, we retry through
1487 * the MDS.
1488 */
1489struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
1490 const struct sockaddr *ds_addr, int ds_addrlen,
1491 int ds_proto, unsigned int ds_timeo, unsigned int ds_retrans)
1492{
1493 struct nfs_client_initdata cl_init = {
1494 .addr = ds_addr,
1495 .addrlen = ds_addrlen,
1496 .rpc_ops = &nfs_v4_clientops,
1497 .proto = ds_proto,
1498 .minorversion = mds_clp->cl_minorversion,
1499 .net = mds_clp->cl_net,
1500 };
1501 struct rpc_timeout ds_timeout;
1502 struct nfs_client *clp;
1503
1504 /*
1505 * Set an authflavor equual to the MDS value. Use the MDS nfs_client
1506 * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS
1507 * (section 13.1 RFC 5661).
1508 */
1509 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
1510 clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr,
1511 mds_clp->cl_rpcclient->cl_auth->au_flavor);
1512
1513 dprintk("<-- %s %p\n", __func__, clp);
1514 return clp;
1515}
1516EXPORT_SYMBOL_GPL(nfs4_set_ds_client);
1517
1518/*
1519 * Session has been established, and the client marked ready.
1520 * Set the mount rsize and wsize with negotiated fore channel
1521 * attributes which will be bound checked in nfs_server_set_fsinfo.
1522 */
1523static void nfs4_session_set_rwsize(struct nfs_server *server)
1524{
1525#ifdef CONFIG_NFS_V4_1
1526 struct nfs4_session *sess;
1527 u32 server_resp_sz;
1528 u32 server_rqst_sz;
1529
1530 if (!nfs4_has_session(server->nfs_client))
1531 return;
1532 sess = server->nfs_client->cl_session;
1533 server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
1534 server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
1535
1536 if (server->rsize > server_resp_sz)
1537 server->rsize = server_resp_sz;
1538 if (server->wsize > server_rqst_sz)
1539 server->wsize = server_rqst_sz;
1540#endif /* CONFIG_NFS_V4_1 */
1541}
1542
1543static int nfs4_server_common_setup(struct nfs_server *server,
1544 struct nfs_fh *mntfh)
1545{
1546 struct nfs_fattr *fattr;
1547 int error;
1548
1549 BUG_ON(!server->nfs_client);
1550 BUG_ON(!server->nfs_client->rpc_ops);
1551 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1552
1553 /* data servers support only a subset of NFSv4.1 */
1554 if (is_ds_only_client(server->nfs_client))
1555 return -EPROTONOSUPPORT;
1556
1557 fattr = nfs_alloc_fattr();
1558 if (fattr == NULL)
1559 return -ENOMEM;
1560
1561 /* We must ensure the session is initialised first */
1562 error = nfs4_init_session(server);
1563 if (error < 0)
1564 goto out;
1565
1566 /* Probe the root fh to retrieve its FSID and filehandle */
1567 error = nfs4_get_rootfh(server, mntfh);
1568 if (error < 0)
1569 goto out;
1570
1571 dprintk("Server FSID: %llx:%llx\n",
1572 (unsigned long long) server->fsid.major,
1573 (unsigned long long) server->fsid.minor);
1574 dprintk("Mount FH: %d\n", mntfh->size);
1575
1576 nfs4_session_set_rwsize(server);
1577
1578 error = nfs_probe_fsinfo(server, mntfh, fattr);
1579 if (error < 0)
1580 goto out;
1581
1582 if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
1583 server->namelen = NFS4_MAXNAMLEN;
1584
1585 nfs_server_insert_lists(server);
1586 server->mount_time = jiffies;
1587 server->destroy = nfs4_destroy_server;
1588out:
1589 nfs_free_fattr(fattr);
1590 return error;
1591}
1592
1593/*
1594 * Create a version 4 volume record
1595 */
1596static int nfs4_init_server(struct nfs_server *server,
1597 const struct nfs_parsed_mount_data *data)
1598{
1599 struct rpc_timeout timeparms;
1600 int error;
1601
1602 dprintk("--> nfs4_init_server()\n");
1603
1604 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
1605 data->timeo, data->retrans);
1606
1607 /* Initialise the client representation from the mount data */
1608 server->flags = data->flags;
1609 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|NFS_CAP_POSIX_LOCK;
1610 if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
1611 server->caps |= NFS_CAP_READDIRPLUS;
1612 server->options = data->options;
1613
1614 /* Get a client record */
1615 error = nfs4_set_client(server,
1616 data->nfs_server.hostname,
1617 (const struct sockaddr *)&data->nfs_server.address,
1618 data->nfs_server.addrlen,
1619 data->client_address,
1620 data->auth_flavors[0],
1621 data->nfs_server.protocol,
1622 &timeparms,
1623 data->minorversion,
1624 data->net);
1625 if (error < 0)
1626 goto error;
1627
1628 /*
1629 * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
1630 * authentication.
1631 */
1632 if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX)
1633 server->caps |= NFS_CAP_UIDGID_NOMAP;
1634
1635 if (data->rsize)
1636 server->rsize = nfs_block_size(data->rsize, NULL);
1637 if (data->wsize)
1638 server->wsize = nfs_block_size(data->wsize, NULL);
1639
1640 server->acregmin = data->acregmin * HZ;
1641 server->acregmax = data->acregmax * HZ;
1642 server->acdirmin = data->acdirmin * HZ;
1643 server->acdirmax = data->acdirmax * HZ;
1644
1645 server->port = data->nfs_server.port;
1646
1647 error = nfs_init_server_rpcclient(server, &timeparms, data->auth_flavors[0]);
1648
1649error:
1650 /* Done */
1651 dprintk("<-- nfs4_init_server() = %d\n", error);
1652 return error;
1653}
1654
1655/*
1656 * Create a version 4 volume record
1657 * - keyed on server and FSID
1658 */
1659struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
1660 struct nfs_fh *mntfh)
1661{
1662 struct nfs_server *server;
1663 int error;
1664
1665 dprintk("--> nfs4_create_server()\n");
1666
1667 server = nfs_alloc_server();
1668 if (!server)
1669 return ERR_PTR(-ENOMEM);
1670
1671 /* set up the general RPC client */
1672 error = nfs4_init_server(server, data);
1673 if (error < 0)
1674 goto error;
1675
1676 error = nfs4_server_common_setup(server, mntfh);
1677 if (error < 0)
1678 goto error;
1679
1680 dprintk("<-- nfs4_create_server() = %p\n", server);
1681 return server;
1682
1683error:
1684 nfs_free_server(server);
1685 dprintk("<-- nfs4_create_server() = error %d\n", error);
1686 return ERR_PTR(error);
1687}
1688
1689/*
1690 * Create an NFS4 referral server record
1691 */
1692struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1693 struct nfs_fh *mntfh)
1694{
1695 struct nfs_client *parent_client;
1696 struct nfs_server *server, *parent_server;
1697 int error;
1698
1699 dprintk("--> nfs4_create_referral_server()\n");
1700
1701 server = nfs_alloc_server();
1702 if (!server)
1703 return ERR_PTR(-ENOMEM);
1704
1705 parent_server = NFS_SB(data->sb);
1706 parent_client = parent_server->nfs_client;
1707
1708 /* Initialise the client representation from the parent server */
1709 nfs_server_copy_userdata(server, parent_server);
1710 server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
1711
1712 /* Get a client representation.
1713 * Note: NFSv4 always uses TCP, */
1714 error = nfs4_set_client(server, data->hostname,
1715 data->addr,
1716 data->addrlen,
1717 parent_client->cl_ipaddr,
1718 data->authflavor,
1719 rpc_protocol(parent_server->client),
1720 parent_server->client->cl_timeout,
1721 parent_client->cl_mvops->minor_version,
1722 parent_client->cl_net);
1723 if (error < 0)
1724 goto error;
1725
1726 error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
1727 if (error < 0)
1728 goto error;
1729
1730 error = nfs4_server_common_setup(server, mntfh);
1731 if (error < 0)
1732 goto error;
1733
1734 dprintk("<-- nfs_create_referral_server() = %p\n", server);
1735 return server;
1736
1737error:
1738 nfs_free_server(server);
1739 dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
1740 return ERR_PTR(error);
1741}
1742
1743#endif /* CONFIG_NFS_V4 */
1744
1745/* 1098/*
1746 * Clone an NFS2, NFS3 or NFS4 server record 1099 * Clone an NFS2, NFS3 or NFS4 server record
1747 */ 1100 */
@@ -2091,7 +1444,3 @@ void nfs_fs_proc_exit(void)
2091} 1444}
2092 1445
2093#endif /* CONFIG_PROC_FS */ 1446#endif /* CONFIG_PROC_FS */
2094
2095module_param(nfs4_disable_idmapping, bool, 0644);
2096MODULE_PARM_DESC(nfs4_disable_idmapping,
2097 "Turn off NFSv4 idmapping when using 'sec=sys'");