hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/nfs/client.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* client.c: NFS client sharing and management code
23 *
34 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128
....@@ -53,6 +49,8 @@
5349 #include "pnfs.h"
5450 #include "nfs.h"
5551 #include "netns.h"
52
+#include "sysfs.h"
53
+#include "nfs42.h"
5654
5755 #define NFSDBG_FACILITY NFSDBG_CLIENT
5856
....@@ -151,7 +149,6 @@
151149 struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
152150 {
153151 struct nfs_client *clp;
154
- struct rpc_cred *cred;
155152 int err = -ENOMEM;
156153
157154 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
....@@ -182,11 +179,10 @@
182179
183180 clp->cl_flags = cl_init->init_flags;
184181 clp->cl_proto = cl_init->proto;
182
+ clp->cl_nconnect = cl_init->nconnect;
185183 clp->cl_net = get_net(cl_init->net);
186184
187
- cred = rpc_lookup_machine_cred("*");
188
- if (!IS_ERR(cred))
189
- clp->cl_machine_cred = cred;
185
+ clp->cl_principal = "*";
190186 nfs_fscache_get_client_cookie(clp);
191187
192188 return clp;
....@@ -201,7 +197,7 @@
201197 EXPORT_SYMBOL_GPL(nfs_alloc_client);
202198
203199 #if IS_ENABLED(CONFIG_NFS_V4)
204
-void nfs_cleanup_cb_ident_idr(struct net *net)
200
+static void nfs_cleanup_cb_ident_idr(struct net *net)
205201 {
206202 struct nfs_net *nn = net_generic(net, nfs_net_id);
207203
....@@ -223,7 +219,7 @@
223219 }
224220
225221 #else
226
-void nfs_cleanup_cb_ident_idr(struct net *net)
222
+static void nfs_cleanup_cb_ident_idr(struct net *net)
227223 {
228224 }
229225
....@@ -247,9 +243,6 @@
247243 /* -EIO all pending I/O */
248244 if (!IS_ERR(clp->cl_rpcclient))
249245 rpc_shutdown_client(clp->cl_rpcclient);
250
-
251
- if (clp->cl_machine_cred != NULL)
252
- put_rpccred(clp->cl_machine_cred);
253246
254247 put_net(clp->cl_net);
255248 put_nfs_version(clp->cl_nfs_mod);
....@@ -322,6 +315,12 @@
322315 /* Match nfsv4 minorversion */
323316 if (clp->cl_minorversion != data->minorversion)
324317 continue;
318
+
319
+ /* Match request for a dedicated DS */
320
+ if (test_bit(NFS_CS_DS, &data->init_flags) !=
321
+ test_bit(NFS_CS_DS, &clp->cl_flags))
322
+ continue;
323
+
325324 /* Match the full socket address */
326325 if (!rpc_cmp_addr_port(sap, clap))
327326 /* Match all xprt_switch full socket addresses */
....@@ -477,6 +476,7 @@
477476 to->to_maxval = to->to_initval;
478477 to->to_exponential = 0;
479478 break;
479
+#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
480480 case XPRT_TRANSPORT_UDP:
481481 if (retrans == NFS_UNSPEC_RETRANS)
482482 to->to_retries = NFS_DEF_UDP_RETRANS;
....@@ -487,6 +487,7 @@
487487 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
488488 to->to_exponential = 1;
489489 break;
490
+#endif
490491 default:
491492 BUG();
492493 }
....@@ -504,6 +505,7 @@
504505 struct rpc_create_args args = {
505506 .net = clp->cl_net,
506507 .protocol = clp->cl_proto,
508
+ .nconnect = clp->cl_nconnect,
507509 .address = (struct sockaddr *)&clp->cl_addr,
508510 .addrsize = clp->cl_addrlen,
509511 .timeout = cl_init->timeparms,
....@@ -512,6 +514,7 @@
512514 .program = &nfs_program,
513515 .version = clp->rpc_ops->version,
514516 .authflavor = flavor,
517
+ .cred = cl_init->cred,
515518 };
516519
517520 if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
....@@ -522,6 +525,10 @@
522525 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
523526 if (test_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags))
524527 args.flags |= RPC_CLNT_CREATE_INFINITE_SLOTS;
528
+ if (test_bit(NFS_CS_NOPING, &clp->cl_flags))
529
+ args.flags |= RPC_CLNT_CREATE_NOPING;
530
+ if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
531
+ args.flags |= RPC_CLNT_CREATE_REUSEPORT;
525532
526533 if (!IS_ERR(clp->cl_rpcclient))
527534 return 0;
....@@ -533,6 +540,7 @@
533540 return PTR_ERR(clnt);
534541 }
535542
543
+ clnt->cl_principal = clp->cl_principal;
536544 clp->cl_rpcclient = clnt;
537545 return 0;
538546 }
....@@ -563,6 +571,7 @@
563571 1 : 0,
564572 .net = clp->cl_net,
565573 .nlmclnt_ops = clp->cl_nfs_mod->rpc_ops->nlmclnt_ops,
574
+ .cred = current_cred(),
566575 };
567576
568577 if (nlm_init.nfs_version > 3)
....@@ -575,8 +584,10 @@
575584 default:
576585 nlm_init.protocol = IPPROTO_TCP;
577586 break;
587
+#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
578588 case XPRT_TRANSPORT_UDP:
579589 nlm_init.protocol = IPPROTO_UDP;
590
+#endif
580591 }
581592
582593 host = nlmclnt_init(&nlm_init);
....@@ -609,6 +620,8 @@
609620 sizeof(server->client->cl_timeout_default));
610621 server->client->cl_timeout = &server->client->cl_timeout_default;
611622 server->client->cl_softrtry = 0;
623
+ if (server->flags & NFS_MOUNT_SOFTERR)
624
+ server->client->cl_softerr = 1;
612625 if (server->flags & NFS_MOUNT_SOFT)
613626 server->client->cl_softrtry = 1;
614627
....@@ -651,25 +664,28 @@
651664 * Create a version 2 or 3 client
652665 */
653666 static int nfs_init_server(struct nfs_server *server,
654
- const struct nfs_parsed_mount_data *data,
655
- struct nfs_subversion *nfs_mod)
667
+ const struct fs_context *fc)
656668 {
669
+ const struct nfs_fs_context *ctx = nfs_fc2context(fc);
657670 struct rpc_timeout timeparms;
658671 struct nfs_client_initdata cl_init = {
659
- .hostname = data->nfs_server.hostname,
660
- .addr = (const struct sockaddr *)&data->nfs_server.address,
661
- .addrlen = data->nfs_server.addrlen,
662
- .nfs_mod = nfs_mod,
663
- .proto = data->nfs_server.protocol,
664
- .net = data->net,
672
+ .hostname = ctx->nfs_server.hostname,
673
+ .addr = (const struct sockaddr *)&ctx->nfs_server.address,
674
+ .addrlen = ctx->nfs_server.addrlen,
675
+ .nfs_mod = ctx->nfs_mod,
676
+ .proto = ctx->nfs_server.protocol,
677
+ .net = fc->net_ns,
665678 .timeparms = &timeparms,
679
+ .cred = server->cred,
680
+ .nconnect = ctx->nfs_server.nconnect,
681
+ .init_flags = (1UL << NFS_CS_REUSEPORT),
666682 };
667683 struct nfs_client *clp;
668684 int error;
669685
670
- nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
671
- data->timeo, data->retrans);
672
- if (data->flags & NFS_MOUNT_NORESVPORT)
686
+ nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
687
+ ctx->timeo, ctx->retrans);
688
+ if (ctx->flags & NFS_MOUNT_NORESVPORT)
673689 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
674690
675691 /* Allocate or find a client reference we can use */
....@@ -680,46 +696,46 @@
680696 server->nfs_client = clp;
681697
682698 /* Initialise the client representation from the mount data */
683
- server->flags = data->flags;
684
- server->options = data->options;
699
+ server->flags = ctx->flags;
700
+ server->options = ctx->options;
685701 server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
686702 NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
687703 NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
688704
689
- if (data->rsize)
690
- server->rsize = nfs_block_size(data->rsize, NULL);
691
- if (data->wsize)
692
- server->wsize = nfs_block_size(data->wsize, NULL);
705
+ if (ctx->rsize)
706
+ server->rsize = nfs_block_size(ctx->rsize, NULL);
707
+ if (ctx->wsize)
708
+ server->wsize = nfs_block_size(ctx->wsize, NULL);
693709
694
- server->acregmin = data->acregmin * HZ;
695
- server->acregmax = data->acregmax * HZ;
696
- server->acdirmin = data->acdirmin * HZ;
697
- server->acdirmax = data->acdirmax * HZ;
710
+ server->acregmin = ctx->acregmin * HZ;
711
+ server->acregmax = ctx->acregmax * HZ;
712
+ server->acdirmin = ctx->acdirmin * HZ;
713
+ server->acdirmax = ctx->acdirmax * HZ;
698714
699715 /* Start lockd here, before we might error out */
700716 error = nfs_start_lockd(server);
701717 if (error < 0)
702718 goto error;
703719
704
- server->port = data->nfs_server.port;
705
- server->auth_info = data->auth_info;
720
+ server->port = ctx->nfs_server.port;
721
+ server->auth_info = ctx->auth_info;
706722
707723 error = nfs_init_server_rpcclient(server, &timeparms,
708
- data->selected_flavor);
724
+ ctx->selected_flavor);
709725 if (error < 0)
710726 goto error;
711727
712728 /* Preserve the values of mount_server-related mount options */
713
- if (data->mount_server.addrlen) {
714
- memcpy(&server->mountd_address, &data->mount_server.address,
715
- data->mount_server.addrlen);
716
- server->mountd_addrlen = data->mount_server.addrlen;
729
+ if (ctx->mount_server.addrlen) {
730
+ memcpy(&server->mountd_address, &ctx->mount_server.address,
731
+ ctx->mount_server.addrlen);
732
+ server->mountd_addrlen = ctx->mount_server.addrlen;
717733 }
718
- server->mountd_version = data->mount_server.version;
719
- server->mountd_port = data->mount_server.port;
720
- server->mountd_protocol = data->mount_server.protocol;
734
+ server->mountd_version = ctx->mount_server.version;
735
+ server->mountd_port = ctx->mount_server.port;
736
+ server->mountd_protocol = ctx->mount_server.protocol;
721737
722
- server->namelen = data->namlen;
738
+ server->namelen = ctx->namlen;
723739 return 0;
724740
725741 error:
....@@ -734,7 +750,7 @@
734750 static void nfs_server_set_fsinfo(struct nfs_server *server,
735751 struct nfs_fsinfo *fsinfo)
736752 {
737
- unsigned long max_rpc_payload;
753
+ unsigned long max_rpc_payload, raw_max_rpc_payload;
738754
739755 /* Work out a lot of parameters */
740756 if (server->rsize == 0)
....@@ -747,7 +763,9 @@
747763 if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
748764 server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
749765
750
- max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
766
+ raw_max_rpc_payload = rpc_max_payload(server->client);
767
+ max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL);
768
+
751769 if (server->rsize > max_rpc_payload)
752770 server->rsize = max_rpc_payload;
753771 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
....@@ -780,6 +798,21 @@
780798 server->clone_blksize = fsinfo->clone_blksize;
781799 /* We're airborne Set socket buffersize */
782800 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
801
+
802
+#ifdef CONFIG_NFS_V4_2
803
+ /*
804
+ * Defaults until limited by the session parameters.
805
+ */
806
+ server->gxasize = min_t(unsigned int, raw_max_rpc_payload,
807
+ XATTR_SIZE_MAX);
808
+ server->sxasize = min_t(unsigned int, raw_max_rpc_payload,
809
+ XATTR_SIZE_MAX);
810
+ server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
811
+ nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
812
+
813
+ if (fsinfo->xattr_support)
814
+ server->caps |= NFS_CAP_XATTR;
815
+#endif
783816 }
784817
785818 /*
....@@ -931,6 +964,7 @@
931964 ida_destroy(&server->lockowner_id);
932965 ida_destroy(&server->openowner_id);
933966 nfs_free_iostats(server->io_stats);
967
+ put_cred(server->cred);
934968 kfree(server);
935969 nfs_release_automount_timer();
936970 }
....@@ -940,9 +974,9 @@
940974 * Create a version 2 or 3 volume record
941975 * - keyed on server and FSID
942976 */
943
-struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
944
- struct nfs_subversion *nfs_mod)
977
+struct nfs_server *nfs_create_server(struct fs_context *fc)
945978 {
979
+ struct nfs_fs_context *ctx = nfs_fc2context(fc);
946980 struct nfs_server *server;
947981 struct nfs_fattr *fattr;
948982 int error;
....@@ -951,24 +985,26 @@
951985 if (!server)
952986 return ERR_PTR(-ENOMEM);
953987
988
+ server->cred = get_cred(current_cred());
989
+
954990 error = -ENOMEM;
955991 fattr = nfs_alloc_fattr();
956992 if (fattr == NULL)
957993 goto error;
958994
959995 /* Get a client representation */
960
- error = nfs_init_server(server, mount_info->parsed, nfs_mod);
996
+ error = nfs_init_server(server, fc);
961997 if (error < 0)
962998 goto error;
963999
9641000 /* Probe the root fh to retrieve its FSID */
965
- error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
1001
+ error = nfs_probe_fsinfo(server, ctx->mntfh, fattr);
9661002 if (error < 0)
9671003 goto error;
9681004 if (server->nfs_client->rpc_ops->version == 3) {
9691005 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
9701006 server->namelen = NFS3_MAXNAMLEN;
971
- if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
1007
+ if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS))
9721008 server->caps |= NFS_CAP_READDIRPLUS;
9731009 } else {
9741010 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
....@@ -976,8 +1012,8 @@
9761012 }
9771013
9781014 if (!(fattr->valid & NFS_ATTR_FATTR)) {
979
- error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh,
980
- fattr, NULL, NULL);
1015
+ error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
1016
+ fattr, NULL, NULL);
9811017 if (error < 0) {
9821018 dprintk("nfs_create_server: getattr error = %d\n", -error);
9831019 goto error;
....@@ -1016,6 +1052,8 @@
10161052 server = nfs_alloc_server();
10171053 if (!server)
10181054 return ERR_PTR(-ENOMEM);
1055
+
1056
+ server->cred = get_cred(source->cred);
10191057
10201058 error = -ENOMEM;
10211059 fattr_fsinfo = nfs_alloc_fattr();
....@@ -1072,6 +1110,18 @@
10721110 #endif
10731111 spin_lock_init(&nn->nfs_client_lock);
10741112 nn->boot_time = ktime_get_real();
1113
+
1114
+ nfs_netns_sysfs_setup(nn, net);
1115
+}
1116
+
1117
+void nfs_clients_exit(struct net *net)
1118
+{
1119
+ struct nfs_net *nn = net_generic(net, nfs_net_id);
1120
+
1121
+ nfs_netns_sysfs_destroy(nn);
1122
+ nfs_cleanup_cb_ident_idr(net);
1123
+ WARN_ON_ONCE(!list_empty(&nn->nfs_client_list));
1124
+ WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list));
10751125 }
10761126
10771127 #ifdef CONFIG_PROC_FS