#include <linux/freezer.h>
#include <linux/fs_struct.h>
#include <linux/kthread.h>
+#include <linux/swap.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/stats.h>
};
+u32 nfsd_supported_minorversion;
+
int nfsd_vers(int vers, enum vers_op change)
{
if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
}
return 0;
}
+
+int nfsd_minorversion(u32 minorversion, enum vers_op change)
+{
+ if (minorversion > NFSD_SUPPORTED_MINOR_VERSION)
+ return -1;
+ switch(change) {
+ case NFSD_SET:
+ nfsd_supported_minorversion = minorversion;
+ break;
+ case NFSD_CLEAR:
+ if (minorversion == 0)
+ return -1;
+ nfsd_supported_minorversion = minorversion - 1;
+ break;
+ case NFSD_TEST:
+ return minorversion <= nfsd_supported_minorversion;
+ case NFSD_AVAIL:
+ return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
+ }
+ return 0;
+}
+
/*
* Maximum number of nfsd processes
*/
}
}
+/*
+ * Each session guarantees a negotiated per slot memory cache for replies
+ * which in turn consumes memory beyond the v2/v3/v4.0 server. A dedicated
+ * NFSv4.1 server might want to use more memory for a DRC than a machine
+ * with mutiple services.
+ *
+ * Impose a hard limit on the number of pages for the DRC which varies
+ * according to the machines free pages. This is of course only a default.
+ *
+ * For now this is a #defined shift which could be under admin control
+ * in the future.
+ */
+static void set_max_drc(void)
+{
+ /* The percent of nr_free_buffer_pages used by the V4.1 server DRC */
+ #define NFSD_DRC_SIZE_SHIFT 7
+ nfsd_serv->sv_drc_max_pages = nr_free_buffer_pages()
+ >> NFSD_DRC_SIZE_SHIFT;
+ nfsd_serv->sv_drc_pages_used = 0;
+ dprintk("%s svc_drc_max_pages %u\n", __func__,
+ nfsd_serv->sv_drc_max_pages);
+}
int nfsd_create_serv(void)
{
}
nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
- AF_INET,
nfsd_last_thread, nfsd, THIS_MODULE);
if (nfsd_serv == NULL)
err = -ENOMEM;
+ else
+ set_max_drc();
do_gettimeofday(&nfssvc_boot); /* record boot time */
return err;
if (!list_empty(&nfsd_serv->sv_permsocks))
return 0;
- error = svc_create_xprt(nfsd_serv, "udp", port,
+ error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;
if (error < 0)
return error;
- error = svc_create_xprt(nfsd_serv, "tcp", port,
+ error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;
nfsd(void *vrqstp)
{
struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp;
- struct fs_struct *fsp;
int err, preverr = 0;
/* Lock module and set up kernel thread */
/* At this point, the thread shares current->fs
* with the init process. We need to create files with a
* umask of 0 instead of init's umask. */
- fsp = copy_fs_struct(current->fs);
- if (!fsp) {
+ if (unshare_fs_struct() < 0) {
printk("Unable to start nfsd thread: out of memory\n");
goto out;
}
- exit_fs(current);
- current->fs = fsp;
+
current->fs->umask = 0;
/*