patch-2.2.18 linux/fs/nfsd/nfssvc.c
Next file: linux/fs/nfsd/nfsxdr.c
Previous file: linux/fs/nfsd/nfsproc.c
Back to the patch index
Back to the overall index
- Lines: 209
- Date:
Thu Nov 9 12:39:16 2000
- Orig file:
v2.2.17/fs/nfsd/nfssvc.c
- Orig date:
Fri Apr 21 12:46:44 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c
@@ -42,7 +42,7 @@
extern struct svc_program nfsd_program;
static void nfsd(struct svc_rqst *rqstp);
struct timeval nfssvc_boot = { 0, 0 };
-static int nfsd_active = 0;
+static atomic_t nfsd_active = ATOMIC_INIT(0);
/*
* Maximum number of nfsd processes
@@ -55,24 +55,19 @@
struct svc_serv * serv;
int error;
- dprintk("nfsd: creating service\n");
error = -EINVAL;
+ if (atomic_read(&nfsd_active))
+ goto out; /* already running */
if (nrservs <= 0)
goto out;
if (nrservs > NFSD_MAXSERVS)
nrservs = NFSD_MAXSERVS;
+
+ dprintk("nfsd: creating service (%d)\n", nrservs);
nfsd_nservers = nrservs;
+ nfssvc_boot = xtime;
error = -ENOMEM;
- nfsd_fh_init(); /* NFS dentry cache */
- if (nfsd_nservers == 0)
- goto out;
-
- error = -ENOMEM;
- nfsd_racache_init(); /* Readahead param cache */
- if (nfsd_nservers == 0)
- goto out;
-
serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE);
if (serv == NULL)
goto out;
@@ -81,12 +76,14 @@
if (error < 0)
goto failure;
-#if 0 /* Don't even pretend that TCP works. It doesn't. */
+#ifdef CONFIG_NFSD_TCP
error = svc_makesock(serv, IPPROTO_TCP, port);
if (error < 0)
goto failure;
#endif
+ nfsd_racache_init(); /* Readahead param cache */
+
while (nrservs--) {
error = svc_create_thread(nfsd, serv);
if (error < 0)
@@ -106,27 +103,27 @@
nfsd(struct svc_rqst *rqstp)
{
struct svc_serv *serv = rqstp->rq_server;
- int oldumask, err, first = 0;
+ int err;
- /* Lock module and set up kernel thread */
+ /* Lock module */
MOD_INC_USE_COUNT;
+
+ /* Set up kernel thread */
lock_kernel();
exit_mm(current);
+ sprintf(current->comm, "nfsd");
current->session = 1;
current->pgrp = 1;
+ current->fs->umask = 0;
+
+ /* Count active threads */
+ atomic_inc(&nfsd_active);
+
+ /* Start lockd */
+ lockd_up();
+
/* Let svc_process check client's authentication. */
rqstp->rq_auth = 1;
- sprintf(current->comm, "nfsd");
-
- oldumask = current->fs->umask; /* Set umask to 0. */
- current->fs->umask = 0;
- if (!nfsd_active++) {
- nfssvc_boot = xtime; /* record boot time */
- first = 1;
- }
-#if 0
- lockd_up(); /* start lockd */
-#endif
/*
* The main request loop
@@ -143,15 +140,12 @@
* recvfrom routine.
*/
while ((err = svc_recv(serv, rqstp,
- first?5*HZ:MAX_SCHEDULE_TIMEOUT)) == -EAGAIN) {
- if (first && 1) {
- exp_readlock();
- expire_all();
- exp_unlock();
- }
- }
- if (err < 0)
- break;
+ MAX_SCHEDULE_TIMEOUT)) == -EAGAIN)
+ ;
+
+ if (err < 0)
+ break;
+
/* Lock the export hash tables for reading. */
exp_readlock();
@@ -184,23 +178,17 @@
printk(KERN_WARNING "nfsd: terminating on signal %d\n", signo);
}
-#if 0
+ /* Count active threads */
+ if (atomic_dec_and_test(&nfsd_active)) {
+ nfsd_export_shutdown(); /* revoke all exports */
+ nfsd_racache_shutdown(); /* release read-ahead cache */
+ }
+
/* Release lockd */
lockd_down();
-#endif
- if (!--nfsd_active) {
- printk("nfsd: last server exiting\n");
- /* revoke all exports */
- nfsd_export_shutdown();
- /* release fhcache */
- nfsd_fh_shutdown ();
- /* release read-ahead cache */
- nfsd_racache_shutdown();
- }
- /* Destroy the thread */
+ /* Destroy the thread's resources */
svc_exit_thread(rqstp);
- current->fs->umask = oldumask;
/* Release module */
MOD_DEC_USE_COUNT;
@@ -213,7 +201,8 @@
kxdrproc_t xdr;
u32 nfserr;
- dprintk("nfsd_dispatch: proc %d\n", rqstp->rq_proc);
+ dprintk("nfsd_dispatch: vers %d proc %d\n",
+ rqstp->rq_vers, rqstp->rq_proc);
proc = rqstp->rq_procinfo;
/* Check whether we have this call in the cache. */
@@ -242,8 +231,20 @@
svc_putlong(&rqstp->rq_resbuf, nfserr);
/* Encode result.
- * FIXME: Most NFSv3 calls return wcc data even when the call failed
+ * For NFSv2, additional info is never returned in case of an error.
*/
+#ifdef CONFIG_NFSD_V3
+ if (!(nfserr && rqstp->rq_vers == 2)) {
+ xdr = proc->pc_encode;
+ if (xdr && !xdr(rqstp, rqstp->rq_resbuf.buf, rqstp->rq_resp)) {
+ /* Failed to encode result. Release cache entry */
+ dprintk("nfsd: failed to encode result!\n");
+ nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
+ *statp = rpc_system_err;
+ return 1;
+ }
+ }
+#else
xdr = proc->pc_encode;
if (!nfserr && xdr
&& !xdr(rqstp, rqstp->rq_resbuf.buf, rqstp->rq_resp)) {
@@ -253,6 +254,7 @@
*statp = rpc_system_err;
return 1;
}
+#endif /* CONFIG_NFSD_V3 */
/* Store reply in cache. */
nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1);
@@ -262,16 +264,16 @@
static struct svc_version nfsd_version2 = {
2, 18, nfsd_procedures2, nfsd_dispatch
};
-#ifdef CONFIG_NFSD_NFS3
+#ifdef CONFIG_NFSD_V3
static struct svc_version nfsd_version3 = {
- 3, 23, nfsd_procedures3, nfsd_dispatch
+ 3, 22, nfsd_procedures3, nfsd_dispatch
};
#endif
static struct svc_version * nfsd_version[] = {
NULL,
NULL,
&nfsd_version2,
-#ifdef CONFIG_NFSD_NFS3
+#ifdef CONFIG_NFSD_V3
&nfsd_version3,
#endif
};
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)