2 * linux/fs/nfsd/nfssvc.c
4 * Central processing for nfsd.
6 * Authors: Olaf Kirch (okir@monad.swb.de)
8 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
11 #define __NO_VERSION__
12 #include <linux/config.h>
13 #include <linux/module.h>
15 #include <linux/sched.h>
16 #include <linux/errno.h>
17 #include <linux/nfs.h>
19 #include <linux/uio.h>
20 #include <linux/version.h>
21 #include <linux/unistd.h>
22 #include <linux/malloc.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
26 #include <linux/sunrpc/types.h>
27 #include <linux/sunrpc/stats.h>
28 #include <linux/sunrpc/svc.h>
29 #include <linux/sunrpc/svcsock.h>
30 #include <linux/nfsd/nfsd.h>
31 #include <linux/nfsd/stats.h>
32 #include <linux/nfsd/cache.h>
33 #include <linux/nfsd/xdr.h>
34 #include <linux/lockd/bind.h>
36 #define NFSDDBG_FACILITY NFSDDBG_SVC
37 #define NFSD_BUFSIZE (1024 + NFSSVC_MAXBLKSIZE)
39 #define ALLOWED_SIGS (sigmask(SIGKILL))
40 #define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
42 extern struct svc_program nfsd_program
;
43 static void nfsd(struct svc_rqst
*rqstp
);
44 struct timeval nfssvc_boot
= { 0, 0 };
45 static int nfsd_active
= 0;
48 * Maximum number of nfsd processes
50 #define NFSD_MAXSERVS 128
53 nfsd_svc(unsigned short port
, int nrservs
)
55 struct svc_serv
* serv
;
58 dprintk("nfsd: creating service\n");
62 if (nrservs
> NFSD_MAXSERVS
)
63 nrservs
= NFSD_MAXSERVS
;
64 nfsd_nservers
= nrservs
;
67 nfsd_racache_init(); /* Readahead param cache */
68 if (nfsd_nservers
== 0)
71 serv
= svc_create(&nfsd_program
, NFSD_BUFSIZE
, NFSSVC_XDRSIZE
);
75 error
= svc_makesock(serv
, IPPROTO_UDP
, port
);
79 #if 0 /* Don't even pretend that TCP works. It doesn't. */
80 error
= svc_makesock(serv
, IPPROTO_TCP
, port
);
86 error
= svc_create_thread(nfsd
, serv
);
92 svc_destroy(serv
); /* Release server */
98 * This is the NFS server kernel thread
101 nfsd(struct svc_rqst
*rqstp
)
103 struct svc_serv
*serv
= rqstp
->rq_server
;
104 int oldumask
, err
, first
= 0;
106 /* Lock module and set up kernel thread */
110 current
->session
= 1;
112 /* Let svc_process check client's authentication. */
114 sprintf(current
->comm
, "nfsd");
116 oldumask
= current
->fs
->umask
; /* Set umask to 0. */
117 current
->fs
->umask
= 0;
118 if (!nfsd_active
++) {
119 nfssvc_boot
= xtime
; /* record boot time */
122 lockd_up(); /* start lockd */
125 * The main request loop
128 /* Block all but the shutdown signals */
129 spin_lock_irq(¤t
->sigmask_lock
);
130 siginitsetinv(¤t
->blocked
, SHUTDOWN_SIGS
);
131 recalc_sigpending(current
);
132 spin_unlock_irq(¤t
->sigmask_lock
);
135 * Find a socket with data available and call its
138 while ((err
= svc_recv(serv
, rqstp
,
139 first
?5*HZ
:MAX_SCHEDULE_TIMEOUT
)) == -EAGAIN
) {
149 /* Lock the export hash tables for reading. */
152 /* Validate the client's address. This will also defeat
153 * port probes on port 2049 by unauthorized clients.
155 rqstp
->rq_client
= exp_getclient(&rqstp
->rq_addr
);
156 /* Process request with signals blocked. */
157 spin_lock_irq(¤t
->sigmask_lock
);
158 siginitsetinv(¤t
->blocked
, ALLOWED_SIGS
);
159 recalc_sigpending(current
);
160 spin_unlock_irq(¤t
->sigmask_lock
);
162 svc_process(serv
, rqstp
);
164 /* Unlock export hash tables */
169 printk(KERN_WARNING
"nfsd: terminating on error %d\n", -err
);
173 for (signo
= 1; signo
<= _NSIG
; signo
++)
174 if (sigismember(¤t
->signal
, signo
) &&
175 !sigismember(¤t
->blocked
, signo
))
177 printk(KERN_WARNING
"nfsd: terminating on signal %d\n", signo
);
182 if (!--nfsd_active
) {
183 printk("nfsd: last server exiting\n");
184 /* revoke all exports */
185 nfsd_export_shutdown();
186 /* release read-ahead cache */
187 nfsd_racache_shutdown();
190 /* Destroy the thread */
191 svc_exit_thread(rqstp
);
192 current
->fs
->umask
= oldumask
;
199 nfsd_dispatch(struct svc_rqst
*rqstp
, u32
*statp
)
201 struct svc_procedure
*proc
;
205 dprintk("nfsd_dispatch: proc %d\n", rqstp
->rq_proc
);
206 proc
= rqstp
->rq_procinfo
;
208 /* Check whether we have this call in the cache. */
209 switch (nfsd_cache_lookup(rqstp
, proc
->pc_cachetype
)) {
219 /* Decode arguments */
220 xdr
= proc
->pc_decode
;
221 if (xdr
&& !xdr(rqstp
, rqstp
->rq_argbuf
.buf
, rqstp
->rq_argp
)) {
222 dprintk("nfsd: failed to decode arguments!\n");
223 nfsd_cache_update(rqstp
, RC_NOCACHE
, NULL
);
224 *statp
= rpc_garbage_args
;
228 /* Now call the procedure handler, and encode NFS status. */
229 nfserr
= proc
->pc_func(rqstp
, rqstp
->rq_argp
, rqstp
->rq_resp
);
230 if (rqstp
->rq_proc
!= 0)
231 svc_putlong(&rqstp
->rq_resbuf
, nfserr
);
234 * FIXME: Most NFSv3 calls return wcc data even when the call failed
236 xdr
= proc
->pc_encode
;
238 && !xdr(rqstp
, rqstp
->rq_resbuf
.buf
, rqstp
->rq_resp
)) {
239 /* Failed to encode result. Release cache entry */
240 dprintk("nfsd: failed to encode result!\n");
241 nfsd_cache_update(rqstp
, RC_NOCACHE
, NULL
);
242 *statp
= rpc_system_err
;
246 /* Store reply in cache. */
247 nfsd_cache_update(rqstp
, proc
->pc_cachetype
, statp
+ 1);
251 static struct svc_version nfsd_version2
= {
252 2, 18, nfsd_procedures2
, nfsd_dispatch
254 #ifdef CONFIG_NFSD_NFS3
255 static struct svc_version nfsd_version3
= {
256 3, 23, nfsd_procedures3
, nfsd_dispatch
259 static struct svc_version
* nfsd_version
[] = {
263 #ifdef CONFIG_NFSD_NFS3
268 #define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
269 struct svc_program nfsd_program
= {
270 NFS_PROGRAM
, /* program number */
271 2, NFSD_NRVERS
-1, /* version range */
272 NFSD_NRVERS
, /* nr of entries in nfsd_version */
273 nfsd_version
, /* version table */
274 "nfsd", /* program name */
275 &nfsd_svcstats
, /* version table */