Blame view

fs/lockd/svc.c 13.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * linux/fs/lockd/svc.c
   *
   * This is the central lockd service.
   *
   * FIXME: Separate the lockd NFS server functionality from the lockd NFS
   * 	  client functionality. Oh why didn't Sun create two separate
   *	  services in the first place?
   *
   * Authors:	Olaf Kirch (okir@monad.swb.de)
   *
   * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
19
20
21
22
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/sysctl.h>
  #include <linux/moduleparam.h>
  
  #include <linux/sched.h>
  #include <linux/errno.h>
  #include <linux/in.h>
  #include <linux/uio.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  #include <linux/smp.h>
353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
24
  #include <linux/mutex.h>
d751a7cd0   Jeff Layton   NLM: Convert lock...
25
  #include <linux/kthread.h>
831441862   Rafael J. Wysocki   Freezer: make ker...
26
  #include <linux/freezer.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
  
  #include <linux/sunrpc/types.h>
  #include <linux/sunrpc/stats.h>
  #include <linux/sunrpc/clnt.h>
  #include <linux/sunrpc/svc.h>
  #include <linux/sunrpc/svcsock.h>
24e36663c   NeilBrown   [PATCH] knfsd: be...
33
  #include <net/ip.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
39
40
41
42
43
  #include <linux/lockd/lockd.h>
  #include <linux/nfs.h>
  
  #define NLMDBG_FACILITY		NLMDBG_SVC
  #define LOCKD_BUFSIZE		(1024 + NLMSVC_XDRSIZE)
  #define ALLOWED_SIGS		(sigmask(SIGKILL))
  
  static struct svc_program	nlmsvc_program;
  
  struct nlmsvc_binding *		nlmsvc_ops;
