cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfsctl.c (40230B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Syscall interface to knfsd.
      4 *
      5 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
      6 */
      7
      8#include <linux/slab.h>
      9#include <linux/namei.h>
     10#include <linux/ctype.h>
     11#include <linux/fs_context.h>
     12
     13#include <linux/sunrpc/svcsock.h>
     14#include <linux/lockd/lockd.h>
     15#include <linux/sunrpc/addr.h>
     16#include <linux/sunrpc/gss_api.h>
     17#include <linux/sunrpc/gss_krb5_enctypes.h>
     18#include <linux/sunrpc/rpc_pipe_fs.h>
     19#include <linux/module.h>
     20#include <linux/fsnotify.h>
     21
     22#include "idmap.h"
     23#include "nfsd.h"
     24#include "cache.h"
     25#include "state.h"
     26#include "netns.h"
     27#include "pnfs.h"
     28
     29/*
     30 *	We have a single directory with several nodes in it.
     31 */
     32enum {
     33	NFSD_Root = 1,
     34	NFSD_List,
     35	NFSD_Export_Stats,
     36	NFSD_Export_features,
     37	NFSD_Fh,
     38	NFSD_FO_UnlockIP,
     39	NFSD_FO_UnlockFS,
     40	NFSD_Threads,
     41	NFSD_Pool_Threads,
     42	NFSD_Pool_Stats,
     43	NFSD_Reply_Cache_Stats,
     44	NFSD_Versions,
     45	NFSD_Ports,
     46	NFSD_MaxBlkSize,
     47	NFSD_MaxConnections,
     48	NFSD_SupportedEnctypes,
     49	/*
     50	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
     51	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
     52	 */
     53#ifdef CONFIG_NFSD_V4
     54	NFSD_Leasetime,
     55	NFSD_Gracetime,
     56	NFSD_RecoveryDir,
     57	NFSD_V4EndGrace,
     58#endif
     59	NFSD_MaxReserved
     60};
     61
     62/*
     63 * write() for these nodes.
     64 */
     65static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
     66static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
     67static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
     68static ssize_t write_threads(struct file *file, char *buf, size_t size);
     69static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
     70static ssize_t write_versions(struct file *file, char *buf, size_t size);
     71static ssize_t write_ports(struct file *file, char *buf, size_t size);
     72static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
     73static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
     74#ifdef CONFIG_NFSD_V4
     75static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
     76static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
     77static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
     78static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
     79#endif
     80
     81static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
     82	[NFSD_Fh] = write_filehandle,
     83	[NFSD_FO_UnlockIP] = write_unlock_ip,
     84	[NFSD_FO_UnlockFS] = write_unlock_fs,
     85	[NFSD_Threads] = write_threads,
     86	[NFSD_Pool_Threads] = write_pool_threads,
     87	[NFSD_Versions] = write_versions,
     88	[NFSD_Ports] = write_ports,
     89	[NFSD_MaxBlkSize] = write_maxblksize,
     90	[NFSD_MaxConnections] = write_maxconn,
     91#ifdef CONFIG_NFSD_V4
     92	[NFSD_Leasetime] = write_leasetime,
     93	[NFSD_Gracetime] = write_gracetime,
     94	[NFSD_RecoveryDir] = write_recoverydir,
     95	[NFSD_V4EndGrace] = write_v4_end_grace,
     96#endif
     97};
     98
     99static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
    100{
    101	ino_t ino =  file_inode(file)->i_ino;
    102	char *data;
    103	ssize_t rv;
    104
    105	if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
    106		return -EINVAL;
    107
    108	data = simple_transaction_get(file, buf, size);
    109	if (IS_ERR(data))
    110		return PTR_ERR(data);
    111
    112	rv =  write_op[ino](file, data, size);
    113	if (rv >= 0) {
    114		simple_transaction_set(file, rv);
    115		rv = size;
    116	}
    117	return rv;
    118}
    119
    120static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
    121{
    122	if (! file->private_data) {
    123		/* An attempt to read a transaction file without writing
    124		 * causes a 0-byte write so that the file can return
    125		 * state information
    126		 */
    127		ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
    128		if (rv < 0)
    129			return rv;
    130	}
    131	return simple_transaction_read(file, buf, size, pos);
    132}
    133
    134static const struct file_operations transaction_ops = {
    135	.write		= nfsctl_transaction_write,
    136	.read		= nfsctl_transaction_read,
    137	.release	= simple_transaction_release,
    138	.llseek		= default_llseek,
    139};
    140
    141static int exports_net_open(struct net *net, struct file *file)
    142{
    143	int err;
    144	struct seq_file *seq;
    145	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
    146
    147	err = seq_open(file, &nfs_exports_op);
    148	if (err)
    149		return err;
    150
    151	seq = file->private_data;
    152	seq->private = nn->svc_export_cache;
    153	return 0;
    154}
    155
    156static int exports_proc_open(struct inode *inode, struct file *file)
    157{
    158	return exports_net_open(current->nsproxy->net_ns, file);
    159}
    160
    161static const struct proc_ops exports_proc_ops = {
    162	.proc_open	= exports_proc_open,
    163	.proc_read	= seq_read,
    164	.proc_lseek	= seq_lseek,
    165	.proc_release	= seq_release,
    166};
    167
    168static int exports_nfsd_open(struct inode *inode, struct file *file)
    169{
    170	return exports_net_open(inode->i_sb->s_fs_info, file);
    171}
    172
    173static const struct file_operations exports_nfsd_operations = {
    174	.open		= exports_nfsd_open,
    175	.read		= seq_read,
    176	.llseek		= seq_lseek,
    177	.release	= seq_release,
    178};
    179
    180static int export_features_show(struct seq_file *m, void *v)
    181{
    182	seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
    183	return 0;
    184}
    185
    186static int export_features_open(struct inode *inode, struct file *file)
    187{
    188	return single_open(file, export_features_show, NULL);
    189}
    190
    191static const struct file_operations export_features_operations = {
    192	.open		= export_features_open,
    193	.read		= seq_read,
    194	.llseek		= seq_lseek,
    195	.release	= single_release,
    196};
    197
    198#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
    199static int supported_enctypes_show(struct seq_file *m, void *v)
    200{
    201	seq_printf(m, KRB5_SUPPORTED_ENCTYPES);
    202	return 0;
    203}
    204
    205static int supported_enctypes_open(struct inode *inode, struct file *file)
    206{
    207	return single_open(file, supported_enctypes_show, NULL);
    208}
    209
    210static const struct file_operations supported_enctypes_ops = {
    211	.open		= supported_enctypes_open,
    212	.read		= seq_read,
    213	.llseek		= seq_lseek,
    214	.release	= single_release,
    215};
    216#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
    217
    218static const struct file_operations pool_stats_operations = {
    219	.open		= nfsd_pool_stats_open,
    220	.read		= seq_read,
    221	.llseek		= seq_lseek,
    222	.release	= nfsd_pool_stats_release,
    223};
    224
    225static const struct file_operations reply_cache_stats_operations = {
    226	.open		= nfsd_reply_cache_stats_open,
    227	.read		= seq_read,
    228	.llseek		= seq_lseek,
    229	.release	= single_release,
    230};
    231
    232/*----------------------------------------------------------------------------*/
    233/*
    234 * payload - write methods
    235 */
    236
    237static inline struct net *netns(struct file *file)
    238{
    239	return file_inode(file)->i_sb->s_fs_info;
    240}
    241
    242/*
    243 * write_unlock_ip - Release all locks used by a client
    244 *
    245 * Experimental.
    246 *
    247 * Input:
    248 *			buf:	'\n'-terminated C string containing a
    249 *				presentation format IP address
    250 *			size:	length of C string in @buf
    251 * Output:
    252 *	On success:	returns zero if all specified locks were released;
    253 *			returns one if one or more locks were not released
    254 *	On error:	return code is negative errno value
    255 */
    256static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
    257{
    258	struct sockaddr_storage address;
    259	struct sockaddr *sap = (struct sockaddr *)&address;
    260	size_t salen = sizeof(address);
    261	char *fo_path;
    262	struct net *net = netns(file);
    263
    264	/* sanity check */
    265	if (size == 0)
    266		return -EINVAL;
    267
    268	if (buf[size-1] != '\n')
    269		return -EINVAL;
    270
    271	fo_path = buf;
    272	if (qword_get(&buf, fo_path, size) < 0)
    273		return -EINVAL;
    274
    275	if (rpc_pton(net, fo_path, size, sap, salen) == 0)
    276		return -EINVAL;
    277
    278	return nlmsvc_unlock_all_by_ip(sap);
    279}
    280
    281/*
    282 * write_unlock_fs - Release all locks on a local file system
    283 *
    284 * Experimental.
    285 *
    286 * Input:
    287 *			buf:	'\n'-terminated C string containing the
    288 *				absolute pathname of a local file system
    289 *			size:	length of C string in @buf
    290 * Output:
    291 *	On success:	returns zero if all specified locks were released;
    292 *			returns one if one or more locks were not released
    293 *	On error:	return code is negative errno value
    294 */
    295static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
    296{
    297	struct path path;
    298	char *fo_path;
    299	int error;
    300
    301	/* sanity check */
    302	if (size == 0)
    303		return -EINVAL;
    304
    305	if (buf[size-1] != '\n')
    306		return -EINVAL;
    307
    308	fo_path = buf;
    309	if (qword_get(&buf, fo_path, size) < 0)
    310		return -EINVAL;
    311
    312	error = kern_path(fo_path, 0, &path);
    313	if (error)
    314		return error;
    315
    316	/*
    317	 * XXX: Needs better sanity checking.  Otherwise we could end up
    318	 * releasing locks on the wrong file system.
    319	 *
    320	 * For example:
    321	 * 1.  Does the path refer to a directory?
    322	 * 2.  Is that directory a mount point, or
    323	 * 3.  Is that directory the root of an exported file system?
    324	 */
    325	error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
    326
    327	path_put(&path);
    328	return error;
    329}
    330
    331/*
    332 * write_filehandle - Get a variable-length NFS file handle by path
    333 *
    334 * On input, the buffer contains a '\n'-terminated C string comprised of
    335 * three alphanumeric words separated by whitespace.  The string may
    336 * contain escape sequences.
    337 *
    338 * Input:
    339 *			buf:
    340 *				domain:		client domain name
    341 *				path:		export pathname
    342 *				maxsize:	numeric maximum size of
    343 *						@buf
    344 *			size:	length of C string in @buf
    345 * Output:
    346 *	On success:	passed-in buffer filled with '\n'-terminated C
    347 *			string containing a ASCII hex text version
    348 *			of the NFS file handle;
    349 *			return code is the size in bytes of the string
    350 *	On error:	return code is negative errno value
    351 */
    352static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
    353{
    354	char *dname, *path;
    355	int maxsize;
    356	char *mesg = buf;
    357	int len;
    358	struct auth_domain *dom;
    359	struct knfsd_fh fh;
    360
    361	if (size == 0)
    362		return -EINVAL;
    363
    364	if (buf[size-1] != '\n')
    365		return -EINVAL;
    366	buf[size-1] = 0;
    367
    368	dname = mesg;
    369	len = qword_get(&mesg, dname, size);
    370	if (len <= 0)
    371		return -EINVAL;
    372	
    373	path = dname+len+1;
    374	len = qword_get(&mesg, path, size);
    375	if (len <= 0)
    376		return -EINVAL;
    377
    378	len = get_int(&mesg, &maxsize);
    379	if (len)
    380		return len;
    381
    382	if (maxsize < NFS_FHSIZE)
    383		return -EINVAL;
    384	maxsize = min(maxsize, NFS3_FHSIZE);
    385
    386	if (qword_get(&mesg, mesg, size)>0)
    387		return -EINVAL;
    388
    389	/* we have all the words, they are in buf.. */
    390	dom = unix_domain_find(dname);
    391	if (!dom)
    392		return -ENOMEM;
    393
    394	len = exp_rootfh(netns(file), dom, path, &fh,  maxsize);
    395	auth_domain_put(dom);
    396	if (len)
    397		return len;
    398
    399	mesg = buf;
    400	len = SIMPLE_TRANSACTION_LIMIT;
    401	qword_addhex(&mesg, &len, fh.fh_raw, fh.fh_size);
    402	mesg[-1] = '\n';
    403	return mesg - buf;
    404}
    405
    406/*
    407 * write_threads - Start NFSD, or report the current number of running threads
    408 *
    409 * Input:
    410 *			buf:		ignored
    411 *			size:		zero
    412 * Output:
    413 *	On success:	passed-in buffer filled with '\n'-terminated C
    414 *			string numeric value representing the number of
    415 *			running NFSD threads;
    416 *			return code is the size in bytes of the string
    417 *	On error:	return code is zero
    418 *
    419 * OR
    420 *
    421 * Input:
    422 *			buf:		C string containing an unsigned
    423 *					integer value representing the
    424 *					number of NFSD threads to start
    425 *			size:		non-zero length of C string in @buf
    426 * Output:
    427 *	On success:	NFS service is started;
    428 *			passed-in buffer filled with '\n'-terminated C
    429 *			string numeric value representing the number of
    430 *			running NFSD threads;
    431 *			return code is the size in bytes of the string
    432 *	On error:	return code is zero or a negative errno value
    433 */
    434static ssize_t write_threads(struct file *file, char *buf, size_t size)
    435{
    436	char *mesg = buf;
    437	int rv;
    438	struct net *net = netns(file);
    439
    440	if (size > 0) {
    441		int newthreads;
    442		rv = get_int(&mesg, &newthreads);
    443		if (rv)
    444			return rv;
    445		if (newthreads < 0)
    446			return -EINVAL;
    447		rv = nfsd_svc(newthreads, net, file->f_cred);
    448		if (rv < 0)
    449			return rv;
    450	} else
    451		rv = nfsd_nrthreads(net);
    452
    453	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
    454}
    455
    456/*
    457 * write_pool_threads - Set or report the current number of threads per pool
    458 *
    459 * Input:
    460 *			buf:		ignored
    461 *			size:		zero
    462 *
    463 * OR
    464 *
    465 * Input:
    466 * 			buf:		C string containing whitespace-
    467 * 					separated unsigned integer values
    468 *					representing the number of NFSD
    469 *					threads to start in each pool
    470 *			size:		non-zero length of C string in @buf
    471 * Output:
    472 *	On success:	passed-in buffer filled with '\n'-terminated C
    473 *			string containing integer values representing the
    474 *			number of NFSD threads in each pool;
    475 *			return code is the size in bytes of the string
    476 *	On error:	return code is zero or a negative errno value
    477 */
    478static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
    479{
    480	/* if size > 0, look for an array of number of threads per node
    481	 * and apply them  then write out number of threads per node as reply
    482	 */
    483	char *mesg = buf;
    484	int i;
    485	int rv;
    486	int len;
    487	int npools;
    488	int *nthreads;
    489	struct net *net = netns(file);
    490
    491	mutex_lock(&nfsd_mutex);
    492	npools = nfsd_nrpools(net);
    493	if (npools == 0) {
    494		/*
    495		 * NFS is shut down.  The admin can start it by
    496		 * writing to the threads file but NOT the pool_threads
    497		 * file, sorry.  Report zero threads.
    498		 */
    499		mutex_unlock(&nfsd_mutex);
    500		strcpy(buf, "0\n");
    501		return strlen(buf);
    502	}
    503
    504	nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
    505	rv = -ENOMEM;
    506	if (nthreads == NULL)
    507		goto out_free;
    508
    509	if (size > 0) {
    510		for (i = 0; i < npools; i++) {
    511			rv = get_int(&mesg, &nthreads[i]);
    512			if (rv == -ENOENT)
    513				break;		/* fewer numbers than pools */
    514			if (rv)
    515				goto out_free;	/* syntax error */
    516			rv = -EINVAL;
    517			if (nthreads[i] < 0)
    518				goto out_free;
    519		}
    520		rv = nfsd_set_nrthreads(i, nthreads, net);
    521		if (rv)
    522			goto out_free;
    523	}
    524
    525	rv = nfsd_get_nrthreads(npools, nthreads, net);
    526	if (rv)
    527		goto out_free;
    528
    529	mesg = buf;
    530	size = SIMPLE_TRANSACTION_LIMIT;
    531	for (i = 0; i < npools && size > 0; i++) {
    532		snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
    533		len = strlen(mesg);
    534		size -= len;
    535		mesg += len;
    536	}
    537	rv = mesg - buf;
    538out_free:
    539	kfree(nthreads);
    540	mutex_unlock(&nfsd_mutex);
    541	return rv;
    542}
    543
    544static ssize_t
    545nfsd_print_version_support(struct nfsd_net *nn, char *buf, int remaining,
    546		const char *sep, unsigned vers, int minor)
    547{
    548	const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
    549	bool supported = !!nfsd_vers(nn, vers, NFSD_TEST);
    550
    551	if (vers == 4 && minor >= 0 &&
    552	    !nfsd_minorversion(nn, minor, NFSD_TEST))
    553		supported = false;
    554	if (minor == 0 && supported)
    555		/*
    556		 * special case for backward compatability.
    557		 * +4.0 is never reported, it is implied by
    558		 * +4, unless -4.0 is present.
    559		 */
    560		return 0;
    561	return snprintf(buf, remaining, format, sep,
    562			supported ? '+' : '-', vers, minor);
    563}
    564
    565static ssize_t __write_versions(struct file *file, char *buf, size_t size)
    566{
    567	char *mesg = buf;
    568	char *vers, *minorp, sign;
    569	int len, num, remaining;
    570	ssize_t tlen = 0;
    571	char *sep;
    572	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
    573
    574	if (size>0) {
    575		if (nn->nfsd_serv)
    576			/* Cannot change versions without updating
    577			 * nn->nfsd_serv->sv_xdrsize, and reallocing
    578			 * rq_argp and rq_resp
    579			 */
    580			return -EBUSY;
    581		if (buf[size-1] != '\n')
    582			return -EINVAL;
    583		buf[size-1] = 0;
    584
    585		vers = mesg;
    586		len = qword_get(&mesg, vers, size);
    587		if (len <= 0) return -EINVAL;
    588		do {
    589			enum vers_op cmd;
    590			unsigned minor;
    591			sign = *vers;
    592			if (sign == '+' || sign == '-')
    593				num = simple_strtol((vers+1), &minorp, 0);
    594			else
    595				num = simple_strtol(vers, &minorp, 0);
    596			if (*minorp == '.') {
    597				if (num != 4)
    598					return -EINVAL;
    599				if (kstrtouint(minorp+1, 0, &minor) < 0)
    600					return -EINVAL;
    601			}
    602
    603			cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
    604			switch(num) {
    605			case 2:
    606			case 3:
    607				nfsd_vers(nn, num, cmd);
    608				break;
    609			case 4:
    610				if (*minorp == '.') {
    611					if (nfsd_minorversion(nn, minor, cmd) < 0)
    612						return -EINVAL;
    613				} else if ((cmd == NFSD_SET) != nfsd_vers(nn, num, NFSD_TEST)) {
    614					/*
    615					 * Either we have +4 and no minors are enabled,
    616					 * or we have -4 and at least one minor is enabled.
    617					 * In either case, propagate 'cmd' to all minors.
    618					 */
    619					minor = 0;
    620					while (nfsd_minorversion(nn, minor, cmd) >= 0)
    621						minor++;
    622				}
    623				break;
    624			default:
    625				return -EINVAL;
    626			}
    627			vers += len + 1;
    628		} while ((len = qword_get(&mesg, vers, size)) > 0);
    629		/* If all get turned off, turn them back on, as
    630		 * having no versions is BAD
    631		 */
    632		nfsd_reset_versions(nn);
    633	}
    634
    635	/* Now write current state into reply buffer */
    636	len = 0;
    637	sep = "";
    638	remaining = SIMPLE_TRANSACTION_LIMIT;
    639	for (num=2 ; num <= 4 ; num++) {
    640		int minor;
    641		if (!nfsd_vers(nn, num, NFSD_AVAIL))
    642			continue;
    643
    644		minor = -1;
    645		do {
    646			len = nfsd_print_version_support(nn, buf, remaining,
    647					sep, num, minor);
    648			if (len >= remaining)
    649				goto out;
    650			remaining -= len;
    651			buf += len;
    652			tlen += len;
    653			minor++;
    654			if (len)
    655				sep = " ";
    656		} while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
    657	}
    658out:
    659	len = snprintf(buf, remaining, "\n");
    660	if (len >= remaining)
    661		return -EINVAL;
    662	return tlen + len;
    663}
    664
    665/*
    666 * write_versions - Set or report the available NFS protocol versions
    667 *
    668 * Input:
    669 *			buf:		ignored
    670 *			size:		zero
    671 * Output:
    672 *	On success:	passed-in buffer filled with '\n'-terminated C
    673 *			string containing positive or negative integer
    674 *			values representing the current status of each
    675 *			protocol version;
    676 *			return code is the size in bytes of the string
    677 *	On error:	return code is zero or a negative errno value
    678 *
    679 * OR
    680 *
    681 * Input:
    682 * 			buf:		C string containing whitespace-
    683 * 					separated positive or negative
    684 * 					integer values representing NFS
    685 * 					protocol versions to enable ("+n")
    686 * 					or disable ("-n")
    687 *			size:		non-zero length of C string in @buf
    688 * Output:
    689 *	On success:	status of zero or more protocol versions has
    690 *			been updated; passed-in buffer filled with
    691 *			'\n'-terminated C string containing positive
    692 *			or negative integer values representing the
    693 *			current status of each protocol version;
    694 *			return code is the size in bytes of the string
    695 *	On error:	return code is zero or a negative errno value
    696 */
    697static ssize_t write_versions(struct file *file, char *buf, size_t size)
    698{
    699	ssize_t rv;
    700
    701	mutex_lock(&nfsd_mutex);
    702	rv = __write_versions(file, buf, size);
    703	mutex_unlock(&nfsd_mutex);
    704	return rv;
    705}
    706
    707/*
    708 * Zero-length write.  Return a list of NFSD's current listener
    709 * transports.
    710 */
    711static ssize_t __write_ports_names(char *buf, struct net *net)
    712{
    713	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
    714
    715	if (nn->nfsd_serv == NULL)
    716		return 0;
    717	return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
    718}
    719
    720/*
    721 * A single 'fd' number was written, in which case it must be for
    722 * a socket of a supported family/protocol, and we use it as an
    723 * nfsd listener.
    724 */
    725static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred *cred)
    726{
    727	char *mesg = buf;
    728	int fd, err;
    729	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
    730
    731	err = get_int(&mesg, &fd);
    732	if (err != 0 || fd < 0)
    733		return -EINVAL;
    734
    735	if (svc_alien_sock(net, fd)) {
    736		printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
    737		return -EINVAL;
    738	}
    739
    740	err = nfsd_create_serv(net);
    741	if (err != 0)
    742		return err;
    743
    744	err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
    745
    746	if (err >= 0 &&
    747	    !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
    748		svc_get(nn->nfsd_serv);
    749
    750	nfsd_put(net);
    751	return err;
    752}
    753
    754/*
    755 * A transport listener is added by writing it's transport name and
    756 * a port number.
    757 */
    758static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cred *cred)
    759{
    760	char transport[16];
    761	struct svc_xprt *xprt;
    762	int port, err;
    763	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
    764
    765	if (sscanf(buf, "%15s %5u", transport, &port) != 2)
    766		return -EINVAL;
    767
    768	if (port < 1 || port > USHRT_MAX)
    769		return -EINVAL;
    770
    771	err = nfsd_create_serv(net);
    772	if (err != 0)
    773		return err;
    774
    775	err = svc_xprt_create(nn->nfsd_serv, transport, net,
    776			      PF_INET, port, SVC_SOCK_ANONYMOUS, cred);
    777	if (err < 0)
    778		goto out_err;
    779
    780	err = svc_xprt_create(nn->nfsd_serv, transport, net,
    781			      PF_INET6, port, SVC_SOCK_ANONYMOUS, cred);
    782	if (err < 0 && err != -EAFNOSUPPORT)
    783		goto out_close;
    784
    785	if (!nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
    786		svc_get(nn->nfsd_serv);
    787
    788	nfsd_put(net);
    789	return 0;
    790out_close:
    791	xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
    792	if (xprt != NULL) {
    793		svc_xprt_close(xprt);
    794		svc_xprt_put(xprt);
    795	}
    796out_err:
    797	nfsd_put(net);
    798	return err;
    799}
    800
    801static ssize_t __write_ports(struct file *file, char *buf, size_t size,
    802			     struct net *net)
    803{
    804	if (size == 0)
    805		return __write_ports_names(buf, net);
    806
    807	if (isdigit(buf[0]))
    808		return __write_ports_addfd(buf, net, file->f_cred);
    809
    810	if (isalpha(buf[0]))
    811		return __write_ports_addxprt(buf, net, file->f_cred);
    812
    813	return -EINVAL;
    814}
    815
    816/*
    817 * write_ports - Pass a socket file descriptor or transport name to listen on
    818 *
    819 * Input:
    820 *			buf:		ignored
    821 *			size:		zero
    822 * Output:
    823 *	On success:	passed-in buffer filled with a '\n'-terminated C
    824 *			string containing a whitespace-separated list of
    825 *			named NFSD listeners;
    826 *			return code is the size in bytes of the string
    827 *	On error:	return code is zero or a negative errno value
    828 *
    829 * OR
    830 *
    831 * Input:
    832 *			buf:		C string containing an unsigned
    833 *					integer value representing a bound
    834 *					but unconnected socket that is to be
    835 *					used as an NFSD listener; listen(3)
    836 *					must be called for a SOCK_STREAM
    837 *					socket, otherwise it is ignored
    838 *			size:		non-zero length of C string in @buf
    839 * Output:
    840 *	On success:	NFS service is started;
    841 *			passed-in buffer filled with a '\n'-terminated C
    842 *			string containing a unique alphanumeric name of
    843 *			the listener;
    844 *			return code is the size in bytes of the string
    845 *	On error:	return code is a negative errno value
    846 *
    847 * OR
    848 *
    849 * Input:
    850 *			buf:		C string containing a transport
    851 *					name and an unsigned integer value
    852 *					representing the port to listen on,
    853 *					separated by whitespace
    854 *			size:		non-zero length of C string in @buf
    855 * Output:
    856 *	On success:	returns zero; NFS service is started
    857 *	On error:	return code is a negative errno value
    858 */
    859static ssize_t write_ports(struct file *file, char *buf, size_t size)
    860{
    861	ssize_t rv;
    862
    863	mutex_lock(&nfsd_mutex);
    864	rv = __write_ports(file, buf, size, netns(file));
    865	mutex_unlock(&nfsd_mutex);
    866	return rv;
    867}
    868
    869
    870int nfsd_max_blksize;
    871
    872/*
    873 * write_maxblksize - Set or report the current NFS blksize
    874 *
    875 * Input:
    876 *			buf:		ignored
    877 *			size:		zero
    878 *
    879 * OR
    880 *
    881 * Input:
    882 * 			buf:		C string containing an unsigned
    883 * 					integer value representing the new
    884 * 					NFS blksize
    885 *			size:		non-zero length of C string in @buf
    886 * Output:
    887 *	On success:	passed-in buffer filled with '\n'-terminated C string
    888 *			containing numeric value of the current NFS blksize
    889 *			setting;
    890 *			return code is the size in bytes of the string
    891 *	On error:	return code is zero or a negative errno value
    892 */
    893static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
    894{
    895	char *mesg = buf;
    896	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
    897
    898	if (size > 0) {
    899		int bsize;
    900		int rv = get_int(&mesg, &bsize);
    901		if (rv)
    902			return rv;
    903		/* force bsize into allowed range and
    904		 * required alignment.
    905		 */
    906		bsize = max_t(int, bsize, 1024);
    907		bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE);
    908		bsize &= ~(1024-1);
    909		mutex_lock(&nfsd_mutex);
    910		if (nn->nfsd_serv) {
    911			mutex_unlock(&nfsd_mutex);
    912			return -EBUSY;
    913		}
    914		nfsd_max_blksize = bsize;
    915		mutex_unlock(&nfsd_mutex);
    916	}
    917
    918	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
    919							nfsd_max_blksize);
    920}
    921
    922/*
    923 * write_maxconn - Set or report the current max number of connections
    924 *
    925 * Input:
    926 *			buf:		ignored
    927 *			size:		zero
    928 * OR
    929 *
    930 * Input:
    931 * 			buf:		C string containing an unsigned
    932 * 					integer value representing the new
    933 * 					number of max connections
    934 *			size:		non-zero length of C string in @buf
    935 * Output:
    936 *	On success:	passed-in buffer filled with '\n'-terminated C string
    937 *			containing numeric value of max_connections setting
    938 *			for this net namespace;
    939 *			return code is the size in bytes of the string
    940 *	On error:	return code is zero or a negative errno value
    941 */
    942static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
    943{
    944	char *mesg = buf;
    945	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
    946	unsigned int maxconn = nn->max_connections;
    947
    948	if (size > 0) {
    949		int rv = get_uint(&mesg, &maxconn);
    950
    951		if (rv)
    952			return rv;
    953		nn->max_connections = maxconn;
    954	}
    955
    956	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
    957}
    958
    959#ifdef CONFIG_NFSD_V4
    960static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
    961				  time64_t *time, struct nfsd_net *nn)
    962{
    963	char *mesg = buf;
    964	int rv, i;
    965
    966	if (size > 0) {
    967		if (nn->nfsd_serv)
    968			return -EBUSY;
    969		rv = get_int(&mesg, &i);
    970		if (rv)
    971			return rv;
    972		/*
    973		 * Some sanity checking.  We don't have a reason for
    974		 * these particular numbers, but problems with the
    975		 * extremes are:
    976		 *	- Too short: the briefest network outage may
    977		 *	  cause clients to lose all their locks.  Also,
    978		 *	  the frequent polling may be wasteful.
    979		 *	- Too long: do you really want reboot recovery
    980		 *	  to take more than an hour?  Or to make other
    981		 *	  clients wait an hour before being able to
    982		 *	  revoke a dead client's locks?
    983		 */
    984		if (i < 10 || i > 3600)
    985			return -EINVAL;
    986		*time = i;
    987	}
    988
    989	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
    990}
    991
    992static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
    993				time64_t *time, struct nfsd_net *nn)
    994{
    995	ssize_t rv;
    996
    997	mutex_lock(&nfsd_mutex);
    998	rv = __nfsd4_write_time(file, buf, size, time, nn);
    999	mutex_unlock(&nfsd_mutex);
   1000	return rv;
   1001}
   1002
   1003/*
   1004 * write_leasetime - Set or report the current NFSv4 lease time
   1005 *
   1006 * Input:
   1007 *			buf:		ignored
   1008 *			size:		zero
   1009 *
   1010 * OR
   1011 *
   1012 * Input:
   1013 *			buf:		C string containing an unsigned
   1014 *					integer value representing the new
   1015 *					NFSv4 lease expiry time
   1016 *			size:		non-zero length of C string in @buf
   1017 * Output:
   1018 *	On success:	passed-in buffer filled with '\n'-terminated C
   1019 *			string containing unsigned integer value of the
   1020 *			current lease expiry time;
   1021 *			return code is the size in bytes of the string
   1022 *	On error:	return code is zero or a negative errno value
   1023 */
   1024static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
   1025{
   1026	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
   1027	return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
   1028}
   1029
   1030/*
   1031 * write_gracetime - Set or report current NFSv4 grace period time
   1032 *
   1033 * As above, but sets the time of the NFSv4 grace period.
   1034 *
   1035 * Note this should never be set to less than the *previous*
   1036 * lease-period time, but we don't try to enforce this.  (In the common
   1037 * case (a new boot), we don't know what the previous lease time was
   1038 * anyway.)
   1039 */
   1040static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
   1041{
   1042	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
   1043	return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
   1044}
   1045
   1046static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
   1047				   struct nfsd_net *nn)
   1048{
   1049	char *mesg = buf;
   1050	char *recdir;
   1051	int len, status;
   1052
   1053	if (size > 0) {
   1054		if (nn->nfsd_serv)
   1055			return -EBUSY;
   1056		if (size > PATH_MAX || buf[size-1] != '\n')
   1057			return -EINVAL;
   1058		buf[size-1] = 0;
   1059
   1060		recdir = mesg;
   1061		len = qword_get(&mesg, recdir, size);
   1062		if (len <= 0)
   1063			return -EINVAL;
   1064
   1065		status = nfs4_reset_recoverydir(recdir);
   1066		if (status)
   1067			return status;
   1068	}
   1069
   1070	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
   1071							nfs4_recoverydir());
   1072}
   1073
   1074/*
   1075 * write_recoverydir - Set or report the pathname of the recovery directory
   1076 *
   1077 * Input:
   1078 *			buf:		ignored
   1079 *			size:		zero
   1080 *
   1081 * OR
   1082 *
   1083 * Input:
   1084 *			buf:		C string containing the pathname
   1085 *					of the directory on a local file
   1086 *					system containing permanent NFSv4
   1087 *					recovery data
   1088 *			size:		non-zero length of C string in @buf
   1089 * Output:
   1090 *	On success:	passed-in buffer filled with '\n'-terminated C string
   1091 *			containing the current recovery pathname setting;
   1092 *			return code is the size in bytes of the string
   1093 *	On error:	return code is zero or a negative errno value
   1094 */
   1095static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
   1096{
   1097	ssize_t rv;
   1098	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
   1099
   1100	mutex_lock(&nfsd_mutex);
   1101	rv = __write_recoverydir(file, buf, size, nn);
   1102	mutex_unlock(&nfsd_mutex);
   1103	return rv;
   1104}
   1105
   1106/*
   1107 * write_v4_end_grace - release grace period for nfsd's v4.x lock manager
   1108 *
   1109 * Input:
   1110 *			buf:		ignored
   1111 *			size:		zero
   1112 * OR
   1113 *
   1114 * Input:
   1115 * 			buf:		any value
   1116 *			size:		non-zero length of C string in @buf
   1117 * Output:
   1118 *			passed-in buffer filled with "Y" or "N" with a newline
   1119 *			and NULL-terminated C string. This indicates whether
   1120 *			the grace period has ended in the current net
   1121 *			namespace. Return code is the size in bytes of the
   1122 *			string. Writing a string that starts with 'Y', 'y', or
   1123 *			'1' to the file will end the grace period for nfsd's v4
   1124 *			lock manager.
   1125 */
   1126static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
   1127{
   1128	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
   1129
   1130	if (size > 0) {
   1131		switch(buf[0]) {
   1132		case 'Y':
   1133		case 'y':
   1134		case '1':
   1135			if (!nn->nfsd_serv)
   1136				return -EBUSY;
   1137			nfsd4_end_grace(nn);
   1138			break;
   1139		default:
   1140			return -EINVAL;
   1141		}
   1142	}
   1143
   1144	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c\n",
   1145			 nn->grace_ended ? 'Y' : 'N');
   1146}
   1147
   1148#endif
   1149
   1150/*----------------------------------------------------------------------------*/
   1151/*
   1152 *	populating the filesystem.
   1153 */
   1154
   1155/* Basically copying rpc_get_inode. */
   1156static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
   1157{
   1158	struct inode *inode = new_inode(sb);
   1159	if (!inode)
   1160		return NULL;
   1161	/* Following advice from simple_fill_super documentation: */
   1162	inode->i_ino = iunique(sb, NFSD_MaxReserved);
   1163	inode->i_mode = mode;
   1164	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
   1165	switch (mode & S_IFMT) {
   1166	case S_IFDIR:
   1167		inode->i_fop = &simple_dir_operations;
   1168		inode->i_op = &simple_dir_inode_operations;
   1169		inc_nlink(inode);
   1170		break;
   1171	default:
   1172		break;
   1173	}
   1174	return inode;
   1175}
   1176
   1177static 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
   1194static 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;
   1207out:
   1208	inode_unlock(dir);
   1209	return dentry;
   1210out_err:
   1211	dput(dentry);
   1212	dentry = ERR_PTR(ret);
   1213	goto out;
   1214}
   1215
   1216static 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
   1224static 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
   1233struct 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 */
   1243static 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
   1256static 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. */
   1271static  int nfsdfs_create_files(struct dentry *root,
   1272				const struct tree_descr *files,
   1273				struct dentry **fdentries)
   1274{
   1275	struct inode *dir = d_inode(root);
   1276	struct inode *inode;
   1277	struct dentry *dentry;
   1278	int i;
   1279
   1280	inode_lock(dir);
   1281	for (i = 0; files->name && files->name[0]; i++, files++) {
   1282		dentry = d_alloc_name(root, files->name);
   1283		if (!dentry)
   1284			goto out;
   1285		inode = nfsd_get_inode(d_inode(root)->i_sb,
   1286					S_IFREG | files->mode);
   1287		if (!inode) {
   1288			dput(dentry);
   1289			goto out;
   1290		}
   1291		inode->i_fop = files->ops;
   1292		inode->i_private = __get_nfsdfs_client(dir);
   1293		d_add(dentry, inode);
   1294		fsnotify_create(dir, dentry);
   1295		if (fdentries)
   1296			fdentries[i] = dentry;
   1297	}
   1298	inode_unlock(dir);
   1299	return 0;
   1300out:
   1301	nfsdfs_remove_files(root);
   1302	inode_unlock(dir);
   1303	return -ENOMEM;
   1304}
   1305
   1306/* on success, returns positive number unique to that client. */
   1307struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
   1308				 struct nfsdfs_client *ncl, u32 id,
   1309				 const struct tree_descr *files,
   1310				 struct dentry **fdentries)
   1311{
   1312	struct dentry *dentry;
   1313	char name[11];
   1314	int ret;
   1315
   1316	sprintf(name, "%u", id);
   1317
   1318	dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
   1319	if (IS_ERR(dentry)) /* XXX: tossing errors? */
   1320		return NULL;
   1321	ret = nfsdfs_create_files(dentry, files, fdentries);
   1322	if (ret) {
   1323		nfsd_client_rmdir(dentry);
   1324		return NULL;
   1325	}
   1326	return dentry;
   1327}
   1328
   1329/* Taken from __rpc_rmdir: */
   1330void nfsd_client_rmdir(struct dentry *dentry)
   1331{
   1332	struct inode *dir = d_inode(dentry->d_parent);
   1333	struct inode *inode = d_inode(dentry);
   1334	int ret;
   1335
   1336	inode_lock(dir);
   1337	nfsdfs_remove_files(dentry);
   1338	clear_ncl(inode);
   1339	dget(dentry);
   1340	ret = simple_rmdir(dir, dentry);
   1341	WARN_ON_ONCE(ret);
   1342	d_drop(dentry);
   1343	fsnotify_rmdir(dir, dentry);
   1344	dput(dentry);
   1345	inode_unlock(dir);
   1346}
   1347
   1348static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
   1349{
   1350	struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
   1351							nfsd_net_id);
   1352	struct dentry *dentry;
   1353	int ret;
   1354
   1355	static const struct tree_descr nfsd_files[] = {
   1356		[NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
   1357		/* Per-export io stats use same ops as exports file */
   1358		[NFSD_Export_Stats] = {"export_stats", &exports_nfsd_operations, S_IRUGO},
   1359		[NFSD_Export_features] = {"export_features",
   1360					&export_features_operations, S_IRUGO},
   1361		[NFSD_FO_UnlockIP] = {"unlock_ip",
   1362					&transaction_ops, S_IWUSR|S_IRUSR},
   1363		[NFSD_FO_UnlockFS] = {"unlock_filesystem",
   1364					&transaction_ops, S_IWUSR|S_IRUSR},
   1365		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
   1366		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
   1367		[NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
   1368		[NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
   1369		[NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
   1370		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
   1371		[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
   1372		[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
   1373		[NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
   1374#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
   1375		[NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
   1376#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
   1377#ifdef CONFIG_NFSD_V4
   1378		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
   1379		[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
   1380		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
   1381		[NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
   1382#endif
   1383		/* last one */ {""}
   1384	};
   1385
   1386	ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
   1387	if (ret)
   1388		return ret;
   1389	dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
   1390	if (IS_ERR(dentry))
   1391		return PTR_ERR(dentry);
   1392	nn->nfsd_client_dir = dentry;
   1393	return 0;
   1394}
   1395
   1396static int nfsd_fs_get_tree(struct fs_context *fc)
   1397{
   1398	return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
   1399}
   1400
   1401static void nfsd_fs_free_fc(struct fs_context *fc)
   1402{
   1403	if (fc->s_fs_info)
   1404		put_net(fc->s_fs_info);
   1405}
   1406
   1407static const struct fs_context_operations nfsd_fs_context_ops = {
   1408	.free		= nfsd_fs_free_fc,
   1409	.get_tree	= nfsd_fs_get_tree,
   1410};
   1411
   1412static int nfsd_init_fs_context(struct fs_context *fc)
   1413{
   1414	put_user_ns(fc->user_ns);
   1415	fc->user_ns = get_user_ns(fc->net_ns->user_ns);
   1416	fc->ops = &nfsd_fs_context_ops;
   1417	return 0;
   1418}
   1419
   1420static void nfsd_umount(struct super_block *sb)
   1421{
   1422	struct net *net = sb->s_fs_info;
   1423
   1424	nfsd_shutdown_threads(net);
   1425
   1426	kill_litter_super(sb);
   1427	put_net(net);
   1428}
   1429
   1430static struct file_system_type nfsd_fs_type = {
   1431	.owner		= THIS_MODULE,
   1432	.name		= "nfsd",
   1433	.init_fs_context = nfsd_init_fs_context,
   1434	.kill_sb	= nfsd_umount,
   1435};
   1436MODULE_ALIAS_FS("nfsd");
   1437
   1438#ifdef CONFIG_PROC_FS
   1439static int create_proc_exports_entry(void)
   1440{
   1441	struct proc_dir_entry *entry;
   1442
   1443	entry = proc_mkdir("fs/nfs", NULL);
   1444	if (!entry)
   1445		return -ENOMEM;
   1446	entry = proc_create("exports", 0, entry, &exports_proc_ops);
   1447	if (!entry) {
   1448		remove_proc_entry("fs/nfs", NULL);
   1449		return -ENOMEM;
   1450	}
   1451	return 0;
   1452}
   1453#else /* CONFIG_PROC_FS */
   1454static int create_proc_exports_entry(void)
   1455{
   1456	return 0;
   1457}
   1458#endif
   1459
   1460unsigned int nfsd_net_id;
   1461
   1462static __net_init int nfsd_init_net(struct net *net)
   1463{
   1464	int retval;
   1465	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
   1466
   1467	retval = nfsd_export_init(net);
   1468	if (retval)
   1469		goto out_export_error;
   1470	retval = nfsd_idmap_init(net);
   1471	if (retval)
   1472		goto out_idmap_error;
   1473	nn->nfsd_versions = NULL;
   1474	nn->nfsd4_minorversions = NULL;
   1475	retval = nfsd_reply_cache_init(nn);
   1476	if (retval)
   1477		goto out_drc_error;
   1478	nn->nfsd4_lease = 90;	/* default lease time */
   1479	nn->nfsd4_grace = 90;
   1480	nn->somebody_reclaimed = false;
   1481	nn->track_reclaim_completes = false;
   1482	nn->clverifier_counter = prandom_u32();
   1483	nn->clientid_base = prandom_u32();
   1484	nn->clientid_counter = nn->clientid_base + 1;
   1485	nn->s2s_cp_cl_id = nn->clientid_counter++;
   1486
   1487	get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key));
   1488	seqlock_init(&nn->writeverf_lock);
   1489
   1490	return 0;
   1491
   1492out_drc_error:
   1493	nfsd_idmap_shutdown(net);
   1494out_idmap_error:
   1495	nfsd_export_shutdown(net);
   1496out_export_error:
   1497	return retval;
   1498}
   1499
   1500static __net_exit void nfsd_exit_net(struct net *net)
   1501{
   1502	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
   1503
   1504	nfsd_reply_cache_shutdown(nn);
   1505	nfsd_idmap_shutdown(net);
   1506	nfsd_export_shutdown(net);
   1507	nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
   1508}
   1509
   1510static struct pernet_operations nfsd_net_ops = {
   1511	.init = nfsd_init_net,
   1512	.exit = nfsd_exit_net,
   1513	.id   = &nfsd_net_id,
   1514	.size = sizeof(struct nfsd_net),
   1515};
   1516
   1517static int __init init_nfsd(void)
   1518{
   1519	int retval;
   1520	printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
   1521
   1522	retval = nfsd4_init_slabs();
   1523	if (retval)
   1524		return retval;
   1525	retval = nfsd4_init_pnfs();
   1526	if (retval)
   1527		goto out_free_slabs;
   1528	retval = nfsd_stat_init();	/* Statistics */
   1529	if (retval)
   1530		goto out_free_pnfs;
   1531	retval = nfsd_drc_slab_create();
   1532	if (retval)
   1533		goto out_free_stat;
   1534	nfsd_lockd_init();	/* lockd->nfsd callbacks */
   1535	retval = create_proc_exports_entry();
   1536	if (retval)
   1537		goto out_free_lockd;
   1538	retval = register_pernet_subsys(&nfsd_net_ops);
   1539	if (retval < 0)
   1540		goto out_free_exports;
   1541	retval = register_cld_notifier();
   1542	if (retval)
   1543		goto out_free_subsys;
   1544	retval = nfsd4_create_laundry_wq();
   1545	if (retval)
   1546		goto out_free_cld;
   1547	retval = register_filesystem(&nfsd_fs_type);
   1548	if (retval)
   1549		goto out_free_all;
   1550	return 0;
   1551out_free_all:
   1552	nfsd4_destroy_laundry_wq();
   1553out_free_cld:
   1554	unregister_cld_notifier();
   1555out_free_subsys:
   1556	unregister_pernet_subsys(&nfsd_net_ops);
   1557out_free_exports:
   1558	remove_proc_entry("fs/nfs/exports", NULL);
   1559	remove_proc_entry("fs/nfs", NULL);
   1560out_free_lockd:
   1561	nfsd_lockd_shutdown();
   1562	nfsd_drc_slab_free();
   1563out_free_stat:
   1564	nfsd_stat_shutdown();
   1565out_free_pnfs:
   1566	nfsd4_exit_pnfs();
   1567out_free_slabs:
   1568	nfsd4_free_slabs();
   1569	return retval;
   1570}
   1571
   1572static void __exit exit_nfsd(void)
   1573{
   1574	unregister_filesystem(&nfsd_fs_type);
   1575	nfsd4_destroy_laundry_wq();
   1576	unregister_cld_notifier();
   1577	unregister_pernet_subsys(&nfsd_net_ops);
   1578	nfsd_drc_slab_free();
   1579	remove_proc_entry("fs/nfs/exports", NULL);
   1580	remove_proc_entry("fs/nfs", NULL);
   1581	nfsd_stat_shutdown();
   1582	nfsd_lockd_shutdown();
   1583	nfsd4_free_slabs();
   1584	nfsd4_exit_pnfs();
   1585}
   1586
   1587MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
   1588MODULE_LICENSE("GPL");
   1589module_init(init_nfsd)
   1590module_exit(exit_nfsd)