hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/nfsd/nfsctl.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Syscall interface to knfsd.
34 *
....@@ -7,6 +8,7 @@
78 #include <linux/slab.h>
89 #include <linux/namei.h>
910 #include <linux/ctype.h>
11
+#include <linux/fs_context.h>
1012
1113 #include <linux/sunrpc/svcsock.h>
1214 #include <linux/lockd/lockd.h>
....@@ -15,6 +17,7 @@
1517 #include <linux/sunrpc/gss_krb5_enctypes.h>
1618 #include <linux/sunrpc/rpc_pipe_fs.h>
1719 #include <linux/module.h>
20
+#include <linux/fsnotify.h>
1821
1922 #include "idmap.h"
2023 #include "nfsd.h"
....@@ -52,6 +55,7 @@
5255 NFSD_RecoveryDir,
5356 NFSD_V4EndGrace,
5457 #endif
58
+ NFSD_MaxReserved
5559 };
5660
5761 /*
....@@ -153,11 +157,11 @@
153157 return exports_net_open(current->nsproxy->net_ns, file);
154158 }
155159
156
-static const struct file_operations exports_proc_operations = {
157
- .open = exports_proc_open,
158
- .read = seq_read,
159
- .llseek = seq_lseek,
160
- .release = seq_release,
160
+static const struct proc_ops exports_proc_ops = {
161
+ .proc_open = exports_proc_open,
162
+ .proc_read = seq_read,
163
+ .proc_lseek = seq_lseek,
164
+ .proc_release = seq_release,
161165 };
162166
163167 static int exports_nfsd_open(struct inode *inode, struct file *file)
....@@ -234,7 +238,7 @@
234238 return file_inode(file)->i_sb->s_fs_info;
235239 }
236240
237
-/**
241
+/*
238242 * write_unlock_ip - Release all locks used by a client
239243 *
240244 * Experimental.
....@@ -273,7 +277,7 @@
273277 return nlmsvc_unlock_all_by_ip(sap);
274278 }
275279
276
-/**
280
+/*
277281 * write_unlock_fs - Release all locks on a local file system
278282 *
279283 * Experimental.
....@@ -323,7 +327,7 @@
323327 return error;
324328 }
325329
326
-/**
330
+/*
327331 * write_filehandle - Get a variable-length NFS file handle by path
328332 *
329333 * On input, the buffer contains a '\n'-terminated C string comprised of
....@@ -347,7 +351,7 @@
347351 static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
348352 {
349353 char *dname, *path;
350
- int uninitialized_var(maxsize);
354
+ int maxsize;
351355 char *mesg = buf;
352356 int len;
353357 struct auth_domain *dom;
....@@ -398,7 +402,7 @@
398402 return mesg - buf;
399403 }
400404
401
-/**
405
+/*
402406 * write_threads - Start NFSD, or report the current number of running threads
403407 *
404408 * Input:
....@@ -439,7 +443,7 @@
439443 return rv;
440444 if (newthreads < 0)
441445 return -EINVAL;
442
- rv = nfsd_svc(newthreads, net);
446
+ rv = nfsd_svc(newthreads, net, file->f_cred);
443447 if (rv < 0)
444448 return rv;
445449 } else
....@@ -448,7 +452,7 @@
448452 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
449453 }
450454
451
-/**
455
+/*
452456 * write_pool_threads - Set or report the current number of threads per pool
453457 *
454458 * Input:
....@@ -537,14 +541,14 @@
537541 }
538542
539543 static ssize_t
540
-nfsd_print_version_support(char *buf, int remaining, const char *sep,
541
- unsigned vers, int minor)
544
+nfsd_print_version_support(struct nfsd_net *nn, char *buf, int remaining,
545
+ const char *sep, unsigned vers, int minor)
542546 {
543547 const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
544
- bool supported = !!nfsd_vers(vers, NFSD_TEST);
548
+ bool supported = !!nfsd_vers(nn, vers, NFSD_TEST);
545549
546550 if (vers == 4 && minor >= 0 &&
547
- !nfsd_minorversion(minor, NFSD_TEST))
551
+ !nfsd_minorversion(nn, minor, NFSD_TEST))
548552 supported = false;
549553 if (minor == 0 && supported)
550554 /*
....@@ -599,20 +603,20 @@
599603 switch(num) {
600604 case 2:
601605 case 3:
602
- nfsd_vers(num, cmd);
606
+ nfsd_vers(nn, num, cmd);
603607 break;
604608 case 4:
605609 if (*minorp == '.') {
606
- if (nfsd_minorversion(minor, cmd) < 0)
610
+ if (nfsd_minorversion(nn, minor, cmd) < 0)
607611 return -EINVAL;
608
- } else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) {
612
+ } else if ((cmd == NFSD_SET) != nfsd_vers(nn, num, NFSD_TEST)) {
609613 /*
610614 * Either we have +4 and no minors are enabled,
611615 * or we have -4 and at least one minor is enabled.
612616 * In either case, propagate 'cmd' to all minors.
613617 */
614618 minor = 0;
615
- while (nfsd_minorversion(minor, cmd) >= 0)
619
+ while (nfsd_minorversion(nn, minor, cmd) >= 0)
616620 minor++;
617621 }
618622 break;
....@@ -624,7 +628,7 @@
624628 /* If all get turned off, turn them back on, as
625629 * having no versions is BAD
626630 */
627
- nfsd_reset_versions();
631
+ nfsd_reset_versions(nn);
628632 }
629633
630634 /* Now write current state into reply buffer */
....@@ -633,12 +637,12 @@
633637 remaining = SIMPLE_TRANSACTION_LIMIT;
634638 for (num=2 ; num <= 4 ; num++) {
635639 int minor;
636
- if (!nfsd_vers(num, NFSD_AVAIL))
640
+ if (!nfsd_vers(nn, num, NFSD_AVAIL))
637641 continue;
638642
639643 minor = -1;
640644 do {
641
- len = nfsd_print_version_support(buf, remaining,
645
+ len = nfsd_print_version_support(nn, buf, remaining,
642646 sep, num, minor);
643647 if (len >= remaining)
644648 goto out;
....@@ -657,7 +661,7 @@
657661 return tlen + len;
658662 }
659663
660
-/**
664
+/*
661665 * write_versions - Set or report the available NFS protocol versions
662666 *
663667 * Input:
....@@ -717,7 +721,7 @@
717721 * a socket of a supported family/protocol, and we use it as an
718722 * nfsd listener.
719723 */
720
-static ssize_t __write_ports_addfd(char *buf, struct net *net)
724
+static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred *cred)
721725 {
722726 char *mesg = buf;
723727 int fd, err;
....@@ -736,7 +740,7 @@
736740 if (err != 0)
737741 return err;
738742
739
- err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
743
+ err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
740744 if (err < 0) {
741745 nfsd_destroy(net);
742746 return err;
....@@ -751,7 +755,7 @@
751755 * A transport listener is added by writing it's transport name and
752756 * a port number.
753757 */
754
-static ssize_t __write_ports_addxprt(char *buf, struct net *net)
758
+static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cred *cred)
755759 {
756760 char transport[16];
757761 struct svc_xprt *xprt;
....@@ -769,12 +773,12 @@
769773 return err;
770774
771775 err = svc_create_xprt(nn->nfsd_serv, transport, net,
772
- PF_INET, port, SVC_SOCK_ANONYMOUS);
776
+ PF_INET, port, SVC_SOCK_ANONYMOUS, cred);
773777 if (err < 0)
774778 goto out_err;
775779
776780 err = svc_create_xprt(nn->nfsd_serv, transport, net,
777
- PF_INET6, port, SVC_SOCK_ANONYMOUS);
781
+ PF_INET6, port, SVC_SOCK_ANONYMOUS, cred);
778782 if (err < 0 && err != -EAFNOSUPPORT)
779783 goto out_close;
780784
....@@ -802,15 +806,15 @@
802806 return __write_ports_names(buf, net);
803807
804808 if (isdigit(buf[0]))
805
- return __write_ports_addfd(buf, net);
809
+ return __write_ports_addfd(buf, net, file->f_cred);
806810
807811 if (isalpha(buf[0]))
808
- return __write_ports_addxprt(buf, net);
812
+ return __write_ports_addxprt(buf, net, file->f_cred);
809813
810814 return -EINVAL;
811815 }
812816
813
-/**
817
+/*
814818 * write_ports - Pass a socket file descriptor or transport name to listen on
815819 *
816820 * Input:
....@@ -866,7 +870,7 @@
866870
867871 int nfsd_max_blksize;
868872
869
-/**
873
+/*
870874 * write_maxblksize - Set or report the current NFS blksize
871875 *
872876 * Input:
....@@ -916,7 +920,7 @@
916920 nfsd_max_blksize);
917921 }
918922
919
-/**
923
+/*
920924 * write_maxconn - Set or report the current max number of connections
921925 *
922926 * Input:
....@@ -955,7 +959,7 @@
955959
956960 #ifdef CONFIG_NFSD_V4
957961 static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
958
- time_t *time, struct nfsd_net *nn)
962
+ time64_t *time, struct nfsd_net *nn)
959963 {
960964 char *mesg = buf;
961965 int rv, i;
....@@ -983,11 +987,11 @@
983987 *time = i;
984988 }
985989
986
- return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
990
+ return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
987991 }
988992
989993 static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
990
- time_t *time, struct nfsd_net *nn)
994
+ time64_t *time, struct nfsd_net *nn)
991995 {
992996 ssize_t rv;
993997
....@@ -997,7 +1001,7 @@
9971001 return rv;
9981002 }
9991003
1000
-/**
1004
+/*
10011005 * write_leasetime - Set or report the current NFSv4 lease time
10021006 *
10031007 * Input:
....@@ -1024,7 +1028,7 @@
10241028 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
10251029 }
10261030
1027
-/**
1031
+/*
10281032 * write_gracetime - Set or report current NFSv4 grace period time
10291033 *
10301034 * As above, but sets the time of the NFSv4 grace period.
....@@ -1068,7 +1072,7 @@
10681072 nfs4_recoverydir());
10691073 }
10701074
1071
-/**
1075
+/*
10721076 * write_recoverydir - Set or report the pathname of the recovery directory
10731077 *
10741078 * Input:
....@@ -1100,7 +1104,7 @@
11001104 return rv;
11011105 }
11021106
1103
-/**
1107
+/*
11041108 * write_v4_end_grace - release grace period for nfsd's v4.x lock manager
11051109 *
11061110 * Input:
....@@ -1149,8 +1153,203 @@
11491153 * populating the filesystem.
11501154 */
11511155
1152
-static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1156
+/* Basically copying rpc_get_inode. */
1157
+static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
11531158 {
1159
+ struct inode *inode = new_inode(sb);
1160
+ if (!inode)
1161
+ return NULL;
1162
+ /* Following advice from simple_fill_super documentation: */
1163
+ inode->i_ino = iunique(sb, NFSD_MaxReserved);
1164
+ inode->i_mode = mode;
1165
+ inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1166
+ switch (mode & S_IFMT) {
1167
+ case S_IFDIR:
1168
+ inode->i_fop = &simple_dir_operations;
1169
+ inode->i_op = &simple_dir_inode_operations;
1170
+ inc_nlink(inode);
1171
+ default:
1172
+ break;
1173
+ }
1174
+ return inode;
1175
+}
1176
+
1177
+static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
1178
+{
1179
+ struct inode *inode;
1180
+
1181
+ inode = nfsd_get_inode(dir->i_sb, mode);
1182
+ if (!inode)
1183
+ return -ENOMEM;
1184
+ if (ncl) {
1185
+ inode->i_private = ncl;
1186
+ kref_get(&ncl->cl_ref);
1187
+ }
1188
+ d_add(dentry, inode);
1189
+ inc_nlink(dir);
1190
+ fsnotify_mkdir(dir, dentry);
1191
+ return 0;
1192
+}
1193
+
1194
+static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name)
1195
+{
1196
+ struct inode *dir = parent->d_inode;
1197
+ struct dentry *dentry;
1198
+ int ret = -ENOMEM;
1199
+
1200
+ inode_lock(dir);
1201
+ dentry = d_alloc_name(parent, name);
1202
+ if (!dentry)
1203
+ goto out_err;
1204
+ ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
1205
+ if (ret)
1206
+ goto out_err;
1207
+out:
1208
+ inode_unlock(dir);
1209
+ return dentry;
1210
+out_err:
1211
+ dput(dentry);
1212
+ dentry = ERR_PTR(ret);
1213
+ goto out;
1214
+}
1215
+
1216
+static void clear_ncl(struct inode *inode)
1217
+{
1218
+ struct nfsdfs_client *ncl = inode->i_private;
1219
+
1220
+ inode->i_private = NULL;
1221
+ kref_put(&ncl->cl_ref, ncl->cl_release);
1222
+}
1223
+
1224
+static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1225
+{
1226
+ struct nfsdfs_client *nc = inode->i_private;
1227
+
1228
+ if (nc)
1229
+ kref_get(&nc->cl_ref);
1230
+ return nc;
1231
+}
1232
+
1233
+struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
1234
+{
1235
+ struct nfsdfs_client *nc;
1236
+
1237
+ inode_lock_shared(inode);
1238
+ nc = __get_nfsdfs_client(inode);
1239
+ inode_unlock_shared(inode);
1240
+ return nc;
1241
+}
1242
+/* from __rpc_unlink */
1243
+static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1244
+{
1245
+ int ret;
1246
+
1247
+ clear_ncl(d_inode(dentry));
1248
+ dget(dentry);
1249
+ ret = simple_unlink(dir, dentry);
1250
+ d_drop(dentry);
1251
+ fsnotify_unlink(dir, dentry);
1252
+ dput(dentry);
1253
+ WARN_ON_ONCE(ret);
1254
+}
1255
+
1256
+static void nfsdfs_remove_files(struct dentry *root)
1257
+{
1258
+ struct dentry *dentry, *tmp;
1259
+
1260
+ list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1261
+ if (!simple_positive(dentry)) {
1262
+ WARN_ON_ONCE(1); /* I think this can't happen? */
1263
+ continue;
1264
+ }
1265
+ nfsdfs_remove_file(d_inode(root), dentry);
1266
+ }
1267
+}
1268
+
1269
+/* XXX: cut'n'paste from simple_fill_super; figure out if we could share
1270
+ * code instead. */
1271
+static int nfsdfs_create_files(struct dentry *root,
1272
+ const struct tree_descr *files)
1273
+{
1274
+ struct inode *dir = d_inode(root);
1275
+ struct inode *inode;
1276
+ struct dentry *dentry;
1277
+ int i;
1278
+
1279
+ inode_lock(dir);
1280
+ for (i = 0; files->name && files->name[0]; i++, files++) {
1281
+ if (!files->name)
1282
+ continue;
1283
+ dentry = d_alloc_name(root, files->name);
1284
+ if (!dentry)
1285
+ goto out;
1286
+ inode = nfsd_get_inode(d_inode(root)->i_sb,
1287
+ S_IFREG | files->mode);
1288
+ if (!inode) {
1289
+ dput(dentry);
1290
+ goto out;
1291
+ }
1292
+ inode->i_fop = files->ops;
1293
+ inode->i_private = __get_nfsdfs_client(dir);
1294
+ d_add(dentry, inode);
1295
+ fsnotify_create(dir, dentry);
1296
+ }
1297
+ inode_unlock(dir);
1298
+ return 0;
1299
+out:
1300
+ nfsdfs_remove_files(root);
1301
+ inode_unlock(dir);
1302
+ return -ENOMEM;
1303
+}
1304
+
1305
+/* on success, returns positive number unique to that client. */
1306
+struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
1307
+ struct nfsdfs_client *ncl, u32 id,
1308
+ const struct tree_descr *files)
1309
+{
1310
+ struct dentry *dentry;
1311
+ char name[11];
1312
+ int ret;
1313
+
1314
+ sprintf(name, "%u", id);
1315
+
1316
+ dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
1317
+ if (IS_ERR(dentry)) /* XXX: tossing errors? */
1318
+ return NULL;
1319
+ ret = nfsdfs_create_files(dentry, files);
1320
+ if (ret) {
1321
+ nfsd_client_rmdir(dentry);
1322
+ return NULL;
1323
+ }
1324
+ return dentry;
1325
+}
1326
+
1327
+/* Taken from __rpc_rmdir: */
1328
+void nfsd_client_rmdir(struct dentry *dentry)
1329
+{
1330
+ struct inode *dir = d_inode(dentry->d_parent);
1331
+ struct inode *inode = d_inode(dentry);
1332
+ int ret;
1333
+
1334
+ inode_lock(dir);
1335
+ nfsdfs_remove_files(dentry);
1336
+ clear_ncl(inode);
1337
+ dget(dentry);
1338
+ ret = simple_rmdir(dir, dentry);
1339
+ WARN_ON_ONCE(ret);
1340
+ d_drop(dentry);
1341
+ fsnotify_rmdir(dir, dentry);
1342
+ dput(dentry);
1343
+ inode_unlock(dir);
1344
+}
1345
+
1346
+static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
1347
+{
1348
+ struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
1349
+ nfsd_net_id);
1350
+ struct dentry *dentry;
1351
+ int ret;
1352
+
11541353 static const struct tree_descr nfsd_files[] = {
11551354 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
11561355 [NFSD_Export_features] = {"export_features",
....@@ -1179,20 +1378,46 @@
11791378 #endif
11801379 /* last one */ {""}
11811380 };
1182
- get_net(sb->s_fs_info);
1183
- return simple_fill_super(sb, 0x6e667364, nfsd_files);
1381
+
1382
+ ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1383
+ if (ret)
1384
+ return ret;
1385
+ dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
1386
+ if (IS_ERR(dentry))
1387
+ return PTR_ERR(dentry);
1388
+ nn->nfsd_client_dir = dentry;
1389
+ return 0;
11841390 }
11851391
1186
-static struct dentry *nfsd_mount(struct file_system_type *fs_type,
1187
- int flags, const char *dev_name, void *data)
1392
+static int nfsd_fs_get_tree(struct fs_context *fc)
11881393 {
1189
- struct net *net = current->nsproxy->net_ns;
1190
- return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super);
1394
+ return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
1395
+}
1396
+
1397
+static void nfsd_fs_free_fc(struct fs_context *fc)
1398
+{
1399
+ if (fc->s_fs_info)
1400
+ put_net(fc->s_fs_info);
1401
+}
1402
+
1403
+static const struct fs_context_operations nfsd_fs_context_ops = {
1404
+ .free = nfsd_fs_free_fc,
1405
+ .get_tree = nfsd_fs_get_tree,
1406
+};
1407
+
1408
+static int nfsd_init_fs_context(struct fs_context *fc)
1409
+{
1410
+ put_user_ns(fc->user_ns);
1411
+ fc->user_ns = get_user_ns(fc->net_ns->user_ns);
1412
+ fc->ops = &nfsd_fs_context_ops;
1413
+ return 0;
11911414 }
11921415
11931416 static void nfsd_umount(struct super_block *sb)
11941417 {
11951418 struct net *net = sb->s_fs_info;
1419
+
1420
+ nfsd_shutdown_threads(net);
11961421
11971422 kill_litter_super(sb);
11981423 put_net(net);
....@@ -1201,7 +1426,7 @@
12011426 static struct file_system_type nfsd_fs_type = {
12021427 .owner = THIS_MODULE,
12031428 .name = "nfsd",
1204
- .mount = nfsd_mount,
1429
+ .init_fs_context = nfsd_init_fs_context,
12051430 .kill_sb = nfsd_umount,
12061431 };
12071432 MODULE_ALIAS_FS("nfsd");
....@@ -1214,8 +1439,7 @@
12141439 entry = proc_mkdir("fs/nfs", NULL);
12151440 if (!entry)
12161441 return -ENOMEM;
1217
- entry = proc_create("exports", 0, entry,
1218
- &exports_proc_operations);
1442
+ entry = proc_create("exports", 0, entry, &exports_proc_ops);
12191443 if (!entry) {
12201444 remove_proc_entry("fs/nfs", NULL);
12211445 return -ENOMEM;
....@@ -1242,16 +1466,28 @@
12421466 retval = nfsd_idmap_init(net);
12431467 if (retval)
12441468 goto out_idmap_error;
1469
+ nn->nfsd_versions = NULL;
1470
+ nn->nfsd4_minorversions = NULL;
1471
+ retval = nfsd_reply_cache_init(nn);
1472
+ if (retval)
1473
+ goto out_drc_error;
12451474 nn->nfsd4_lease = 90; /* default lease time */
12461475 nn->nfsd4_grace = 90;
12471476 nn->somebody_reclaimed = false;
1477
+ nn->track_reclaim_completes = false;
12481478 nn->clverifier_counter = prandom_u32();
1249
- nn->clientid_counter = prandom_u32();
1479
+ nn->clientid_base = prandom_u32();
1480
+ nn->clientid_counter = nn->clientid_base + 1;
1481
+ nn->s2s_cp_cl_id = nn->clientid_counter++;
12501482
12511483 atomic_set(&nn->ntf_refcnt, 0);
12521484 init_waitqueue_head(&nn->ntf_wq);
1485
+ seqlock_init(&nn->boot_lock);
1486
+
12531487 return 0;
12541488
1489
+out_drc_error:
1490
+ nfsd_idmap_shutdown(net);
12551491 out_idmap_error:
12561492 nfsd_export_shutdown(net);
12571493 out_export_error:
....@@ -1260,8 +1496,12 @@
12601496
12611497 static __net_exit void nfsd_exit_net(struct net *net)
12621498 {
1499
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1500
+
1501
+ nfsd_reply_cache_shutdown(nn);
12631502 nfsd_idmap_shutdown(net);
12641503 nfsd_export_shutdown(net);
1504
+ nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
12651505 }
12661506
12671507 static struct pernet_operations nfsd_net_ops = {
....@@ -1276,23 +1516,14 @@
12761516 int retval;
12771517 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
12781518
1279
- retval = register_pernet_subsys(&nfsd_net_ops);
1280
- if (retval < 0)
1281
- return retval;
1282
- retval = register_cld_notifier();
1283
- if (retval)
1284
- goto out_unregister_pernet;
12851519 retval = nfsd4_init_slabs();
12861520 if (retval)
1287
- goto out_unregister_notifier;
1521
+ return retval;
12881522 retval = nfsd4_init_pnfs();
12891523 if (retval)
12901524 goto out_free_slabs;
1291
- retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */
1292
- if (retval)
1293
- goto out_exit_pnfs;
12941525 nfsd_stat_init(); /* Statistics */
1295
- retval = nfsd_reply_cache_init();
1526
+ retval = nfsd_drc_slab_create();
12961527 if (retval)
12971528 goto out_free_stat;
12981529 nfsd_lockd_init(); /* lockd->nfsd callbacks */
....@@ -1301,44 +1532,48 @@
13011532 goto out_free_lockd;
13021533 retval = register_filesystem(&nfsd_fs_type);
13031534 if (retval)
1535
+ goto out_free_exports;
1536
+ retval = register_pernet_subsys(&nfsd_net_ops);
1537
+ if (retval < 0)
1538
+ goto out_free_filesystem;
1539
+ retval = register_cld_notifier();
1540
+ if (retval)
13041541 goto out_free_all;
13051542 return 0;
13061543 out_free_all:
1544
+ unregister_pernet_subsys(&nfsd_net_ops);
1545
+out_free_filesystem:
1546
+ unregister_filesystem(&nfsd_fs_type);
1547
+out_free_exports:
13071548 remove_proc_entry("fs/nfs/exports", NULL);
13081549 remove_proc_entry("fs/nfs", NULL);
13091550 out_free_lockd:
13101551 nfsd_lockd_shutdown();
1311
- nfsd_reply_cache_shutdown();
1552
+ nfsd_drc_slab_free();
13121553 out_free_stat:
13131554 nfsd_stat_shutdown();
1314
- nfsd_fault_inject_cleanup();
1315
-out_exit_pnfs:
13161555 nfsd4_exit_pnfs();
13171556 out_free_slabs:
13181557 nfsd4_free_slabs();
1319
-out_unregister_notifier:
1320
- unregister_cld_notifier();
1321
-out_unregister_pernet:
1322
- unregister_pernet_subsys(&nfsd_net_ops);
13231558 return retval;
13241559 }
13251560
13261561 static void __exit exit_nfsd(void)
13271562 {
1328
- nfsd_reply_cache_shutdown();
1563
+ unregister_cld_notifier();
1564
+ unregister_pernet_subsys(&nfsd_net_ops);
1565
+ nfsd_drc_slab_free();
13291566 remove_proc_entry("fs/nfs/exports", NULL);
13301567 remove_proc_entry("fs/nfs", NULL);
13311568 nfsd_stat_shutdown();
13321569 nfsd_lockd_shutdown();
13331570 nfsd4_free_slabs();
13341571 nfsd4_exit_pnfs();
1335
- nfsd_fault_inject_cleanup();
13361572 unregister_filesystem(&nfsd_fs_type);
1337
- unregister_cld_notifier();
1338
- unregister_pernet_subsys(&nfsd_net_ops);
13391573 }
13401574
13411575 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
13421576 MODULE_LICENSE("GPL");
1577
+MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);
13431578 module_init(init_nfsd)
13441579 module_exit(exit_nfsd)