2de59872a   Trond Myklebust   LOCKD: Make lockd...
44
  EXPORT_SYMBOL_GPL(nlmsvc_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
46
  static DEFINE_MUTEX(nlmsvc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
  static unsigned int		nlmsvc_users;
d751a7cd0   Jeff Layton   NLM: Convert lock...
48
  static struct task_struct	*nlmsvc_task;
abd1ec4ef   Jeff Layton   lockd: close pote...
49
  static struct svc_rqst		*nlmsvc_rqst;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  unsigned long			nlmsvc_timeout;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
56
57
  /*
   * These can be set at insmod time (useful for NFS as root filesystem),
   * and also changed through the sysctl interface.  -- Jamie Lokier, Aug 2003
   */
  static unsigned long		nlm_grace_period;
  static unsigned long		nlm_timeout = LOCKD_DFLT_TIMEO;
  static int			nlm_udpport, nlm_tcpport;
c72a476b4   Jeff Layton   lockd: set svc_se...
58
59
  /* RLIM_NOFILE defaults to 1024. That seems like a reasonable default here. */
  static unsigned int		nlm_max_connections = 1024;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
61
62
63
64
65
66
67
  /*
   * Constants needed for the sysctl interface.
   */
  static const unsigned long	nlm_grace_period_min = 0;
  static const unsigned long	nlm_grace_period_max = 240;
  static const unsigned long	nlm_timeout_min = 3;
  static const unsigned long	nlm_timeout_max = 20;
  static const int		nlm_port_min = 0, nlm_port_max = 65535;
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
68
  #ifdef CONFIG_SYSCTL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  static struct ctl_table_header * nlm_sysctl_table;
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
70
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

9a8db97e7   Marc Eshel   knfsd: lockd: nfs...
72
  static unsigned long get_lockd_grace_period(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
  	/* Note: nlm_timeout should always be nonzero */
  	if (nlm_grace_period)
9a8db97e7   Marc Eshel   knfsd: lockd: nfs...
76
  		return roundup(nlm_grace_period, nlm_timeout) * HZ;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  	else
9a8db97e7   Marc Eshel   knfsd: lockd: nfs...
78
79
  		return nlm_timeout * 5 * HZ;
  }
af558e33b   J. Bruce Fields   nfsd: common grac...
80
81
  static struct lock_manager lockd_manager = {
  };
9a8db97e7   Marc Eshel   knfsd: lockd: nfs...
82

c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
83
  static void grace_ender(struct work_struct *not_used)
9a8db97e7   Marc Eshel   knfsd: lockd: nfs...
84
  {
af558e33b   J. Bruce Fields   nfsd: common grac...
85
  	locks_end_grace(&lockd_manager);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  }
c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
87
88
89
  static DECLARE_DELAYED_WORK(grace_period_end, grace_ender);
  
  static void set_grace_period(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  {
af558e33b   J. Bruce Fields   nfsd: common grac...
91
  	unsigned long grace_period = get_lockd_grace_period();
c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
92

af558e33b   J. Bruce Fields   nfsd: common grac...
93
  	locks_start_grace(&lockd_manager);
c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
94
95
  	cancel_delayed_work_sync(&grace_period_end);
  	schedule_delayed_work(&grace_period_end, grace_period);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  }
89996df4b   J. Bruce Fields   lockd: fix list c...
97
98
99
100
101
102
103
104
105
  static void restart_grace(void)
  {
  	if (nlmsvc_ops) {
  		cancel_delayed_work_sync(&grace_period_end);
  		locks_end_grace(&lockd_manager);
  		nlmsvc_invalidate_all();
  		set_grace_period();
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
  /*
   * This is the lockd kernel thread
   */
d751a7cd0   Jeff Layton   NLM: Convert lock...
109
110
  static int
  lockd(void *vrqstp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  {
f97c650dd   Jeff Layton   NLM: don't let lo...
112
  	int		err = 0, preverr = 0;
d751a7cd0   Jeff Layton   NLM: Convert lock...
113
  	struct svc_rqst *rqstp = vrqstp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114

d751a7cd0   Jeff Layton   NLM: Convert lock...
115
  	/* try_to_freeze() is called from svc_recv() */
831441862   Rafael J. Wysocki   Freezer: make ker...
116
  	set_freezable();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117

d751a7cd0   Jeff Layton   NLM: Convert lock...
118
  	/* Allow SIGKILL to tell lockd to drop all of its locks */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
  	allow_signal(SIGKILL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
  	dprintk("NFS locking service started (ver " LOCKD_VERSION ").
  ");
  
  	if (!nlm_timeout)
  		nlm_timeout = LOCKD_DFLT_TIMEO;
  	nlmsvc_timeout = nlm_timeout * HZ;
c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
126
  	set_grace_period();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
  
  	/*
  	 * The main request loop. We don't terminate until the last
d751a7cd0   Jeff Layton   NLM: Convert lock...
130
  	 * NFS mount or NFS daemon has gone away.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  	 */
d751a7cd0   Jeff Layton   NLM: Convert lock...
132
  	while (!kthread_should_stop()) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  		long timeout = MAX_SCHEDULE_TIMEOUT;
5216a8e70   Pavel Emelyanov   Wrap buffers used...
134
  		RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135

c72a476b4   Jeff Layton   lockd: set svc_se...
136
137
  		/* update sv_maxconn if it has changed */
  		rqstp->rq_server->sv_maxconn = nlm_max_connections;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  		if (signalled()) {
  			flush_signals(current);
89996df4b   J. Bruce Fields   lockd: fix list c...
140
  			restart_grace();
d751a7cd0   Jeff Layton   NLM: Convert lock...
141
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  		}
8fafa9008   J. Bruce Fields   locks: allow lock...
143
  		timeout = nlmsvc_retry_blocked();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
146
147
  		/*
  		 * Find a socket with data available and call its
  		 * recvfrom routine.
  		 */
6fb2b47fa   NeilBrown   [PATCH] knfsd: Dr...
148
  		err = svc_recv(rqstp, timeout);
f97c650dd   Jeff Layton   NLM: don't let lo...
149
150
  		if (err == -EAGAIN || err == -EINTR) {
  			preverr = err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  			continue;
f97c650dd   Jeff Layton   NLM: don't let lo...
152
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  		if (err < 0) {
f97c650dd   Jeff Layton   NLM: don't let lo...
154
155
156
157
158
159
160
161
  			if (err != preverr) {
  				printk(KERN_WARNING "%s: unexpected error "
  					"from svc_recv (%d)
  ", __func__, err);
  				preverr = err;
  			}
  			schedule_timeout_interruptible(HZ);
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
  		}
f97c650dd   Jeff Layton   NLM: don't let lo...
163
  		preverr = err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164

ad06e4bd6   Chuck Lever   [PATCH] knfsd: SU...
165
166
167
  		dprintk("lockd: request from %s
  ",
  				svc_print_addr(rqstp, buf, sizeof(buf)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168

6fb2b47fa   NeilBrown   [PATCH] knfsd: Dr...
169
  		svc_process(rqstp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  	}
2bd615797   Trond Myklebust   SUNRPC: Ensure th...
171
  	flush_signals(current);
c8ab5f2a1   J. Bruce Fields   lockd: don't depe...
172
  	cancel_delayed_work_sync(&grace_period_end);
2c5e76158   J. Bruce Fields   nfsd: clean up gr...
173
  	locks_end_grace(&lockd_manager);
d751a7cd0   Jeff Layton   NLM: Convert lock...
174
175
176
  	if (nlmsvc_ops)
  		nlmsvc_invalidate_all();
  	nlm_shutdown_hosts();
d751a7cd0   Jeff Layton   NLM: Convert lock...
177
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
  }
eb16e9077   Chuck Lever   lockd: Start PF_I...
179
180
  static int create_lockd_listener(struct svc_serv *serv, const char *name,
  				 const int family, const unsigned short port)
d3fe5ea7c   Chuck Lever   NLM: Refactor mak...
181
182
  {
  	struct svc_xprt *xprt;
eb16e9077   Chuck Lever   lockd: Start PF_I...
183
  	xprt = svc_find_xprt(serv, name, family, 0);
d3fe5ea7c   Chuck Lever   NLM: Refactor mak...
184
  	if (xprt == NULL)
fc5d00b04   Pavel Emelyanov   sunrpc: Add net a...
185
  		return svc_create_xprt(serv, name, &init_net, family, port,
eb16e9077   Chuck Lever   lockd: Start PF_I...
186
  						SVC_SOCK_DEFAULTS);
d3fe5ea7c   Chuck Lever   NLM: Refactor mak...
187
188
189
  	svc_xprt_put(xprt);
  	return 0;
  }
eb16e9077   Chuck Lever   lockd: Start PF_I...
190
191
192
193
194
195
196
197
198
199
  static int create_lockd_family(struct svc_serv *serv, const int family)
  {
  	int err;
  
  	err = create_lockd_listener(serv, "udp", family, nlm_udpport);
  	if (err < 0)
  		return err;
  
  	return create_lockd_listener(serv, "tcp", family, nlm_tcpport);
  }
482fb94e1   Chuck Lever   [PATCH] knfsd: SU...
200
  /*
8c3916f4b   Chuck Lever   NLM: Always start...
201
202
203
204
205
206
207
208
   * Ensure there are active UDP and TCP listeners for lockd.
   *
   * Even if we have only TCP NFS mounts and/or TCP NFSDs, some
   * local services (such as rpc.statd) still require UDP, and
   * some NFS servers do not yet support NLM over TCP.
   *
   * Returns zero if all listeners are available; otherwise a
   * negative errno value is returned.
482fb94e1   Chuck Lever   [PATCH] knfsd: SU...
209
   */
8c3916f4b   Chuck Lever   NLM: Always start...
210
  static int make_socks(struct svc_serv *serv)
24e36663c   NeilBrown   [PATCH] knfsd: be...
211
  {
482fb94e1   Chuck Lever   [PATCH] knfsd: SU...
212
  	static int warned;
0dba7c2a9   Chuck Lever   NLM: Clean up flo...
213
  	int err;
482fb94e1   Chuck Lever   [PATCH] knfsd: SU...
214

eb16e9077   Chuck Lever   lockd: Start PF_I...
215
  	err = create_lockd_family(serv, PF_INET);
0dba7c2a9   Chuck Lever   NLM: Clean up flo...
216
217
  	if (err < 0)
  		goto out_err;
eb16e9077   Chuck Lever   lockd: Start PF_I...
218
219
  	err = create_lockd_family(serv, PF_INET6);
  	if (err < 0 && err != -EAFNOSUPPORT)
0dba7c2a9   Chuck Lever   NLM: Clean up flo...
220
221
222
223
224
225
226
  		goto out_err;
  
  	warned = 0;
  	return 0;
  
  out_err:
  	if (warned++ == 0)
7dcf91ec6   NeilBrown   [PATCH] knfsd: Mo...
227
  		printk(KERN_WARNING
0dba7c2a9   Chuck Lever   NLM: Clean up flo...
228
229
  			"lockd_up: makesock failed, error=%d
  ", err);
24e36663c   NeilBrown   [PATCH] knfsd: be...
230
231
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232
233
234
  /*
   * Bring up the lockd process if it's not already up.
   */
26a414092   Chuck Lever   NLM: Remove "prot...
235
  int lockd_up(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
  {
d751a7cd0   Jeff Layton   NLM: Convert lock...
237
  	struct svc_serv *serv;
d751a7cd0   Jeff Layton   NLM: Convert lock...
238
  	int		error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239

353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
240
  	mutex_lock(&nlmsvc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
  	 * Check whether we're already up and running.
  	 */
8c3916f4b   Chuck Lever   NLM: Always start...
244
  	if (nlmsvc_rqst)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
  		goto out;
  
  	/*
  	 * Sanity check: if there's no pid,
  	 * we should be the first user ...
  	 */
4a3ae42dc   NeilBrown   [PATCH] knfsd: Co...
251
  	if (nlmsvc_users)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
  		printk(KERN_WARNING
  			"lockd_up: no pid, %d users??
  ", nlmsvc_users);
  
  	error = -ENOMEM;
49a9072f2   Chuck Lever   SUNRPC: Remove @f...
257
  	serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
259
260
261
262
  	if (!serv) {
  		printk(KERN_WARNING "lockd_up: create service failed
  ");
  		goto out;
  	}
8c3916f4b   Chuck Lever   NLM: Always start...
263
264
  	error = make_socks(serv);
  	if (error < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  		goto destroy_and_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
269
  
  	/*
  	 * Create the kernel thread and wait for it to start.
  	 */
11fd165c6   Eric Dumazet   sunrpc: use bette...
270
  	nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
abd1ec4ef   Jeff Layton   lockd: close pote...
271
272
273
  	if (IS_ERR(nlmsvc_rqst)) {
  		error = PTR_ERR(nlmsvc_rqst);
  		nlmsvc_rqst = NULL;
d751a7cd0   Jeff Layton   NLM: Convert lock...
274
275
276
277
278
279
280
281
  		printk(KERN_WARNING
  			"lockd_up: svc_rqst allocation failed, error=%d
  ",
  			error);
  		goto destroy_and_out;
  	}
  
  	svc_sock_update_bufs(serv);
c72a476b4   Jeff Layton   lockd: set svc_se...
282
  	serv->sv_maxconn = nlm_max_connections;
d751a7cd0   Jeff Layton   NLM: Convert lock...
283

abd1ec4ef   Jeff Layton   lockd: close pote...
284
  	nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name);
d751a7cd0   Jeff Layton   NLM: Convert lock...
285
286
  	if (IS_ERR(nlmsvc_task)) {
  		error = PTR_ERR(nlmsvc_task);
abd1ec4ef   Jeff Layton   lockd: close pote...
287
  		svc_exit_thread(nlmsvc_rqst);
d751a7cd0   Jeff Layton   NLM: Convert lock...
288
  		nlmsvc_task = NULL;
abd1ec4ef   Jeff Layton   lockd: close pote...
289
  		nlmsvc_rqst = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
  		printk(KERN_WARNING
d751a7cd0   Jeff Layton   NLM: Convert lock...
291
292
  			"lockd_up: kthread_run failed, error=%d
  ", error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
  		goto destroy_and_out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
296
297
298
299
300
301
302
  
  	/*
  	 * Note: svc_serv structures have an initial use count of 1,
  	 * so we exit through here on both success and failure.
  	 */
  destroy_and_out:
  	svc_destroy(serv);
  out:
4a3ae42dc   NeilBrown   [PATCH] knfsd: Co...
303
304
  	if (!error)
  		nlmsvc_users++;
353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
305
  	mutex_unlock(&nlmsvc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
  	return error;
  }
2de59872a   Trond Myklebust   LOCKD: Make lockd...
308
  EXPORT_SYMBOL_GPL(lockd_up);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
313
314
315
  
  /*
   * Decrement the user count and bring down lockd if we're the last.
   */
  void
  lockd_down(void)
  {
353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
316
  	mutex_lock(&nlmsvc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
  	if (nlmsvc_users) {
  		if (--nlmsvc_users)
  			goto out;
d751a7cd0   Jeff Layton   NLM: Convert lock...
320
321
322
323
324
  	} else {
  		printk(KERN_ERR "lockd_down: no users! task=%p
  ",
  			nlmsvc_task);
  		BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326

d751a7cd0   Jeff Layton   NLM: Convert lock...
327
328
329
330
  	if (!nlmsvc_task) {
  		printk(KERN_ERR "lockd_down: no lockd running.
  ");
  		BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
  	}
d751a7cd0   Jeff Layton   NLM: Convert lock...
332
  	kthread_stop(nlmsvc_task);
abd1ec4ef   Jeff Layton   lockd: close pote...
333
334
335
  	svc_exit_thread(nlmsvc_rqst);
  	nlmsvc_task = NULL;
  	nlmsvc_rqst = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  out:
353ab6e97   Ingo Molnar   [PATCH] sem2mutex...
337
  	mutex_unlock(&nlmsvc_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  }
2de59872a   Trond Myklebust   LOCKD: Make lockd...
339
  EXPORT_SYMBOL_GPL(lockd_down);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340

90d5b1806   Chuck Lever   NLM: LOCKD fails ...
341
  #ifdef CONFIG_SYSCTL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
  /*
   * Sysctl parameters (same as module parameters, different interface).
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
  static ctl_table nlm_sysctls[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
  		.procname	= "nlm_grace_period",
  		.data		= &nlm_grace_period,
7ee91ec14   Steve Dickson   [PATCH] NFS: proc...
349
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
351
  		.proc_handler	= proc_doulongvec_minmax,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
  		.extra1		= (unsigned long *) &nlm_grace_period_min,
  		.extra2		= (unsigned long *) &nlm_grace_period_max,
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
  		.procname	= "nlm_timeout",
  		.data		= &nlm_timeout,
7ee91ec14   Steve Dickson   [PATCH] NFS: proc...
358
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
360
  		.proc_handler	= proc_doulongvec_minmax,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
363
364
  		.extra1		= (unsigned long *) &nlm_timeout_min,
  		.extra2		= (unsigned long *) &nlm_timeout_max,
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
366
367
368
  		.procname	= "nlm_udpport",
  		.data		= &nlm_udpport,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
369
  		.proc_handler	= proc_dointvec_minmax,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
372
373
  		.extra1		= (int *) &nlm_port_min,
  		.extra2		= (int *) &nlm_port_max,
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
377
  		.procname	= "nlm_tcpport",
  		.data		= &nlm_tcpport,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
378
  		.proc_handler	= proc_dointvec_minmax,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
  		.extra1		= (int *) &nlm_port_min,
  		.extra2		= (int *) &nlm_port_max,
  	},
abd1f5009   Olaf Kirch   [PATCH] knfsd: lo...
382
  	{
abd1f5009   Olaf Kirch   [PATCH] knfsd: lo...
383
384
385
386
  		.procname	= "nsm_use_hostnames",
  		.data		= &nsm_use_hostnames,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
387
  		.proc_handler	= proc_dointvec,
abd1f5009   Olaf Kirch   [PATCH] knfsd: lo...
388
  	},
460f5cac1   Olaf Kirch   [PATCH] knfsd: ex...
389
  	{
460f5cac1   Olaf Kirch   [PATCH] knfsd: ex...
390
391
392
393
  		.procname	= "nsm_local_state",
  		.data		= &nsm_local_state,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
394
  		.proc_handler	= proc_dointvec,
460f5cac1   Olaf Kirch   [PATCH] knfsd: ex...
395
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
396
  	{ }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
400
  };
  
  static ctl_table nlm_sysctl_dir[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
  		.procname	= "nfs",
  		.mode		= 0555,
  		.child		= nlm_sysctls,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
405
  	{ }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
409
  };
  
  static ctl_table nlm_sysctl_root[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
  		.procname	= "fs",
  		.mode		= 0555,
  		.child		= nlm_sysctl_dir,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
414
  	{ }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  };
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
416
  #endif	/* CONFIG_SYSCTL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
  /*
405ae7d38   Robert P. J. Day   Replace remaining...
418
   * Module (and sysfs) parameters.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
   */
  
  #define param_set_min_max(name, type, which_strtol, min, max)		\
  static int param_set_##name(const char *val, struct kernel_param *kp)	\
  {									\
  	char *endp;							\
  	__typeof__(type) num = which_strtol(val, &endp, 0);		\
  	if (endp == val || *endp || num < (min) || num > (max))		\
  		return -EINVAL;						\
  	*((int *) kp->arg) = num;					\
  	return 0;							\
  }
  
  static inline int is_callback(u32 proc)
  {
  	return proc == NLMPROC_GRANTED
  		|| proc == NLMPROC_GRANTED_MSG
  		|| proc == NLMPROC_TEST_RES
  		|| proc == NLMPROC_LOCK_RES
  		|| proc == NLMPROC_CANCEL_RES
  		|| proc == NLMPROC_UNLOCK_RES
  		|| proc == NLMPROC_NSM_NOTIFY;
  }
  
  
  static int lockd_authenticate(struct svc_rqst *rqstp)
  {
  	rqstp->rq_client = NULL;
  	switch (rqstp->rq_authop->flavour) {
  		case RPC_AUTH_NULL:
  		case RPC_AUTH_UNIX:
  			if (rqstp->rq_proc == 0)
  				return SVC_OK;
  			if (is_callback(rqstp->rq_proc)) {
  				/* Leave it to individual procedures to
  				 * call nlmsvc_lookup_host(rqstp)
  				 */
  				return SVC_OK;
  			}
  			return svc_set_client(rqstp);
  	}
  	return SVC_DENIED;
  }
  
  
  param_set_min_max(port, int, simple_strtol, 0, 65535)
  param_set_min_max(grace_period, unsigned long, simple_strtoul,
  		  nlm_grace_period_min, nlm_grace_period_max)
  param_set_min_max(timeout, unsigned long, simple_strtoul,
  		  nlm_timeout_min, nlm_timeout_max)
  
  MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
  MODULE_DESCRIPTION("NFS file locking service version " LOCKD_VERSION ".");
  MODULE_LICENSE("GPL");
  
  module_param_call(nlm_grace_period, param_set_grace_period, param_get_ulong,
  		  &nlm_grace_period, 0644);
  module_param_call(nlm_timeout, param_set_timeout, param_get_ulong,
  		  &nlm_timeout, 0644);
  module_param_call(nlm_udpport, param_set_port, param_get_int,
  		  &nlm_udpport, 0644);
  module_param_call(nlm_tcpport, param_set_port, param_get_int,
  		  &nlm_tcpport, 0644);
abd1f5009   Olaf Kirch   [PATCH] knfsd: lo...
482
  module_param(nsm_use_hostnames, bool, 0644);
c72a476b4   Jeff Layton   lockd: set svc_se...
483
  module_param(nlm_max_connections, uint, 0644);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
485
486
487
488
489
490
  
  /*
   * Initialising and terminating the module.
   */
  
  static int __init init_nlm(void)
  {
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
491
  #ifdef CONFIG_SYSCTL
0b4d41471   Eric W. Biederman   [PATCH] sysctl: r...
492
  	nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
  	return nlm_sysctl_table ? 0 : -ENOMEM;
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
494
495
496
  #else
  	return 0;
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
500
501
502
  }
  
  static void __exit exit_nlm(void)
  {
  	/* FIXME: delete all NLM clients */
  	nlm_shutdown_hosts();
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
503
  #ifdef CONFIG_SYSCTL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
  	unregister_sysctl_table(nlm_sysctl_table);
90d5b1806   Chuck Lever   NLM: LOCKD fails ...
505
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  }
  
  module_init(init_nlm);
  module_exit(exit_nlm);
  
  /*
   * Define NLM program and procedures
   */
  static struct svc_version	nlmsvc_version1 = {
  		.vs_vers	= 1,
  		.vs_nproc	= 17,
  		.vs_proc	= nlmsvc_procedures,
  		.vs_xdrsize	= NLMSVC_XDRSIZE,
  };
  static struct svc_version	nlmsvc_version3 = {
  		.vs_vers	= 3,
  		.vs_nproc	= 24,
  		.vs_proc	= nlmsvc_procedures,
  		.vs_xdrsize	= NLMSVC_XDRSIZE,
  };
  #ifdef CONFIG_LOCKD_V4
  static struct svc_version	nlmsvc_version4 = {
  		.vs_vers	= 4,
  		.vs_nproc	= 24,
  		.vs_proc	= nlmsvc_procedures4,
  		.vs_xdrsize	= NLMSVC_XDRSIZE,
  };
  #endif
  static struct svc_version *	nlmsvc_version[] = {
  	[1] = &nlmsvc_version1,
  	[3] = &nlmsvc_version3,
  #ifdef CONFIG_LOCKD_V4
  	[4] = &nlmsvc_version4,
  #endif
  };
  
  static struct svc_stat		nlmsvc_stats;
e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
543
  #define NLM_NRVERS	ARRAY_SIZE(nlmsvc_version)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
546
547
548
549
550
551
552
  static struct svc_program	nlmsvc_program = {
  	.pg_prog		= NLM_PROGRAM,		/* program number */
  	.pg_nvers		= NLM_NRVERS,		/* number of entries in nlmsvc_version */
  	.pg_vers		= nlmsvc_version,	/* version table */
  	.pg_name		= "lockd",		/* service name */
  	.pg_class		= "nfsd",		/* share authentication with nfsd */
  	.pg_stats		= &nlmsvc_stats,	/* stats table */
  	.pg_authenticate = &lockd_authenticate	/* export authentication */
  };