Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Syscall interface to knfsd.
0004  *
0005  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
0006  */
0007 
0008 #include <linux/slab.h>
0009 #include <linux/namei.h>
0010 #include <linux/ctype.h>
0011 #include <linux/fs_context.h>
0012 
0013 #include <linux/sunrpc/svcsock.h>
0014 #include <linux/lockd/lockd.h>
0015 #include <linux/sunrpc/addr.h>
0016 #include <linux/sunrpc/gss_api.h>
0017 #include <linux/sunrpc/gss_krb5_enctypes.h>
0018 #include <linux/sunrpc/rpc_pipe_fs.h>
0019 #include <linux/module.h>
0020 #include <linux/fsnotify.h>
0021 
0022 #include "idmap.h"
0023 #include "nfsd.h"
0024 #include "cache.h"
0025 #include "state.h"
0026 #include "netns.h"
0027 #include "pnfs.h"
0028 #include "filecache.h"
0029 
0030 /*
0031  *  We have a single directory with several nodes in it.
0032  */
0033 enum {
0034     NFSD_Root = 1,
0035     NFSD_List,
0036     NFSD_Export_Stats,
0037     NFSD_Export_features,
0038     NFSD_Fh,
0039     NFSD_FO_UnlockIP,
0040     NFSD_FO_UnlockFS,
0041     NFSD_Threads,
0042     NFSD_Pool_Threads,
0043     NFSD_Pool_Stats,
0044     NFSD_Reply_Cache_Stats,
0045     NFSD_Versions,
0046     NFSD_Ports,
0047     NFSD_MaxBlkSize,
0048     NFSD_MaxConnections,
0049     NFSD_Filecache,
0050     NFSD_SupportedEnctypes,
0051     /*
0052      * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
0053      * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
0054      */
0055 #ifdef CONFIG_NFSD_V4
0056     NFSD_Leasetime,
0057     NFSD_Gracetime,
0058     NFSD_RecoveryDir,
0059     NFSD_V4EndGrace,
0060 #endif
0061     NFSD_MaxReserved
0062 };
0063 
0064 /*
0065  * write() for these nodes.
0066  */
0067 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
0068 static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
0069 static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
0070 static ssize_t write_threads(struct file *file, char *buf, size_t size);
0071 static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
0072 static ssize_t write_versions(struct file *file, char *buf, size_t size);
0073 static ssize_t write_ports(struct file *file, char *buf, size_t size);
0074 static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
0075 static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
0076 #ifdef CONFIG_NFSD_V4
0077 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
0078 static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
0079 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
0080 static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
0081 #endif
0082 
0083 static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
0084     [NFSD_Fh] = write_filehandle,
0085     [NFSD_FO_UnlockIP] = write_unlock_ip,
0086     [NFSD_FO_UnlockFS] = write_unlock_fs,
0087     [NFSD_Threads] = write_threads,
0088     [NFSD_Pool_Threads] = write_pool_threads,
0089     [NFSD_Versions] = write_versions,
0090     [NFSD_Ports] = write_ports,
0091     [NFSD_MaxBlkSize] = write_maxblksize,
0092     [NFSD_MaxConnections] = write_maxconn,
0093 #ifdef CONFIG_NFSD_V4
0094     [NFSD_Leasetime] = write_leasetime,
0095     [NFSD_Gracetime] = write_gracetime,
0096     [NFSD_RecoveryDir] = write_recoverydir,
0097     [NFSD_V4EndGrace] = write_v4_end_grace,
0098 #endif
0099 };
0100 
0101 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
0102 {
0103     ino_t ino =  file_inode(file)->i_ino;
0104     char *data;
0105     ssize_t rv;
0106 
0107     if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
0108         return -EINVAL;
0109 
0110     data = simple_transaction_get(file, buf, size);
0111     if (IS_ERR(data))
0112         return PTR_ERR(data);
0113 
0114     rv =  write_op[ino](file, data, size);
0115     if (rv >= 0) {
0116         simple_transaction_set(file, rv);
0117         rv = size;
0118     }
0119     return rv;
0120 }
0121 
0122 static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
0123 {
0124     if (! file->private_data) {
0125         /* An attempt to read a transaction file without writing
0126          * causes a 0-byte write so that the file can return
0127          * state information
0128          */
0129         ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
0130         if (rv < 0)
0131             return rv;
0132     }
0133     return simple_transaction_read(file, buf, size, pos);
0134 }
0135 
0136 static const struct file_operations transaction_ops = {
0137     .write      = nfsctl_transaction_write,
0138     .read       = nfsctl_transaction_read,
0139     .release    = simple_transaction_release,
0140     .llseek     = default_llseek,
0141 };
0142 
0143 static int exports_net_open(struct net *net, struct file *file)
0144 {
0145     int err;
0146     struct seq_file *seq;
0147     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0148 
0149     err = seq_open(file, &nfs_exports_op);
0150     if (err)
0151         return err;
0152 
0153     seq = file->private_data;
0154     seq->private = nn->svc_export_cache;
0155     return 0;
0156 }
0157 
0158 static int exports_proc_open(struct inode *inode, struct file *file)
0159 {
0160     return exports_net_open(current->nsproxy->net_ns, file);
0161 }
0162 
0163 static const struct proc_ops exports_proc_ops = {
0164     .proc_open  = exports_proc_open,
0165     .proc_read  = seq_read,
0166     .proc_lseek = seq_lseek,
0167     .proc_release   = seq_release,
0168 };
0169 
0170 static int exports_nfsd_open(struct inode *inode, struct file *file)
0171 {
0172     return exports_net_open(inode->i_sb->s_fs_info, file);
0173 }
0174 
0175 static const struct file_operations exports_nfsd_operations = {
0176     .open       = exports_nfsd_open,
0177     .read       = seq_read,
0178     .llseek     = seq_lseek,
0179     .release    = seq_release,
0180 };
0181 
0182 static int export_features_show(struct seq_file *m, void *v)
0183 {
0184     seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
0185     return 0;
0186 }
0187 
0188 static int export_features_open(struct inode *inode, struct file *file)
0189 {
0190     return single_open(file, export_features_show, NULL);
0191 }
0192 
0193 static const struct file_operations export_features_operations = {
0194     .open       = export_features_open,
0195     .read       = seq_read,
0196     .llseek     = seq_lseek,
0197     .release    = single_release,
0198 };
0199 
0200 #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
0201 static int supported_enctypes_show(struct seq_file *m, void *v)
0202 {
0203     seq_printf(m, KRB5_SUPPORTED_ENCTYPES);
0204     return 0;
0205 }
0206 
0207 static int supported_enctypes_open(struct inode *inode, struct file *file)
0208 {
0209     return single_open(file, supported_enctypes_show, NULL);
0210 }
0211 
0212 static const struct file_operations supported_enctypes_ops = {
0213     .open       = supported_enctypes_open,
0214     .read       = seq_read,
0215     .llseek     = seq_lseek,
0216     .release    = single_release,
0217 };
0218 #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
0219 
0220 static const struct file_operations pool_stats_operations = {
0221     .open       = nfsd_pool_stats_open,
0222     .read       = seq_read,
0223     .llseek     = seq_lseek,
0224     .release    = nfsd_pool_stats_release,
0225 };
0226 
0227 static const struct file_operations reply_cache_stats_operations = {
0228     .open       = nfsd_reply_cache_stats_open,
0229     .read       = seq_read,
0230     .llseek     = seq_lseek,
0231     .release    = single_release,
0232 };
0233 
0234 static const struct file_operations filecache_ops = {
0235     .open       = nfsd_file_cache_stats_open,
0236     .read       = seq_read,
0237     .llseek     = seq_lseek,
0238     .release    = single_release,
0239 };
0240 
0241 /*----------------------------------------------------------------------------*/
0242 /*
0243  * payload - write methods
0244  */
0245 
0246 static inline struct net *netns(struct file *file)
0247 {
0248     return file_inode(file)->i_sb->s_fs_info;
0249 }
0250 
0251 /*
0252  * write_unlock_ip - Release all locks used by a client
0253  *
0254  * Experimental.
0255  *
0256  * Input:
0257  *          buf:    '\n'-terminated C string containing a
0258  *              presentation format IP address
0259  *          size:   length of C string in @buf
0260  * Output:
0261  *  On success: returns zero if all specified locks were released;
0262  *          returns one if one or more locks were not released
0263  *  On error:   return code is negative errno value
0264  */
0265 static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
0266 {
0267     struct sockaddr_storage address;
0268     struct sockaddr *sap = (struct sockaddr *)&address;
0269     size_t salen = sizeof(address);
0270     char *fo_path;
0271     struct net *net = netns(file);
0272 
0273     /* sanity check */
0274     if (size == 0)
0275         return -EINVAL;
0276 
0277     if (buf[size-1] != '\n')
0278         return -EINVAL;
0279 
0280     fo_path = buf;
0281     if (qword_get(&buf, fo_path, size) < 0)
0282         return -EINVAL;
0283 
0284     if (rpc_pton(net, fo_path, size, sap, salen) == 0)
0285         return -EINVAL;
0286 
0287     return nlmsvc_unlock_all_by_ip(sap);
0288 }
0289 
0290 /*
0291  * write_unlock_fs - Release all locks on a local file system
0292  *
0293  * Experimental.
0294  *
0295  * Input:
0296  *          buf:    '\n'-terminated C string containing the
0297  *              absolute pathname of a local file system
0298  *          size:   length of C string in @buf
0299  * Output:
0300  *  On success: returns zero if all specified locks were released;
0301  *          returns one if one or more locks were not released
0302  *  On error:   return code is negative errno value
0303  */
0304 static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
0305 {
0306     struct path path;
0307     char *fo_path;
0308     int error;
0309 
0310     /* sanity check */
0311     if (size == 0)
0312         return -EINVAL;
0313 
0314     if (buf[size-1] != '\n')
0315         return -EINVAL;
0316 
0317     fo_path = buf;
0318     if (qword_get(&buf, fo_path, size) < 0)
0319         return -EINVAL;
0320 
0321     error = kern_path(fo_path, 0, &path);
0322     if (error)
0323         return error;
0324 
0325     /*
0326      * XXX: Needs better sanity checking.  Otherwise we could end up
0327      * releasing locks on the wrong file system.
0328      *
0329      * For example:
0330      * 1.  Does the path refer to a directory?
0331      * 2.  Is that directory a mount point, or
0332      * 3.  Is that directory the root of an exported file system?
0333      */
0334     error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
0335 
0336     path_put(&path);
0337     return error;
0338 }
0339 
0340 /*
0341  * write_filehandle - Get a variable-length NFS file handle by path
0342  *
0343  * On input, the buffer contains a '\n'-terminated C string comprised of
0344  * three alphanumeric words separated by whitespace.  The string may
0345  * contain escape sequences.
0346  *
0347  * Input:
0348  *          buf:
0349  *              domain:     client domain name
0350  *              path:       export pathname
0351  *              maxsize:    numeric maximum size of
0352  *                      @buf
0353  *          size:   length of C string in @buf
0354  * Output:
0355  *  On success: passed-in buffer filled with '\n'-terminated C
0356  *          string containing a ASCII hex text version
0357  *          of the NFS file handle;
0358  *          return code is the size in bytes of the string
0359  *  On error:   return code is negative errno value
0360  */
0361 static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
0362 {
0363     char *dname, *path;
0364     int maxsize;
0365     char *mesg = buf;
0366     int len;
0367     struct auth_domain *dom;
0368     struct knfsd_fh fh;
0369 
0370     if (size == 0)
0371         return -EINVAL;
0372 
0373     if (buf[size-1] != '\n')
0374         return -EINVAL;
0375     buf[size-1] = 0;
0376 
0377     dname = mesg;
0378     len = qword_get(&mesg, dname, size);
0379     if (len <= 0)
0380         return -EINVAL;
0381     
0382     path = dname+len+1;
0383     len = qword_get(&mesg, path, size);
0384     if (len <= 0)
0385         return -EINVAL;
0386 
0387     len = get_int(&mesg, &maxsize);
0388     if (len)
0389         return len;
0390 
0391     if (maxsize < NFS_FHSIZE)
0392         return -EINVAL;
0393     maxsize = min(maxsize, NFS3_FHSIZE);
0394 
0395     if (qword_get(&mesg, mesg, size)>0)
0396         return -EINVAL;
0397 
0398     /* we have all the words, they are in buf.. */
0399     dom = unix_domain_find(dname);
0400     if (!dom)
0401         return -ENOMEM;
0402 
0403     len = exp_rootfh(netns(file), dom, path, &fh,  maxsize);
0404     auth_domain_put(dom);
0405     if (len)
0406         return len;
0407 
0408     mesg = buf;
0409     len = SIMPLE_TRANSACTION_LIMIT;
0410     qword_addhex(&mesg, &len, fh.fh_raw, fh.fh_size);
0411     mesg[-1] = '\n';
0412     return mesg - buf;
0413 }
0414 
0415 /*
0416  * write_threads - Start NFSD, or report the current number of running threads
0417  *
0418  * Input:
0419  *          buf:        ignored
0420  *          size:       zero
0421  * Output:
0422  *  On success: passed-in buffer filled with '\n'-terminated C
0423  *          string numeric value representing the number of
0424  *          running NFSD threads;
0425  *          return code is the size in bytes of the string
0426  *  On error:   return code is zero
0427  *
0428  * OR
0429  *
0430  * Input:
0431  *          buf:        C string containing an unsigned
0432  *                  integer value representing the
0433  *                  number of NFSD threads to start
0434  *          size:       non-zero length of C string in @buf
0435  * Output:
0436  *  On success: NFS service is started;
0437  *          passed-in buffer filled with '\n'-terminated C
0438  *          string numeric value representing the number of
0439  *          running NFSD threads;
0440  *          return code is the size in bytes of the string
0441  *  On error:   return code is zero or a negative errno value
0442  */
0443 static ssize_t write_threads(struct file *file, char *buf, size_t size)
0444 {
0445     char *mesg = buf;
0446     int rv;
0447     struct net *net = netns(file);
0448 
0449     if (size > 0) {
0450         int newthreads;
0451         rv = get_int(&mesg, &newthreads);
0452         if (rv)
0453             return rv;
0454         if (newthreads < 0)
0455             return -EINVAL;
0456         rv = nfsd_svc(newthreads, net, file->f_cred);
0457         if (rv < 0)
0458             return rv;
0459     } else
0460         rv = nfsd_nrthreads(net);
0461 
0462     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
0463 }
0464 
0465 /*
0466  * write_pool_threads - Set or report the current number of threads per pool
0467  *
0468  * Input:
0469  *          buf:        ignored
0470  *          size:       zero
0471  *
0472  * OR
0473  *
0474  * Input:
0475  *          buf:        C string containing whitespace-
0476  *                  separated unsigned integer values
0477  *                  representing the number of NFSD
0478  *                  threads to start in each pool
0479  *          size:       non-zero length of C string in @buf
0480  * Output:
0481  *  On success: passed-in buffer filled with '\n'-terminated C
0482  *          string containing integer values representing the
0483  *          number of NFSD threads in each pool;
0484  *          return code is the size in bytes of the string
0485  *  On error:   return code is zero or a negative errno value
0486  */
0487 static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
0488 {
0489     /* if size > 0, look for an array of number of threads per node
0490      * and apply them  then write out number of threads per node as reply
0491      */
0492     char *mesg = buf;
0493     int i;
0494     int rv;
0495     int len;
0496     int npools;
0497     int *nthreads;
0498     struct net *net = netns(file);
0499 
0500     mutex_lock(&nfsd_mutex);
0501     npools = nfsd_nrpools(net);
0502     if (npools == 0) {
0503         /*
0504          * NFS is shut down.  The admin can start it by
0505          * writing to the threads file but NOT the pool_threads
0506          * file, sorry.  Report zero threads.
0507          */
0508         mutex_unlock(&nfsd_mutex);
0509         strcpy(buf, "0\n");
0510         return strlen(buf);
0511     }
0512 
0513     nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
0514     rv = -ENOMEM;
0515     if (nthreads == NULL)
0516         goto out_free;
0517 
0518     if (size > 0) {
0519         for (i = 0; i < npools; i++) {
0520             rv = get_int(&mesg, &nthreads[i]);
0521             if (rv == -ENOENT)
0522                 break;      /* fewer numbers than pools */
0523             if (rv)
0524                 goto out_free;  /* syntax error */
0525             rv = -EINVAL;
0526             if (nthreads[i] < 0)
0527                 goto out_free;
0528         }
0529         rv = nfsd_set_nrthreads(i, nthreads, net);
0530         if (rv)
0531             goto out_free;
0532     }
0533 
0534     rv = nfsd_get_nrthreads(npools, nthreads, net);
0535     if (rv)
0536         goto out_free;
0537 
0538     mesg = buf;
0539     size = SIMPLE_TRANSACTION_LIMIT;
0540     for (i = 0; i < npools && size > 0; i++) {
0541         snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
0542         len = strlen(mesg);
0543         size -= len;
0544         mesg += len;
0545     }
0546     rv = mesg - buf;
0547 out_free:
0548     kfree(nthreads);
0549     mutex_unlock(&nfsd_mutex);
0550     return rv;
0551 }
0552 
0553 static ssize_t
0554 nfsd_print_version_support(struct nfsd_net *nn, char *buf, int remaining,
0555         const char *sep, unsigned vers, int minor)
0556 {
0557     const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u";
0558     bool supported = !!nfsd_vers(nn, vers, NFSD_TEST);
0559 
0560     if (vers == 4 && minor >= 0 &&
0561         !nfsd_minorversion(nn, minor, NFSD_TEST))
0562         supported = false;
0563     if (minor == 0 && supported)
0564         /*
0565          * special case for backward compatability.
0566          * +4.0 is never reported, it is implied by
0567          * +4, unless -4.0 is present.
0568          */
0569         return 0;
0570     return snprintf(buf, remaining, format, sep,
0571             supported ? '+' : '-', vers, minor);
0572 }
0573 
0574 static ssize_t __write_versions(struct file *file, char *buf, size_t size)
0575 {
0576     char *mesg = buf;
0577     char *vers, *minorp, sign;
0578     int len, num, remaining;
0579     ssize_t tlen = 0;
0580     char *sep;
0581     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
0582 
0583     if (size>0) {
0584         if (nn->nfsd_serv)
0585             /* Cannot change versions without updating
0586              * nn->nfsd_serv->sv_xdrsize, and reallocing
0587              * rq_argp and rq_resp
0588              */
0589             return -EBUSY;
0590         if (buf[size-1] != '\n')
0591             return -EINVAL;
0592         buf[size-1] = 0;
0593 
0594         vers = mesg;
0595         len = qword_get(&mesg, vers, size);
0596         if (len <= 0) return -EINVAL;
0597         do {
0598             enum vers_op cmd;
0599             unsigned minor;
0600             sign = *vers;
0601             if (sign == '+' || sign == '-')
0602                 num = simple_strtol((vers+1), &minorp, 0);
0603             else
0604                 num = simple_strtol(vers, &minorp, 0);
0605             if (*minorp == '.') {
0606                 if (num != 4)
0607                     return -EINVAL;
0608                 if (kstrtouint(minorp+1, 0, &minor) < 0)
0609                     return -EINVAL;
0610             }
0611 
0612             cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET;
0613             switch(num) {
0614             case 2:
0615             case 3:
0616                 nfsd_vers(nn, num, cmd);
0617                 break;
0618             case 4:
0619                 if (*minorp == '.') {
0620                     if (nfsd_minorversion(nn, minor, cmd) < 0)
0621                         return -EINVAL;
0622                 } else if ((cmd == NFSD_SET) != nfsd_vers(nn, num, NFSD_TEST)) {
0623                     /*
0624                      * Either we have +4 and no minors are enabled,
0625                      * or we have -4 and at least one minor is enabled.
0626                      * In either case, propagate 'cmd' to all minors.
0627                      */
0628                     minor = 0;
0629                     while (nfsd_minorversion(nn, minor, cmd) >= 0)
0630                         minor++;
0631                 }
0632                 break;
0633             default:
0634                 return -EINVAL;
0635             }
0636             vers += len + 1;
0637         } while ((len = qword_get(&mesg, vers, size)) > 0);
0638         /* If all get turned off, turn them back on, as
0639          * having no versions is BAD
0640          */
0641         nfsd_reset_versions(nn);
0642     }
0643 
0644     /* Now write current state into reply buffer */
0645     sep = "";
0646     remaining = SIMPLE_TRANSACTION_LIMIT;
0647     for (num=2 ; num <= 4 ; num++) {
0648         int minor;
0649         if (!nfsd_vers(nn, num, NFSD_AVAIL))
0650             continue;
0651 
0652         minor = -1;
0653         do {
0654             len = nfsd_print_version_support(nn, buf, remaining,
0655                     sep, num, minor);
0656             if (len >= remaining)
0657                 goto out;
0658             remaining -= len;
0659             buf += len;
0660             tlen += len;
0661             minor++;
0662             if (len)
0663                 sep = " ";
0664         } while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION);
0665     }
0666 out:
0667     len = snprintf(buf, remaining, "\n");
0668     if (len >= remaining)
0669         return -EINVAL;
0670     return tlen + len;
0671 }
0672 
0673 /*
0674  * write_versions - Set or report the available NFS protocol versions
0675  *
0676  * Input:
0677  *          buf:        ignored
0678  *          size:       zero
0679  * Output:
0680  *  On success: passed-in buffer filled with '\n'-terminated C
0681  *          string containing positive or negative integer
0682  *          values representing the current status of each
0683  *          protocol version;
0684  *          return code is the size in bytes of the string
0685  *  On error:   return code is zero or a negative errno value
0686  *
0687  * OR
0688  *
0689  * Input:
0690  *          buf:        C string containing whitespace-
0691  *                  separated positive or negative
0692  *                  integer values representing NFS
0693  *                  protocol versions to enable ("+n")
0694  *                  or disable ("-n")
0695  *          size:       non-zero length of C string in @buf
0696  * Output:
0697  *  On success: status of zero or more protocol versions has
0698  *          been updated; passed-in buffer filled with
0699  *          '\n'-terminated C string containing positive
0700  *          or negative integer values representing the
0701  *          current status of each protocol version;
0702  *          return code is the size in bytes of the string
0703  *  On error:   return code is zero or a negative errno value
0704  */
0705 static ssize_t write_versions(struct file *file, char *buf, size_t size)
0706 {
0707     ssize_t rv;
0708 
0709     mutex_lock(&nfsd_mutex);
0710     rv = __write_versions(file, buf, size);
0711     mutex_unlock(&nfsd_mutex);
0712     return rv;
0713 }
0714 
0715 /*
0716  * Zero-length write.  Return a list of NFSD's current listener
0717  * transports.
0718  */
0719 static ssize_t __write_ports_names(char *buf, struct net *net)
0720 {
0721     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0722 
0723     if (nn->nfsd_serv == NULL)
0724         return 0;
0725     return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
0726 }
0727 
0728 /*
0729  * A single 'fd' number was written, in which case it must be for
0730  * a socket of a supported family/protocol, and we use it as an
0731  * nfsd listener.
0732  */
0733 static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred *cred)
0734 {
0735     char *mesg = buf;
0736     int fd, err;
0737     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0738 
0739     err = get_int(&mesg, &fd);
0740     if (err != 0 || fd < 0)
0741         return -EINVAL;
0742 
0743     if (svc_alien_sock(net, fd)) {
0744         printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
0745         return -EINVAL;
0746     }
0747 
0748     err = nfsd_create_serv(net);
0749     if (err != 0)
0750         return err;
0751 
0752     err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred);
0753 
0754     if (err >= 0 &&
0755         !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
0756         svc_get(nn->nfsd_serv);
0757 
0758     nfsd_put(net);
0759     return err;
0760 }
0761 
0762 /*
0763  * A transport listener is added by writing it's transport name and
0764  * a port number.
0765  */
0766 static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cred *cred)
0767 {
0768     char transport[16];
0769     struct svc_xprt *xprt;
0770     int port, err;
0771     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0772 
0773     if (sscanf(buf, "%15s %5u", transport, &port) != 2)
0774         return -EINVAL;
0775 
0776     if (port < 1 || port > USHRT_MAX)
0777         return -EINVAL;
0778 
0779     err = nfsd_create_serv(net);
0780     if (err != 0)
0781         return err;
0782 
0783     err = svc_xprt_create(nn->nfsd_serv, transport, net,
0784                   PF_INET, port, SVC_SOCK_ANONYMOUS, cred);
0785     if (err < 0)
0786         goto out_err;
0787 
0788     err = svc_xprt_create(nn->nfsd_serv, transport, net,
0789                   PF_INET6, port, SVC_SOCK_ANONYMOUS, cred);
0790     if (err < 0 && err != -EAFNOSUPPORT)
0791         goto out_close;
0792 
0793     if (!nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1))
0794         svc_get(nn->nfsd_serv);
0795 
0796     nfsd_put(net);
0797     return 0;
0798 out_close:
0799     xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
0800     if (xprt != NULL) {
0801         svc_xprt_close(xprt);
0802         svc_xprt_put(xprt);
0803     }
0804 out_err:
0805     nfsd_put(net);
0806     return err;
0807 }
0808 
0809 static ssize_t __write_ports(struct file *file, char *buf, size_t size,
0810                  struct net *net)
0811 {
0812     if (size == 0)
0813         return __write_ports_names(buf, net);
0814 
0815     if (isdigit(buf[0]))
0816         return __write_ports_addfd(buf, net, file->f_cred);
0817 
0818     if (isalpha(buf[0]))
0819         return __write_ports_addxprt(buf, net, file->f_cred);
0820 
0821     return -EINVAL;
0822 }
0823 
0824 /*
0825  * write_ports - Pass a socket file descriptor or transport name to listen on
0826  *
0827  * Input:
0828  *          buf:        ignored
0829  *          size:       zero
0830  * Output:
0831  *  On success: passed-in buffer filled with a '\n'-terminated C
0832  *          string containing a whitespace-separated list of
0833  *          named NFSD listeners;
0834  *          return code is the size in bytes of the string
0835  *  On error:   return code is zero or a negative errno value
0836  *
0837  * OR
0838  *
0839  * Input:
0840  *          buf:        C string containing an unsigned
0841  *                  integer value representing a bound
0842  *                  but unconnected socket that is to be
0843  *                  used as an NFSD listener; listen(3)
0844  *                  must be called for a SOCK_STREAM
0845  *                  socket, otherwise it is ignored
0846  *          size:       non-zero length of C string in @buf
0847  * Output:
0848  *  On success: NFS service is started;
0849  *          passed-in buffer filled with a '\n'-terminated C
0850  *          string containing a unique alphanumeric name of
0851  *          the listener;
0852  *          return code is the size in bytes of the string
0853  *  On error:   return code is a negative errno value
0854  *
0855  * OR
0856  *
0857  * Input:
0858  *          buf:        C string containing a transport
0859  *                  name and an unsigned integer value
0860  *                  representing the port to listen on,
0861  *                  separated by whitespace
0862  *          size:       non-zero length of C string in @buf
0863  * Output:
0864  *  On success: returns zero; NFS service is started
0865  *  On error:   return code is a negative errno value
0866  */
0867 static ssize_t write_ports(struct file *file, char *buf, size_t size)
0868 {
0869     ssize_t rv;
0870 
0871     mutex_lock(&nfsd_mutex);
0872     rv = __write_ports(file, buf, size, netns(file));
0873     mutex_unlock(&nfsd_mutex);
0874     return rv;
0875 }
0876 
0877 
0878 int nfsd_max_blksize;
0879 
0880 /*
0881  * write_maxblksize - Set or report the current NFS blksize
0882  *
0883  * Input:
0884  *          buf:        ignored
0885  *          size:       zero
0886  *
0887  * OR
0888  *
0889  * Input:
0890  *          buf:        C string containing an unsigned
0891  *                  integer value representing the new
0892  *                  NFS blksize
0893  *          size:       non-zero length of C string in @buf
0894  * Output:
0895  *  On success: passed-in buffer filled with '\n'-terminated C string
0896  *          containing numeric value of the current NFS blksize
0897  *          setting;
0898  *          return code is the size in bytes of the string
0899  *  On error:   return code is zero or a negative errno value
0900  */
0901 static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
0902 {
0903     char *mesg = buf;
0904     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
0905 
0906     if (size > 0) {
0907         int bsize;
0908         int rv = get_int(&mesg, &bsize);
0909         if (rv)
0910             return rv;
0911         /* force bsize into allowed range and
0912          * required alignment.
0913          */
0914         bsize = max_t(int, bsize, 1024);
0915         bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE);
0916         bsize &= ~(1024-1);
0917         mutex_lock(&nfsd_mutex);
0918         if (nn->nfsd_serv) {
0919             mutex_unlock(&nfsd_mutex);
0920             return -EBUSY;
0921         }
0922         nfsd_max_blksize = bsize;
0923         mutex_unlock(&nfsd_mutex);
0924     }
0925 
0926     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
0927                             nfsd_max_blksize);
0928 }
0929 
0930 /*
0931  * write_maxconn - Set or report the current max number of connections
0932  *
0933  * Input:
0934  *          buf:        ignored
0935  *          size:       zero
0936  * OR
0937  *
0938  * Input:
0939  *          buf:        C string containing an unsigned
0940  *                  integer value representing the new
0941  *                  number of max connections
0942  *          size:       non-zero length of C string in @buf
0943  * Output:
0944  *  On success: passed-in buffer filled with '\n'-terminated C string
0945  *          containing numeric value of max_connections setting
0946  *          for this net namespace;
0947  *          return code is the size in bytes of the string
0948  *  On error:   return code is zero or a negative errno value
0949  */
0950 static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
0951 {
0952     char *mesg = buf;
0953     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
0954     unsigned int maxconn = nn->max_connections;
0955 
0956     if (size > 0) {
0957         int rv = get_uint(&mesg, &maxconn);
0958 
0959         if (rv)
0960             return rv;
0961         nn->max_connections = maxconn;
0962     }
0963 
0964     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn);
0965 }
0966 
0967 #ifdef CONFIG_NFSD_V4
0968 static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
0969                   time64_t *time, struct nfsd_net *nn)
0970 {
0971     char *mesg = buf;
0972     int rv, i;
0973 
0974     if (size > 0) {
0975         if (nn->nfsd_serv)
0976             return -EBUSY;
0977         rv = get_int(&mesg, &i);
0978         if (rv)
0979             return rv;
0980         /*
0981          * Some sanity checking.  We don't have a reason for
0982          * these particular numbers, but problems with the
0983          * extremes are:
0984          *  - Too short: the briefest network outage may
0985          *    cause clients to lose all their locks.  Also,
0986          *    the frequent polling may be wasteful.
0987          *  - Too long: do you really want reboot recovery
0988          *    to take more than an hour?  Or to make other
0989          *    clients wait an hour before being able to
0990          *    revoke a dead client's locks?
0991          */
0992         if (i < 10 || i > 3600)
0993             return -EINVAL;
0994         *time = i;
0995     }
0996 
0997     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
0998 }
0999 
1000 static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
1001                 time64_t *time, struct nfsd_net *nn)
1002 {
1003     ssize_t rv;
1004 
1005     mutex_lock(&nfsd_mutex);
1006     rv = __nfsd4_write_time(file, buf, size, time, nn);
1007     mutex_unlock(&nfsd_mutex);
1008     return rv;
1009 }
1010 
1011 /*
1012  * write_leasetime - Set or report the current NFSv4 lease time
1013  *
1014  * Input:
1015  *          buf:        ignored
1016  *          size:       zero
1017  *
1018  * OR
1019  *
1020  * Input:
1021  *          buf:        C string containing an unsigned
1022  *                  integer value representing the new
1023  *                  NFSv4 lease expiry time
1024  *          size:       non-zero length of C string in @buf
1025  * Output:
1026  *  On success: passed-in buffer filled with '\n'-terminated C
1027  *          string containing unsigned integer value of the
1028  *          current lease expiry time;
1029  *          return code is the size in bytes of the string
1030  *  On error:   return code is zero or a negative errno value
1031  */
1032 static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
1033 {
1034     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1035     return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
1036 }
1037 
1038 /*
1039  * write_gracetime - Set or report current NFSv4 grace period time
1040  *
1041  * As above, but sets the time of the NFSv4 grace period.
1042  *
1043  * Note this should never be set to less than the *previous*
1044  * lease-period time, but we don't try to enforce this.  (In the common
1045  * case (a new boot), we don't know what the previous lease time was
1046  * anyway.)
1047  */
1048 static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
1049 {
1050     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1051     return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
1052 }
1053 
1054 static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
1055                    struct nfsd_net *nn)
1056 {
1057     char *mesg = buf;
1058     char *recdir;
1059     int len, status;
1060 
1061     if (size > 0) {
1062         if (nn->nfsd_serv)
1063             return -EBUSY;
1064         if (size > PATH_MAX || buf[size-1] != '\n')
1065             return -EINVAL;
1066         buf[size-1] = 0;
1067 
1068         recdir = mesg;
1069         len = qword_get(&mesg, recdir, size);
1070         if (len <= 0)
1071             return -EINVAL;
1072 
1073         status = nfs4_reset_recoverydir(recdir);
1074         if (status)
1075             return status;
1076     }
1077 
1078     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
1079                             nfs4_recoverydir());
1080 }
1081 
1082 /*
1083  * write_recoverydir - Set or report the pathname of the recovery directory
1084  *
1085  * Input:
1086  *          buf:        ignored
1087  *          size:       zero
1088  *
1089  * OR
1090  *
1091  * Input:
1092  *          buf:        C string containing the pathname
1093  *                  of the directory on a local file
1094  *                  system containing permanent NFSv4
1095  *                  recovery data
1096  *          size:       non-zero length of C string in @buf
1097  * Output:
1098  *  On success: passed-in buffer filled with '\n'-terminated C string
1099  *          containing the current recovery pathname setting;
1100  *          return code is the size in bytes of the string
1101  *  On error:   return code is zero or a negative errno value
1102  */
1103 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1104 {
1105     ssize_t rv;
1106     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1107 
1108     mutex_lock(&nfsd_mutex);
1109     rv = __write_recoverydir(file, buf, size, nn);
1110     mutex_unlock(&nfsd_mutex);
1111     return rv;
1112 }
1113 
1114 /*
1115  * write_v4_end_grace - release grace period for nfsd's v4.x lock manager
1116  *
1117  * Input:
1118  *          buf:        ignored
1119  *          size:       zero
1120  * OR
1121  *
1122  * Input:
1123  *          buf:        any value
1124  *          size:       non-zero length of C string in @buf
1125  * Output:
1126  *          passed-in buffer filled with "Y" or "N" with a newline
1127  *          and NULL-terminated C string. This indicates whether
1128  *          the grace period has ended in the current net
1129  *          namespace. Return code is the size in bytes of the
1130  *          string. Writing a string that starts with 'Y', 'y', or
1131  *          '1' to the file will end the grace period for nfsd's v4
1132  *          lock manager.
1133  */
1134 static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
1135 {
1136     struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
1137 
1138     if (size > 0) {
1139         switch(buf[0]) {
1140         case 'Y':
1141         case 'y':
1142         case '1':
1143             if (!nn->nfsd_serv)
1144                 return -EBUSY;
1145             nfsd4_end_grace(nn);
1146             break;
1147         default:
1148             return -EINVAL;
1149         }
1150     }
1151 
1152     return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c\n",
1153              nn->grace_ended ? 'Y' : 'N');
1154 }
1155 
1156 #endif
1157 
1158 /*----------------------------------------------------------------------------*/
1159 /*
1160  *  populating the filesystem.
1161  */
1162 
1163 /* Basically copying rpc_get_inode. */
1164 static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
1165 {
1166     struct inode *inode = new_inode(sb);
1167     if (!inode)
1168         return NULL;
1169     /* Following advice from simple_fill_super documentation: */
1170     inode->i_ino = iunique(sb, NFSD_MaxReserved);
1171     inode->i_mode = mode;
1172     inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
1173     switch (mode & S_IFMT) {
1174     case S_IFDIR:
1175         inode->i_fop = &simple_dir_operations;
1176         inode->i_op = &simple_dir_inode_operations;
1177         inc_nlink(inode);
1178         break;
1179     default:
1180         break;
1181     }
1182     return inode;
1183 }
1184 
1185 static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode, struct nfsdfs_client *ncl)
1186 {
1187     struct inode *inode;
1188 
1189     inode = nfsd_get_inode(dir->i_sb, mode);
1190     if (!inode)
1191         return -ENOMEM;
1192     if (ncl) {
1193         inode->i_private = ncl;
1194         kref_get(&ncl->cl_ref);
1195     }
1196     d_add(dentry, inode);
1197     inc_nlink(dir);
1198     fsnotify_mkdir(dir, dentry);
1199     return 0;
1200 }
1201 
1202 static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name)
1203 {
1204     struct inode *dir = parent->d_inode;
1205     struct dentry *dentry;
1206     int ret = -ENOMEM;
1207 
1208     inode_lock(dir);
1209     dentry = d_alloc_name(parent, name);
1210     if (!dentry)
1211         goto out_err;
1212     ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600, ncl);
1213     if (ret)
1214         goto out_err;
1215 out:
1216     inode_unlock(dir);
1217     return dentry;
1218 out_err:
1219     dput(dentry);
1220     dentry = ERR_PTR(ret);
1221     goto out;
1222 }
1223 
1224 static void clear_ncl(struct inode *inode)
1225 {
1226     struct nfsdfs_client *ncl = inode->i_private;
1227 
1228     inode->i_private = NULL;
1229     kref_put(&ncl->cl_ref, ncl->cl_release);
1230 }
1231 
1232 static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1233 {
1234     struct nfsdfs_client *nc = inode->i_private;
1235 
1236     if (nc)
1237         kref_get(&nc->cl_ref);
1238     return nc;
1239 }
1240 
1241 struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
1242 {
1243     struct nfsdfs_client *nc;
1244 
1245     inode_lock_shared(inode);
1246     nc = __get_nfsdfs_client(inode);
1247     inode_unlock_shared(inode);
1248     return nc;
1249 }
1250 /* from __rpc_unlink */
1251 static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1252 {
1253     int ret;
1254 
1255     clear_ncl(d_inode(dentry));
1256     dget(dentry);
1257     ret = simple_unlink(dir, dentry);
1258     d_drop(dentry);
1259     fsnotify_unlink(dir, dentry);
1260     dput(dentry);
1261     WARN_ON_ONCE(ret);
1262 }
1263 
1264 static void nfsdfs_remove_files(struct dentry *root)
1265 {
1266     struct dentry *dentry, *tmp;
1267 
1268     list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1269         if (!simple_positive(dentry)) {
1270             WARN_ON_ONCE(1); /* I think this can't happen? */
1271             continue;
1272         }
1273         nfsdfs_remove_file(d_inode(root), dentry);
1274     }
1275 }
1276 
1277 /* XXX: cut'n'paste from simple_fill_super; figure out if we could share
1278  * code instead. */
1279 static  int nfsdfs_create_files(struct dentry *root,
1280                 const struct tree_descr *files,
1281                 struct dentry **fdentries)
1282 {
1283     struct inode *dir = d_inode(root);
1284     struct inode *inode;
1285     struct dentry *dentry;
1286     int i;
1287 
1288     inode_lock(dir);
1289     for (i = 0; files->name && files->name[0]; i++, files++) {
1290         dentry = d_alloc_name(root, files->name);
1291         if (!dentry)
1292             goto out;
1293         inode = nfsd_get_inode(d_inode(root)->i_sb,
1294                     S_IFREG | files->mode);
1295         if (!inode) {
1296             dput(dentry);
1297             goto out;
1298         }
1299         inode->i_fop = files->ops;
1300         inode->i_private = __get_nfsdfs_client(dir);
1301         d_add(dentry, inode);
1302         fsnotify_create(dir, dentry);
1303         if (fdentries)
1304             fdentries[i] = dentry;
1305     }
1306     inode_unlock(dir);
1307     return 0;
1308 out:
1309     nfsdfs_remove_files(root);
1310     inode_unlock(dir);
1311     return -ENOMEM;
1312 }
1313 
1314 /* on success, returns positive number unique to that client. */
1315 struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
1316                  struct nfsdfs_client *ncl, u32 id,
1317                  const struct tree_descr *files,
1318                  struct dentry **fdentries)
1319 {
1320     struct dentry *dentry;
1321     char name[11];
1322     int ret;
1323 
1324     sprintf(name, "%u", id);
1325 
1326     dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
1327     if (IS_ERR(dentry)) /* XXX: tossing errors? */
1328         return NULL;
1329     ret = nfsdfs_create_files(dentry, files, fdentries);
1330     if (ret) {
1331         nfsd_client_rmdir(dentry);
1332         return NULL;
1333     }
1334     return dentry;
1335 }
1336 
1337 /* Taken from __rpc_rmdir: */
1338 void nfsd_client_rmdir(struct dentry *dentry)
1339 {
1340     struct inode *dir = d_inode(dentry->d_parent);
1341     struct inode *inode = d_inode(dentry);
1342     int ret;
1343 
1344     inode_lock(dir);
1345     nfsdfs_remove_files(dentry);
1346     clear_ncl(inode);
1347     dget(dentry);
1348     ret = simple_rmdir(dir, dentry);
1349     WARN_ON_ONCE(ret);
1350     d_drop(dentry);
1351     fsnotify_rmdir(dir, dentry);
1352     dput(dentry);
1353     inode_unlock(dir);
1354 }
1355 
1356 static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
1357 {
1358     struct nfsd_net *nn = net_generic(current->nsproxy->net_ns,
1359                             nfsd_net_id);
1360     struct dentry *dentry;
1361     int ret;
1362 
1363     static const struct tree_descr nfsd_files[] = {
1364         [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1365         /* Per-export io stats use same ops as exports file */
1366         [NFSD_Export_Stats] = {"export_stats", &exports_nfsd_operations, S_IRUGO},
1367         [NFSD_Export_features] = {"export_features",
1368                     &export_features_operations, S_IRUGO},
1369         [NFSD_FO_UnlockIP] = {"unlock_ip",
1370                     &transaction_ops, S_IWUSR|S_IRUSR},
1371         [NFSD_FO_UnlockFS] = {"unlock_filesystem",
1372                     &transaction_ops, S_IWUSR|S_IRUSR},
1373         [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
1374         [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
1375         [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
1376         [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
1377         [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
1378         [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
1379         [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
1380         [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
1381         [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
1382         [NFSD_Filecache] = {"filecache", &filecache_ops, S_IRUGO},
1383 #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
1384         [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
1385 #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
1386 #ifdef CONFIG_NFSD_V4
1387         [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
1388         [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
1389         [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
1390         [NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1391 #endif
1392         /* last one */ {""}
1393     };
1394 
1395     ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1396     if (ret)
1397         return ret;
1398     dentry = nfsd_mkdir(sb->s_root, NULL, "clients");
1399     if (IS_ERR(dentry))
1400         return PTR_ERR(dentry);
1401     nn->nfsd_client_dir = dentry;
1402     return 0;
1403 }
1404 
1405 static int nfsd_fs_get_tree(struct fs_context *fc)
1406 {
1407     return get_tree_keyed(fc, nfsd_fill_super, get_net(fc->net_ns));
1408 }
1409 
1410 static void nfsd_fs_free_fc(struct fs_context *fc)
1411 {
1412     if (fc->s_fs_info)
1413         put_net(fc->s_fs_info);
1414 }
1415 
1416 static const struct fs_context_operations nfsd_fs_context_ops = {
1417     .free       = nfsd_fs_free_fc,
1418     .get_tree   = nfsd_fs_get_tree,
1419 };
1420 
1421 static int nfsd_init_fs_context(struct fs_context *fc)
1422 {
1423     put_user_ns(fc->user_ns);
1424     fc->user_ns = get_user_ns(fc->net_ns->user_ns);
1425     fc->ops = &nfsd_fs_context_ops;
1426     return 0;
1427 }
1428 
1429 static void nfsd_umount(struct super_block *sb)
1430 {
1431     struct net *net = sb->s_fs_info;
1432 
1433     nfsd_shutdown_threads(net);
1434 
1435     kill_litter_super(sb);
1436     put_net(net);
1437 }
1438 
1439 static struct file_system_type nfsd_fs_type = {
1440     .owner      = THIS_MODULE,
1441     .name       = "nfsd",
1442     .init_fs_context = nfsd_init_fs_context,
1443     .kill_sb    = nfsd_umount,
1444 };
1445 MODULE_ALIAS_FS("nfsd");
1446 
1447 #ifdef CONFIG_PROC_FS
1448 static int create_proc_exports_entry(void)
1449 {
1450     struct proc_dir_entry *entry;
1451 
1452     entry = proc_mkdir("fs/nfs", NULL);
1453     if (!entry)
1454         return -ENOMEM;
1455     entry = proc_create("exports", 0, entry, &exports_proc_ops);
1456     if (!entry) {
1457         remove_proc_entry("fs/nfs", NULL);
1458         return -ENOMEM;
1459     }
1460     return 0;
1461 }
1462 #else /* CONFIG_PROC_FS */
1463 static int create_proc_exports_entry(void)
1464 {
1465     return 0;
1466 }
1467 #endif
1468 
1469 unsigned int nfsd_net_id;
1470 
1471 static __net_init int nfsd_init_net(struct net *net)
1472 {
1473     int retval;
1474     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1475 
1476     retval = nfsd_export_init(net);
1477     if (retval)
1478         goto out_export_error;
1479     retval = nfsd_idmap_init(net);
1480     if (retval)
1481         goto out_idmap_error;
1482     nn->nfsd_versions = NULL;
1483     nn->nfsd4_minorversions = NULL;
1484     retval = nfsd_reply_cache_init(nn);
1485     if (retval)
1486         goto out_drc_error;
1487     nfsd4_init_leases_net(nn);
1488 
1489     get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key));
1490     seqlock_init(&nn->writeverf_lock);
1491 
1492     return 0;
1493 
1494 out_drc_error:
1495     nfsd_idmap_shutdown(net);
1496 out_idmap_error:
1497     nfsd_export_shutdown(net);
1498 out_export_error:
1499     return retval;
1500 }
1501 
1502 static __net_exit void nfsd_exit_net(struct net *net)
1503 {
1504     struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1505 
1506     nfsd_reply_cache_shutdown(nn);
1507     nfsd_idmap_shutdown(net);
1508     nfsd_export_shutdown(net);
1509     nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
1510 }
1511 
1512 static struct pernet_operations nfsd_net_ops = {
1513     .init = nfsd_init_net,
1514     .exit = nfsd_exit_net,
1515     .id   = &nfsd_net_id,
1516     .size = sizeof(struct nfsd_net),
1517 };
1518 
1519 static int __init init_nfsd(void)
1520 {
1521     int retval;
1522 
1523     retval = nfsd4_init_slabs();
1524     if (retval)
1525         return retval;
1526     retval = nfsd4_init_pnfs();
1527     if (retval)
1528         goto out_free_slabs;
1529     retval = nfsd_stat_init();  /* Statistics */
1530     if (retval)
1531         goto out_free_pnfs;
1532     retval = nfsd_drc_slab_create();
1533     if (retval)
1534         goto out_free_stat;
1535     nfsd_lockd_init();  /* lockd->nfsd callbacks */
1536     retval = create_proc_exports_entry();
1537     if (retval)
1538         goto out_free_lockd;
1539     retval = register_pernet_subsys(&nfsd_net_ops);
1540     if (retval < 0)
1541         goto out_free_exports;
1542     retval = register_cld_notifier();
1543     if (retval)
1544         goto out_free_subsys;
1545     retval = nfsd4_create_laundry_wq();
1546     if (retval)
1547         goto out_free_cld;
1548     retval = register_filesystem(&nfsd_fs_type);
1549     if (retval)
1550         goto out_free_all;
1551     return 0;
1552 out_free_all:
1553     nfsd4_destroy_laundry_wq();
1554 out_free_cld:
1555     unregister_cld_notifier();
1556 out_free_subsys:
1557     unregister_pernet_subsys(&nfsd_net_ops);
1558 out_free_exports:
1559     remove_proc_entry("fs/nfs/exports", NULL);
1560     remove_proc_entry("fs/nfs", NULL);
1561 out_free_lockd:
1562     nfsd_lockd_shutdown();
1563     nfsd_drc_slab_free();
1564 out_free_stat:
1565     nfsd_stat_shutdown();
1566 out_free_pnfs:
1567     nfsd4_exit_pnfs();
1568 out_free_slabs:
1569     nfsd4_free_slabs();
1570     return retval;
1571 }
1572 
1573 static void __exit exit_nfsd(void)
1574 {
1575     unregister_filesystem(&nfsd_fs_type);
1576     nfsd4_destroy_laundry_wq();
1577     unregister_cld_notifier();
1578     unregister_pernet_subsys(&nfsd_net_ops);
1579     nfsd_drc_slab_free();
1580     remove_proc_entry("fs/nfs/exports", NULL);
1581     remove_proc_entry("fs/nfs", NULL);
1582     nfsd_stat_shutdown();
1583     nfsd_lockd_shutdown();
1584     nfsd4_free_slabs();
1585     nfsd4_exit_pnfs();
1586 }
1587 
1588 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
1589 MODULE_LICENSE("GPL");
1590 module_init(init_nfsd)
1591 module_exit(exit_nfsd)