Blame view

fs/nfsd/nfsctl.c 32.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
   * Syscall interface to knfsd.
   *
   * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
   */
5a0e3ad6a   Tejun Heo   include cleanup: ...
6
  #include <linux/slab.h>
3f8206d49   Al Viro   [PATCH] get rid o...
7
  #include <linux/namei.h>
b41b66d63   NeilBrown   [PATCH] knfsd: al...
8
  #include <linux/ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9

80212d59e   NeilBrown   [PATCH] knfsd: de...
10
  #include <linux/sunrpc/svcsock.h>
4373ea84c   Wendy Cheng   lockd: unlock loc...
11
  #include <linux/lockd/lockd.h>
5976687a2   Jeff Layton   sunrpc: move addr...
12
  #include <linux/sunrpc/addr.h>
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
13
  #include <linux/sunrpc/gss_api.h>
b084f598d   J. Bruce Fields   nfsd: fix depende...
14
  #include <linux/sunrpc/gss_krb5_enctypes.h>
813fd320c   Jeff Layton   nfsd: add notifie...
15
  #include <linux/sunrpc/rpc_pipe_fs.h>
143cb494c   Paul Gortmaker   fs: add module.h ...
16
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17

2ca72e17e   J. Bruce Fields   nfsd4: move idmap...
18
  #include "idmap.h"
9a74af213   Boaz Harrosh   nfsd: Move privat...
19
20
  #include "nfsd.h"
  #include "cache.h"
f3c7521fe   Bryan Schumaker   NFSD: Fold fault_...
21
  #include "state.h"
7ea34ac15   Jeff Layton   nfsd: add a per-n...
22
  #include "netns.h"
9cf514ccf   Christoph Hellwig   nfsd: implement p...
23
  #include "pnfs.h"
9a74af213   Boaz Harrosh   nfsd: Move privat...
24

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  /*
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
26
   *	We have a single directory with several nodes in it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
   */
  enum {
  	NFSD_Root = 1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  	NFSD_List,
e8e8753f7   J. Bruce Fields   nfsd: new interfa...
31
  	NFSD_Export_features,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  	NFSD_Fh,
4373ea84c   Wendy Cheng   lockd: unlock loc...
33
  	NFSD_FO_UnlockIP,
17efa372c   Wendy Cheng   lockd: unlock loc...
34
  	NFSD_FO_UnlockFS,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  	NFSD_Threads,
eed2965af   Greg Banks   [PATCH] knfsd: al...
36
  	NFSD_Pool_Threads,
03cf6c9f4   Greg Banks   knfsd: add file t...
37
  	NFSD_Pool_Stats,
a2f999a37   Jeff Layton   nfsd: add new rep...
38
  	NFSD_Reply_Cache_Stats,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
39
  	NFSD_Versions,
80212d59e   NeilBrown   [PATCH] knfsd: de...
40
  	NFSD_Ports,
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
41
  	NFSD_MaxBlkSize,
5b8db00ba   Jeff Layton   nfsd: add a new /...
42
  	NFSD_MaxConnections,
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
43
  	NFSD_SupportedEnctypes,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
44
45
46
47
48
  	/*
  	 * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
  	 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
  	 */
  #ifdef CONFIG_NFSD_V4
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
  	NFSD_Leasetime,
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
50
  	NFSD_Gracetime,
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
51
  	NFSD_RecoveryDir,
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
52
  	NFSD_V4EndGrace,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
53
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
  };
  
  /*
   * write() for these nodes.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
b046ccdc1   Chuck Lever   NFSD: clean up fa...
60
61
  static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
  static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  static ssize_t write_threads(struct file *file, char *buf, size_t size);
eed2965af   Greg Banks   [PATCH] knfsd: al...
63
  static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
64
  static ssize_t write_versions(struct file *file, char *buf, size_t size);
80212d59e   NeilBrown   [PATCH] knfsd: de...
65
  static ssize_t write_ports(struct file *file, char *buf, size_t size);
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
66
  static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
5b8db00ba   Jeff Layton   nfsd: add a new /...
67
  static ssize_t write_maxconn(struct file *file, char *buf, size_t size);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
68
  #ifdef CONFIG_NFSD_V4
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
70
  static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
71
  static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
72
  static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
73
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
  
  static ssize_t (*write_op[])(struct file *, char *, size_t) = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	[NFSD_Fh] = write_filehandle,
b046ccdc1   Chuck Lever   NFSD: clean up fa...
77
78
  	[NFSD_FO_UnlockIP] = write_unlock_ip,
  	[NFSD_FO_UnlockFS] = write_unlock_fs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  	[NFSD_Threads] = write_threads,
eed2965af   Greg Banks   [PATCH] knfsd: al...
80
  	[NFSD_Pool_Threads] = write_pool_threads,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
81
  	[NFSD_Versions] = write_versions,
80212d59e   NeilBrown   [PATCH] knfsd: de...
82
  	[NFSD_Ports] = write_ports,
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
83
  	[NFSD_MaxBlkSize] = write_maxblksize,
5b8db00ba   Jeff Layton   nfsd: add a new /...
84
  	[NFSD_MaxConnections] = write_maxconn,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
85
  #ifdef CONFIG_NFSD_V4
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  	[NFSD_Leasetime] = write_leasetime,
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
87
  	[NFSD_Gracetime] = write_gracetime,
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
88
  	[NFSD_RecoveryDir] = write_recoverydir,
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
89
  	[NFSD_V4EndGrace] = write_v4_end_grace,
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
90
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
  };
  
  static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
  {
496ad9aa8   Al Viro   new helper: file_...
95
  	ino_t ino =  file_inode(file)->i_ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
  	char *data;
  	ssize_t rv;
e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
98
  	if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
102
103
104
105
  		return -EINVAL;
  
  	data = simple_transaction_get(file, buf, size);
  	if (IS_ERR(data))
  		return PTR_ERR(data);
  
  	rv =  write_op[ino](file, data, size);
8971a1016   NeilBrown   [PATCH] knfsd: fi...
106
  	if (rv >= 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
111
  		simple_transaction_set(file, rv);
  		rv = size;
  	}
  	return rv;
  }
7390022d6   NeilBrown   [PATCH] knfsd: Re...
112
113
114
115
116
117
118
119
120
121
122
123
124
  static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
  {
  	if (! file->private_data) {
  		/* An attempt to read a transaction file without writing
  		 * causes a 0-byte write so that the file can return
  		 * state information
  		 */
  		ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
  		if (rv < 0)
  			return rv;
  	}
  	return simple_transaction_read(file, buf, size, pos);
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
125
  static const struct file_operations transaction_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
  	.write		= nfsctl_transaction_write,
7390022d6   NeilBrown   [PATCH] knfsd: Re...
127
  	.read		= nfsctl_transaction_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
  	.release	= simple_transaction_release,
6038f373a   Arnd Bergmann   llseek: automatic...
129
  	.llseek		= default_llseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  };
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
131
  static int exports_net_open(struct net *net, struct file *file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  {
f2c7ea10f   Stanislav Kinsbursky   nfsd: pass svc_ex...
133
134
  	int err;
  	struct seq_file *seq;
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
135
  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
f2c7ea10f   Stanislav Kinsbursky   nfsd: pass svc_ex...
136
137
138
139
140
141
  
  	err = seq_open(file, &nfs_exports_op);
  	if (err)
  		return err;
  
  	seq = file->private_data;
e5f06f720   Stanislav Kinsbursky   nfsd: make expkey...
142
  	seq->private = nn->svc_export_cache;
f2c7ea10f   Stanislav Kinsbursky   nfsd: pass svc_ex...
143
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  }
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
145
146
147
148
149
150
151
152
153
154
  static int exports_proc_open(struct inode *inode, struct file *file)
  {
  	return exports_net_open(current->nsproxy->net_ns, file);
  }
  
  static const struct file_operations exports_proc_operations = {
  	.open		= exports_proc_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= seq_release,
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
155
156
157
158
159
160
161
162
163
  };
  
  static int exports_nfsd_open(struct inode *inode, struct file *file)
  {
  	return exports_net_open(inode->i_sb->s_fs_info, file);
  }
  
  static const struct file_operations exports_nfsd_operations = {
  	.open		= exports_nfsd_open,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= seq_release,
  };
e8e8753f7   J. Bruce Fields   nfsd: new interfa...
168
169
170
171
172
173
174
175
176
177
178
  static int export_features_show(struct seq_file *m, void *v)
  {
  	seq_printf(m, "0x%x 0x%x
  ", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
  	return 0;
  }
  
  static int export_features_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, export_features_show, NULL);
  }
75ef9de12   Al Viro   constify a bunch ...
179
  static const struct file_operations export_features_operations = {
e8e8753f7   J. Bruce Fields   nfsd: new interfa...
180
181
182
183
184
  	.open		= export_features_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
b084f598d   J. Bruce Fields   nfsd: fix depende...
185
  #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
186
187
  static int supported_enctypes_show(struct seq_file *m, void *v)
  {
b084f598d   J. Bruce Fields   nfsd: fix depende...
188
  	seq_printf(m, KRB5_SUPPORTED_ENCTYPES);
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
189
190
191
192
193
194
195
  	return 0;
  }
  
  static int supported_enctypes_open(struct inode *inode, struct file *file)
  {
  	return single_open(file, supported_enctypes_show, NULL);
  }
75ef9de12   Al Viro   constify a bunch ...
196
  static const struct file_operations supported_enctypes_ops = {
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
197
198
199
200
201
  	.open		= supported_enctypes_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
b084f598d   J. Bruce Fields   nfsd: fix depende...
202
  #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
203

828c09509   Alexey Dobriyan   const: constify r...
204
  static const struct file_operations pool_stats_operations = {
03cf6c9f4   Greg Banks   knfsd: add file t...
205
206
207
  	.open		= nfsd_pool_stats_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
ed2d8aed5   Ryusei Yamaguchi   knfsd: Replace lo...
208
  	.release	= nfsd_pool_stats_release,
03cf6c9f4   Greg Banks   knfsd: add file t...
209
  };
a2f999a37   Jeff Layton   nfsd: add new rep...
210
211
212
213
214
215
  static struct file_operations reply_cache_stats_operations = {
  	.open		= nfsd_reply_cache_stats_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= single_release,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
218
  /*----------------------------------------------------------------------------*/
  /*
   * payload - write methods
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
   */
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
220
221
222
223
  static inline struct net *netns(struct file *file)
  {
  	return file_inode(file)->i_sb->s_fs_info;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

262a09823   Chuck Lever   NFSD: Add documen...
225
226
227
228
229
230
231
232
  /**
   * write_unlock_ip - Release all locks used by a client
   *
   * Experimental.
   *
   * Input:
   *			buf:	'
  '-terminated C string containing a
4116092b9   Chuck Lever   NFSD: Support IPv...
233
   *				presentation format IP address
262a09823   Chuck Lever   NFSD: Add documen...
234
235
236
237
238
   *			size:	length of C string in @buf
   * Output:
   *	On success:	returns zero if all specified locks were released;
   *			returns one if one or more locks were not released
   *	On error:	return code is negative errno value
262a09823   Chuck Lever   NFSD: Add documen...
239
   */
b046ccdc1   Chuck Lever   NFSD: clean up fa...
240
  static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
4373ea84c   Wendy Cheng   lockd: unlock loc...
241
  {
4116092b9   Chuck Lever   NFSD: Support IPv...
242
243
244
  	struct sockaddr_storage address;
  	struct sockaddr *sap = (struct sockaddr *)&address;
  	size_t salen = sizeof(address);
367c8c7bd   Chuck Lever   lockd: Pass "stru...
245
  	char *fo_path;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
246
  	struct net *net = netns(file);
4373ea84c   Wendy Cheng   lockd: unlock loc...
247
248
249
250
251
252
253
254
255
256
257
258
  
  	/* sanity check */
  	if (size == 0)
  		return -EINVAL;
  
  	if (buf[size-1] != '
  ')
  		return -EINVAL;
  
  	fo_path = buf;
  	if (qword_get(&buf, fo_path, size) < 0)
  		return -EINVAL;
11f779421   Stanislav Kinsbursky   nfsd: containeriz...
259
  	if (rpc_pton(net, fo_path, size, sap, salen) == 0)
4373ea84c   Wendy Cheng   lockd: unlock loc...
260
  		return -EINVAL;
4373ea84c   Wendy Cheng   lockd: unlock loc...
261

4116092b9   Chuck Lever   NFSD: Support IPv...
262
  	return nlmsvc_unlock_all_by_ip(sap);
4373ea84c   Wendy Cheng   lockd: unlock loc...
263
  }
262a09823   Chuck Lever   NFSD: Add documen...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  /**
   * write_unlock_fs - Release all locks on a local file system
   *
   * Experimental.
   *
   * Input:
   *			buf:	'
  '-terminated C string containing the
   *				absolute pathname of a local file system
   *			size:	length of C string in @buf
   * Output:
   *	On success:	returns zero if all specified locks were released;
   *			returns one if one or more locks were not released
   *	On error:	return code is negative errno value
   */
b046ccdc1   Chuck Lever   NFSD: clean up fa...
279
  static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
17efa372c   Wendy Cheng   lockd: unlock loc...
280
  {
a63bb9966   Al Viro   [PATCH] switch nf...
281
  	struct path path;
17efa372c   Wendy Cheng   lockd: unlock loc...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  	char *fo_path;
  	int error;
  
  	/* sanity check */
  	if (size == 0)
  		return -EINVAL;
  
  	if (buf[size-1] != '
  ')
  		return -EINVAL;
  
  	fo_path = buf;
  	if (qword_get(&buf, fo_path, size) < 0)
  		return -EINVAL;
a63bb9966   Al Viro   [PATCH] switch nf...
296
  	error = kern_path(fo_path, 0, &path);
17efa372c   Wendy Cheng   lockd: unlock loc...
297
298
  	if (error)
  		return error;
262a09823   Chuck Lever   NFSD: Add documen...
299
300
301
302
303
304
305
306
307
  	/*
  	 * XXX: Needs better sanity checking.  Otherwise we could end up
  	 * releasing locks on the wrong file system.
  	 *
  	 * For example:
  	 * 1.  Does the path refer to a directory?
  	 * 2.  Is that directory a mount point, or
  	 * 3.  Is that directory the root of an exported file system?
  	 */
d8c9584ea   Al Viro   vfs: prefer ->den...
308
  	error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
17efa372c   Wendy Cheng   lockd: unlock loc...
309

a63bb9966   Al Viro   [PATCH] switch nf...
310
  	path_put(&path);
17efa372c   Wendy Cheng   lockd: unlock loc...
311
312
  	return error;
  }
262a09823   Chuck Lever   NFSD: Add documen...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  /**
   * write_filehandle - Get a variable-length NFS file handle by path
   *
   * On input, the buffer contains a '
  '-terminated C string comprised of
   * three alphanumeric words separated by whitespace.  The string may
   * contain escape sequences.
   *
   * Input:
   *			buf:
   *				domain:		client domain name
   *				path:		export pathname
   *				maxsize:	numeric maximum size of
   *						@buf
   *			size:	length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C
   *			string containing a ASCII hex text version
   *			of the NFS file handle;
   *			return code is the size in bytes of the string
   *	On error:	return code is negative errno value
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
  static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  	char *dname, *path;
246d95ba0   Andrew Morton   nfsd warning fix
339
  	int uninitialized_var(maxsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
343
  	char *mesg = buf;
  	int len;
  	struct auth_domain *dom;
  	struct knfsd_fh fh;
87d26ea77   J. Bruce Fields   nfsd: more carefu...
344
345
  	if (size == 0)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
348
349
350
351
352
  	if (buf[size-1] != '
  ')
  		return -EINVAL;
  	buf[size-1] = 0;
  
  	dname = mesg;
  	len = qword_get(&mesg, dname, size);
54224f04a   Chuck Lever   NFSD: Fix a handf...
353
354
  	if (len <= 0)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
356
357
  	
  	path = dname+len+1;
  	len = qword_get(&mesg, path, size);
54224f04a   Chuck Lever   NFSD: Fix a handf...
358
359
  	if (len <= 0)
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
365
366
  
  	len = get_int(&mesg, &maxsize);
  	if (len)
  		return len;
  
  	if (maxsize < NFS_FHSIZE)
  		return -EINVAL;
3c7aa15d2   Kinglong Mee   NFSD: Using min/m...
367
  	maxsize = min(maxsize, NFS3_FHSIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
371
372
373
374
375
  
  	if (qword_get(&mesg, mesg, size)>0)
  		return -EINVAL;
  
  	/* we have all the words, they are in buf.. */
  	dom = unix_domain_find(dname);
  	if (!dom)
  		return -ENOMEM;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
376
  	len = exp_rootfh(netns(file), dom, path, &fh,  maxsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
380
  	auth_domain_put(dom);
  	if (len)
  		return len;
  	
54224f04a   Chuck Lever   NFSD: Fix a handf...
381
382
  	mesg = buf;
  	len = SIMPLE_TRANSACTION_LIMIT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
386
387
  	qword_addhex(&mesg, &len, (char*)&fh.fh_base, fh.fh_size);
  	mesg[-1] = '
  ';
  	return mesg - buf;	
  }
262a09823   Chuck Lever   NFSD: Add documen...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
  /**
   * write_threads - Start NFSD, or report the current number of running threads
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C
   *			string numeric value representing the number of
   *			running NFSD threads;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero
   *
   * OR
   *
   * Input:
   *			buf:		C string containing an unsigned
   *					integer value representing the
   *					number of NFSD threads to start
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	NFS service is started;
   *			passed-in buffer filled with '
  '-terminated C
   *			string numeric value representing the number of
   *			running NFSD threads;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
  static ssize_t write_threads(struct file *file, char *buf, size_t size)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  	char *mesg = buf;
  	int rv;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
422
  	struct net *net = netns(file);
d41a9417c   Stanislav Kinsbursky   nfsd: pass net to...
423

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
426
427
428
  	if (size > 0) {
  		int newthreads;
  		rv = get_int(&mesg, &newthreads);
  		if (rv)
  			return rv;
9e074856c   Chuck Lever   NFSD: Replace ope...
429
  		if (newthreads < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  			return -EINVAL;
d41a9417c   Stanislav Kinsbursky   nfsd: pass net to...
431
  		rv = nfsd_svc(newthreads, net);
82e12fe92   NeilBrown   nfsd: don't take ...
432
  		if (rv < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  			return rv;
82e12fe92   NeilBrown   nfsd: don't take ...
434
  	} else
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
435
  		rv = nfsd_nrthreads(net);
e06b64050   Chuck Lever   NFSD: Stricter bu...
436

82e12fe92   NeilBrown   nfsd: don't take ...
437
438
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d
  ", rv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
  }
262a09823   Chuck Lever   NFSD: Add documen...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
  /**
   * write_pool_threads - Set or report the current number of threads per pool
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   *
   * OR
   *
   * Input:
   * 			buf:		C string containing whitespace-
   * 					separated unsigned integer values
   *					representing the number of NFSD
   *					threads to start in each pool
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C
   *			string containing integer values representing the
   *			number of NFSD threads in each pool;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
eed2965af   Greg Banks   [PATCH] knfsd: al...
463
464
465
466
467
468
469
470
471
  static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
  {
  	/* if size > 0, look for an array of number of threads per node
  	 * and apply them  then write out number of threads per node as reply
  	 */
  	char *mesg = buf;
  	int i;
  	int rv;
  	int len;
bedbdd8ba   Neil Brown   knfsd: Replace lo...
472
  	int npools;
eed2965af   Greg Banks   [PATCH] knfsd: al...
473
  	int *nthreads;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
474
  	struct net *net = netns(file);
eed2965af   Greg Banks   [PATCH] knfsd: al...
475

bedbdd8ba   Neil Brown   knfsd: Replace lo...
476
  	mutex_lock(&nfsd_mutex);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
477
  	npools = nfsd_nrpools(net);
eed2965af   Greg Banks   [PATCH] knfsd: al...
478
479
480
481
482
483
  	if (npools == 0) {
  		/*
  		 * NFS is shut down.  The admin can start it by
  		 * writing to the threads file but NOT the pool_threads
  		 * file, sorry.  Report zero threads.
  		 */
bedbdd8ba   Neil Brown   knfsd: Replace lo...
484
  		mutex_unlock(&nfsd_mutex);
eed2965af   Greg Banks   [PATCH] knfsd: al...
485
486
487
488
489
490
  		strcpy(buf, "0
  ");
  		return strlen(buf);
  	}
  
  	nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
bedbdd8ba   Neil Brown   knfsd: Replace lo...
491
  	rv = -ENOMEM;
eed2965af   Greg Banks   [PATCH] knfsd: al...
492
  	if (nthreads == NULL)
bedbdd8ba   Neil Brown   knfsd: Replace lo...
493
  		goto out_free;
eed2965af   Greg Banks   [PATCH] knfsd: al...
494
495
496
497
498
499
500
501
502
503
504
505
  
  	if (size > 0) {
  		for (i = 0; i < npools; i++) {
  			rv = get_int(&mesg, &nthreads[i]);
  			if (rv == -ENOENT)
  				break;		/* fewer numbers than pools */
  			if (rv)
  				goto out_free;	/* syntax error */
  			rv = -EINVAL;
  			if (nthreads[i] < 0)
  				goto out_free;
  		}
3938a0d5e   Stanislav Kinsbursky   nfsd: pass net to...
506
  		rv = nfsd_set_nrthreads(i, nthreads, net);
eed2965af   Greg Banks   [PATCH] knfsd: al...
507
508
509
  		if (rv)
  			goto out_free;
  	}
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
510
  	rv = nfsd_get_nrthreads(npools, nthreads, net);
eed2965af   Greg Banks   [PATCH] knfsd: al...
511
512
513
514
515
516
517
518
519
520
521
522
  	if (rv)
  		goto out_free;
  
  	mesg = buf;
  	size = SIMPLE_TRANSACTION_LIMIT;
  	for (i = 0; i < npools && size > 0; i++) {
  		snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '
  ' : ' '));
  		len = strlen(mesg);
  		size -= len;
  		mesg += len;
  	}
413d63d71   J. Bruce Fields   nfsd: minor write...
523
  	rv = mesg - buf;
eed2965af   Greg Banks   [PATCH] knfsd: al...
524
525
  out_free:
  	kfree(nthreads);
bedbdd8ba   Neil Brown   knfsd: Replace lo...
526
  	mutex_unlock(&nfsd_mutex);
eed2965af   Greg Banks   [PATCH] knfsd: al...
527
528
  	return rv;
  }
3dd98a3bc   Jeff Layton   knfsd: clean up n...
529
  static ssize_t __write_versions(struct file *file, char *buf, size_t size)
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
530
  {
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
531
  	char *mesg = buf;
8daf220a6   Benny Halevy   nfsd41: control n...
532
  	char *vers, *minorp, sign;
261758b5c   Chuck Lever   NFSD: Stricter bu...
533
  	int len, num, remaining;
8daf220a6   Benny Halevy   nfsd41: control n...
534
  	unsigned minor;
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
535
536
  	ssize_t tlen = 0;
  	char *sep;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
537
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
538
539
  
  	if (size>0) {
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
540
  		if (nn->nfsd_serv)
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
541
  			/* Cannot change versions without updating
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
542
  			 * nn->nfsd_serv->sv_xdrsize, and reallocing
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
543
544
  			 * rq_argp and rq_resp
  			 */
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
545
546
547
548
549
550
551
552
553
554
555
556
  			return -EBUSY;
  		if (buf[size-1] != '
  ')
  			return -EINVAL;
  		buf[size-1] = 0;
  
  		vers = mesg;
  		len = qword_get(&mesg, vers, size);
  		if (len <= 0) return -EINVAL;
  		do {
  			sign = *vers;
  			if (sign == '+' || sign == '-')
8daf220a6   Benny Halevy   nfsd41: control n...
557
  				num = simple_strtol((vers+1), &minorp, 0);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
558
  			else
8daf220a6   Benny Halevy   nfsd41: control n...
559
560
  				num = simple_strtol(vers, &minorp, 0);
  			if (*minorp == '.') {
ff89be87c   J. Bruce Fields   nfsd4: require ve...
561
  				if (num != 4)
8daf220a6   Benny Halevy   nfsd41: control n...
562
563
564
565
566
567
568
569
570
  					return -EINVAL;
  				minor = simple_strtoul(minorp+1, NULL, 0);
  				if (minor == 0)
  					return -EINVAL;
  				if (nfsd_minorversion(minor, sign == '-' ?
  						     NFSD_CLEAR : NFSD_SET) < 0)
  					return -EINVAL;
  				goto next;
  			}
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
571
572
573
574
  			switch(num) {
  			case 2:
  			case 3:
  			case 4:
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
575
  				nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
576
577
578
579
  				break;
  			default:
  				return -EINVAL;
  			}
8daf220a6   Benny Halevy   nfsd41: control n...
580
  		next:
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
581
  			vers += len + 1;
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
582
583
584
585
  		} while ((len = qword_get(&mesg, vers, size)) > 0);
  		/* If all get turned off, turn them back on, as
  		 * having no versions is BAD
  		 */
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
586
  		nfsd_reset_versions();
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
587
  	}
261758b5c   Chuck Lever   NFSD: Stricter bu...
588

70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
589
590
591
  	/* Now write current state into reply buffer */
  	len = 0;
  	sep = "";
261758b5c   Chuck Lever   NFSD: Stricter bu...
592
  	remaining = SIMPLE_TRANSACTION_LIMIT;
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
593
  	for (num=2 ; num <= 4 ; num++)
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
594
  		if (nfsd_vers(num, NFSD_AVAIL)) {
261758b5c   Chuck Lever   NFSD: Stricter bu...
595
  			len = snprintf(buf, remaining, "%s%c%d", sep,
6658d3a7b   NeilBrown   [PATCH] knfsd: re...
596
  				       nfsd_vers(num, NFSD_TEST)?'+':'-',
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
597
598
  				       num);
  			sep = " ";
261758b5c   Chuck Lever   NFSD: Stricter bu...
599

818f2f57f   Dan Carpenter   nfsd: minor off b...
600
  			if (len >= remaining)
261758b5c   Chuck Lever   NFSD: Stricter bu...
601
602
603
604
  				break;
  			remaining -= len;
  			buf += len;
  			tlen += len;
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
605
  		}
8daf220a6   Benny Halevy   nfsd41: control n...
606
  	if (nfsd_vers(4, NFSD_AVAIL))
261758b5c   Chuck Lever   NFSD: Stricter bu...
607
608
609
  		for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION;
  		     minor++) {
  			len = snprintf(buf, remaining, " %c4.%u",
8daf220a6   Benny Halevy   nfsd41: control n...
610
611
612
613
  					(nfsd_vers(4, NFSD_TEST) &&
  					 nfsd_minorversion(minor, NFSD_TEST)) ?
  						'+' : '-',
  					minor);
261758b5c   Chuck Lever   NFSD: Stricter bu...
614

818f2f57f   Dan Carpenter   nfsd: minor off b...
615
  			if (len >= remaining)
261758b5c   Chuck Lever   NFSD: Stricter bu...
616
617
618
619
620
621
622
623
  				break;
  			remaining -= len;
  			buf += len;
  			tlen += len;
  		}
  
  	len = snprintf(buf, remaining, "
  ");
818f2f57f   Dan Carpenter   nfsd: minor off b...
624
  	if (len >= remaining)
261758b5c   Chuck Lever   NFSD: Stricter bu...
625
626
  		return -EINVAL;
  	return tlen + len;
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
627
  }
262a09823   Chuck Lever   NFSD: Add documen...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  /**
   * write_versions - Set or report the available NFS protocol versions
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C
   *			string containing positive or negative integer
   *			values representing the current status of each
   *			protocol version;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   *
   * OR
   *
   * Input:
   * 			buf:		C string containing whitespace-
   * 					separated positive or negative
   * 					integer values representing NFS
   * 					protocol versions to enable ("+n")
   * 					or disable ("-n")
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	status of zero or more protocol versions has
   *			been updated; passed-in buffer filled with
   *			'
  '-terminated C string containing positive
   *			or negative integer values representing the
   *			current status of each protocol version;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
3dd98a3bc   Jeff Layton   knfsd: clean up n...
662
663
664
665
666
667
668
669
670
  static ssize_t write_versions(struct file *file, char *buf, size_t size)
  {
  	ssize_t rv;
  
  	mutex_lock(&nfsd_mutex);
  	rv = __write_versions(file, buf, size);
  	mutex_unlock(&nfsd_mutex);
  	return rv;
  }
4cd5dc751   Chuck Lever   NFSD: Refactor tr...
671
  /*
0a5372d8a   Chuck Lever   NFSD: Finish refa...
672
673
674
   * Zero-length write.  Return a list of NFSD's current listener
   * transports.
   */
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
675
  static ssize_t __write_ports_names(char *buf, struct net *net)
0a5372d8a   Chuck Lever   NFSD: Finish refa...
676
  {
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
677
678
679
  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  
  	if (nn->nfsd_serv == NULL)
0a5372d8a   Chuck Lever   NFSD: Finish refa...
680
  		return 0;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
681
  	return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
0a5372d8a   Chuck Lever   NFSD: Finish refa...
682
683
684
  }
  
  /*
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
685
686
687
688
   * A single 'fd' number was written, in which case it must be for
   * a socket of a supported family/protocol, and we use it as an
   * nfsd listener.
   */
081603520   Stanislav Kinsbursky   nfsd: pass net to...
689
  static ssize_t __write_ports_addfd(char *buf, struct net *net)
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
690
691
692
  {
  	char *mesg = buf;
  	int fd, err;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
693
  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
694
695
696
697
  
  	err = get_int(&mesg, &fd);
  	if (err != 0 || fd < 0)
  		return -EINVAL;
306463942   Stanislav Kinsbursky   nfsd: check passe...
698
699
700
701
702
  	if (svc_alien_sock(net, fd)) {
  		printk(KERN_ERR "%s: socket net is different to NFSd's one
  ", __func__);
  		return -EINVAL;
  	}
6777436b0   Stanislav Kinsbursky   nfsd: pass net to...
703
  	err = nfsd_create_serv(net);
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
704
705
  	if (err != 0)
  		return err;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
706
  	err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
78a8d7c8c   Jeff Layton   nfsd: fix error h...
707
  	if (err < 0) {
19f7e2ca4   Stanislav Kinsbursky   NFSd: introduce n...
708
  		nfsd_destroy(net);
78a8d7c8c   Jeff Layton   nfsd: fix error h...
709
710
  		return err;
  	}
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
711

ea068bad2   Chuck Lever   NFSD: move lockd_...
712
  	/* Decrease the count, but don't shut down the service */
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
713
  	nn->nfsd_serv->sv_nrthreads--;
ea068bad2   Chuck Lever   NFSD: move lockd_...
714
  	return err;
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
715
716
717
  }
  
  /*
4eb68c266   Chuck Lever   NFSD: Refactor tr...
718
719
720
   * A transport listener is added by writing it's transport name and
   * a port number.
   */
081603520   Stanislav Kinsbursky   nfsd: pass net to...
721
  static ssize_t __write_ports_addxprt(char *buf, struct net *net)
4eb68c266   Chuck Lever   NFSD: Refactor tr...
722
723
  {
  	char transport[16];
37498292a   Chuck Lever   NFSD: Create PF_I...
724
  	struct svc_xprt *xprt;
4eb68c266   Chuck Lever   NFSD: Refactor tr...
725
  	int port, err;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
726
  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
4eb68c266   Chuck Lever   NFSD: Refactor tr...
727

a10fded18   J. Bruce Fields   nfsd: allow confi...
728
  	if (sscanf(buf, "%15s %5u", transport, &port) != 2)
4eb68c266   Chuck Lever   NFSD: Refactor tr...
729
  		return -EINVAL;
4be929be3   Alexey Dobriyan   kernel-wide: repl...
730
  	if (port < 1 || port > USHRT_MAX)
4eb68c266   Chuck Lever   NFSD: Refactor tr...
731
  		return -EINVAL;
6777436b0   Stanislav Kinsbursky   nfsd: pass net to...
732
  	err = nfsd_create_serv(net);
4eb68c266   Chuck Lever   NFSD: Refactor tr...
733
734
  	if (err != 0)
  		return err;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
735
  	err = svc_create_xprt(nn->nfsd_serv, transport, net,
4eb68c266   Chuck Lever   NFSD: Refactor tr...
736
  				PF_INET, port, SVC_SOCK_ANONYMOUS);
687179081   Chuck Lever   SUNRPC: NFS kerne...
737
  	if (err < 0)
37498292a   Chuck Lever   NFSD: Create PF_I...
738
  		goto out_err;
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
739
  	err = svc_create_xprt(nn->nfsd_serv, transport, net,
37498292a   Chuck Lever   NFSD: Create PF_I...
740
741
742
  				PF_INET6, port, SVC_SOCK_ANONYMOUS);
  	if (err < 0 && err != -EAFNOSUPPORT)
  		goto out_close;
0cd14a061   Jeff Layton   nfsd: fix error h...
743
744
  
  	/* Decrease the count, but don't shut down the service */
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
745
  	nn->nfsd_serv->sv_nrthreads--;
4eb68c266   Chuck Lever   NFSD: Refactor tr...
746
  	return 0;
37498292a   Chuck Lever   NFSD: Create PF_I...
747
  out_close:
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
748
  	xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
37498292a   Chuck Lever   NFSD: Create PF_I...
749
750
751
752
753
  	if (xprt != NULL) {
  		svc_close_xprt(xprt);
  		svc_xprt_put(xprt);
  	}
  out_err:
19f7e2ca4   Stanislav Kinsbursky   NFSd: introduce n...
754
  	nfsd_destroy(net);
37498292a   Chuck Lever   NFSD: Create PF_I...
755
  	return err;
4eb68c266   Chuck Lever   NFSD: Refactor tr...
756
  }
081603520   Stanislav Kinsbursky   nfsd: pass net to...
757
758
  static ssize_t __write_ports(struct file *file, char *buf, size_t size,
  			     struct net *net)
80212d59e   NeilBrown   [PATCH] knfsd: de...
759
  {
0a5372d8a   Chuck Lever   NFSD: Finish refa...
760
  	if (size == 0)
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
761
  		return __write_ports_names(buf, net);
0b7c2f6fc   Chuck Lever   NFSD: Refactor so...
762
763
  
  	if (isdigit(buf[0]))
081603520   Stanislav Kinsbursky   nfsd: pass net to...
764
  		return __write_ports_addfd(buf, net);
82d565919   Chuck Lever   NFSD: Refactor po...
765

4eb68c266   Chuck Lever   NFSD: Refactor tr...
766
  	if (isalpha(buf[0]))
081603520   Stanislav Kinsbursky   nfsd: pass net to...
767
  		return __write_ports_addxprt(buf, net);
4cd5dc751   Chuck Lever   NFSD: Refactor tr...
768

b41b66d63   NeilBrown   [PATCH] knfsd: al...
769
  	return -EINVAL;
80212d59e   NeilBrown   [PATCH] knfsd: de...
770
  }
262a09823   Chuck Lever   NFSD: Add documen...
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  /**
   * write_ports - Pass a socket file descriptor or transport name to listen on
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   * Output:
   *	On success:	passed-in buffer filled with a '
  '-terminated C
   *			string containing a whitespace-separated list of
   *			named NFSD listeners;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   *
   * OR
   *
   * Input:
   *			buf:		C string containing an unsigned
   *					integer value representing a bound
   *					but unconnected socket that is to be
c71206a7b   Chuck Lever   NFSD: Note an add...
791
792
793
   *					used as an NFSD listener; listen(3)
   *					must be called for a SOCK_STREAM
   *					socket, otherwise it is ignored
262a09823   Chuck Lever   NFSD: Add documen...
794
795
796
797
798
799
800
801
802
803
804
805
806
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	NFS service is started;
   *			passed-in buffer filled with a '
  '-terminated C
   *			string containing a unique alphanumeric name of
   *			the listener;
   *			return code is the size in bytes of the string
   *	On error:	return code is a negative errno value
   *
   * OR
   *
   * Input:
262a09823   Chuck Lever   NFSD: Add documen...
807
808
809
810
811
812
813
814
   *			buf:		C string containing a transport
   *					name and an unsigned integer value
   *					representing the port to listen on,
   *					separated by whitespace
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	returns zero; NFS service is started
   *	On error:	return code is a negative errno value
262a09823   Chuck Lever   NFSD: Add documen...
815
   */
bedbdd8ba   Neil Brown   knfsd: Replace lo...
816
817
818
  static ssize_t write_ports(struct file *file, char *buf, size_t size)
  {
  	ssize_t rv;
3dd98a3bc   Jeff Layton   knfsd: clean up n...
819

bedbdd8ba   Neil Brown   knfsd: Replace lo...
820
  	mutex_lock(&nfsd_mutex);
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
821
  	rv = __write_ports(file, buf, size, netns(file));
bedbdd8ba   Neil Brown   knfsd: Replace lo...
822
823
824
  	mutex_unlock(&nfsd_mutex);
  	return rv;
  }
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
825
  int nfsd_max_blksize;
262a09823   Chuck Lever   NFSD: Add documen...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
  /**
   * write_maxblksize - Set or report the current NFS blksize
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   *
   * OR
   *
   * Input:
   * 			buf:		C string containing an unsigned
   * 					integer value representing the new
   * 					NFS blksize
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C string
   *			containing numeric value of the current NFS blksize
   *			setting;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
848
849
850
  static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
  {
  	char *mesg = buf;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
851
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
852

596bbe53e   NeilBrown   [PATCH] knfsd: Al...
853
854
855
856
857
858
859
860
  	if (size > 0) {
  		int bsize;
  		int rv = get_int(&mesg, &bsize);
  		if (rv)
  			return rv;
  		/* force bsize into allowed range and
  		 * required alignment.
  		 */
3c7aa15d2   Kinglong Mee   NFSD: Using min/m...
861
862
  		bsize = max_t(int, bsize, 1024);
  		bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE);
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
863
  		bsize &= ~(1024-1);
bedbdd8ba   Neil Brown   knfsd: Replace lo...
864
  		mutex_lock(&nfsd_mutex);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
865
  		if (nn->nfsd_serv) {
bedbdd8ba   Neil Brown   knfsd: Replace lo...
866
  			mutex_unlock(&nfsd_mutex);
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
867
868
869
  			return -EBUSY;
  		}
  		nfsd_max_blksize = bsize;
bedbdd8ba   Neil Brown   knfsd: Replace lo...
870
  		mutex_unlock(&nfsd_mutex);
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
871
  	}
e06b64050   Chuck Lever   NFSD: Stricter bu...
872
873
874
875
  
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d
  ",
  							nfsd_max_blksize);
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
876
  }
5b8db00ba   Jeff Layton   nfsd: add a new /...
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
  /**
   * write_maxconn - Set or report the current max number of connections
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   * OR
   *
   * Input:
   * 			buf:		C string containing an unsigned
   * 					integer value representing the new
   * 					number of max connections
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C string
   *			containing numeric value of max_connections setting
   *			for this net namespace;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
  static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
  {
  	char *mesg = buf;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
901
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
5b8db00ba   Jeff Layton   nfsd: add a new /...
902
903
904
905
906
907
908
909
910
911
912
913
914
  	unsigned int maxconn = nn->max_connections;
  
  	if (size > 0) {
  		int rv = get_uint(&mesg, &maxconn);
  
  		if (rv)
  			return rv;
  		nn->max_connections = maxconn;
  	}
  
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u
  ", maxconn);
  }
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
915
  #ifdef CONFIG_NFSD_V4
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
916
917
  static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
  				  time_t *time, struct nfsd_net *nn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  	char *mesg = buf;
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
920
  	int rv, i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
922
  
  	if (size > 0) {
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
923
  		if (nn->nfsd_serv)
3dd98a3bc   Jeff Layton   knfsd: clean up n...
924
  			return -EBUSY;
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
925
  		rv = get_int(&mesg, &i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
927
  		if (rv)
  			return rv;
e7b184f19   J. Bruce Fields   nfsd4: document l...
928
929
930
931
932
933
934
935
936
937
938
939
  		/*
  		 * Some sanity checking.  We don't have a reason for
  		 * these particular numbers, but problems with the
  		 * extremes are:
  		 *	- Too short: the briefest network outage may
  		 *	  cause clients to lose all their locks.  Also,
  		 *	  the frequent polling may be wasteful.
  		 *	- Too long: do you really want reboot recovery
  		 *	  to take more than an hour?  Or to make other
  		 *	  clients wait an hour before being able to
  		 *	  revoke a dead client's locks?
  		 */
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
940
  		if (i < 10 || i > 3600)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
  			return -EINVAL;
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
942
  		*time = i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  	}
e06b64050   Chuck Lever   NFSD: Stricter bu...
944

f01357401   J. Bruce Fields   nfsd4: reshuffle ...
945
946
947
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld
  ", *time);
  }
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
948
949
  static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
  				time_t *time, struct nfsd_net *nn)
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
950
951
952
953
  {
  	ssize_t rv;
  
  	mutex_lock(&nfsd_mutex);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
954
  	rv = __nfsd4_write_time(file, buf, size, time, nn);
f01357401   J. Bruce Fields   nfsd4: reshuffle ...
955
956
  	mutex_unlock(&nfsd_mutex);
  	return rv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
957
  }
262a09823   Chuck Lever   NFSD: Add documen...
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
  /**
   * write_leasetime - Set or report the current NFSv4 lease time
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   *
   * OR
   *
   * Input:
   *			buf:		C string containing an unsigned
   *					integer value representing the new
   *					NFSv4 lease expiry time
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C
   *			string containing unsigned integer value of the
   *			current lease expiry time;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
3dd98a3bc   Jeff Layton   knfsd: clean up n...
980
981
  static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
  {
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
982
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
983
  	return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
3dd98a3bc   Jeff Layton   knfsd: clean up n...
984
  }
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
985
986
987
988
989
990
991
992
993
994
995
996
  /**
   * write_gracetime - Set or report current NFSv4 grace period time
   *
   * As above, but sets the time of the NFSv4 grace period.
   *
   * Note this should never be set to less than the *previous*
   * lease-period time, but we don't try to enforce this.  (In the common
   * case (a new boot), we don't know what the previous lease time was
   * anyway.)
   */
  static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
  {
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
997
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
998
  	return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
999
  }
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
1000
1001
  static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
  				   struct nfsd_net *nn)
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1002
1003
1004
1005
  {
  	char *mesg = buf;
  	char *recdir;
  	int len, status;
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1006
  	if (size > 0) {
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
1007
  		if (nn->nfsd_serv)
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1008
1009
1010
1011
1012
  			return -EBUSY;
  		if (size > PATH_MAX || buf[size-1] != '
  ')
  			return -EINVAL;
  		buf[size-1] = 0;
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1013

3dd98a3bc   Jeff Layton   knfsd: clean up n...
1014
1015
1016
1017
  		recdir = mesg;
  		len = qword_get(&mesg, recdir, size);
  		if (len <= 0)
  			return -EINVAL;
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1018

3dd98a3bc   Jeff Layton   knfsd: clean up n...
1019
  		status = nfs4_reset_recoverydir(recdir);
690499610   Andi Kleen   gcc-4.6: nfsd: fi...
1020
1021
  		if (status)
  			return status;
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1022
  	}
3d72ab8fd   Chuck Lever   NFSD: Stricter bu...
1023
1024
1025
1026
  
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s
  ",
  							nfs4_recoverydir());
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1027
  }
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1028

262a09823   Chuck Lever   NFSD: Add documen...
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
  /**
   * write_recoverydir - Set or report the pathname of the recovery directory
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   *
   * OR
   *
   * Input:
   *			buf:		C string containing the pathname
   *					of the directory on a local file
   *					system containing permanent NFSv4
   *					recovery data
   *			size:		non-zero length of C string in @buf
   * Output:
   *	On success:	passed-in buffer filled with '
  '-terminated C string
   *			containing the current recovery pathname setting;
   *			return code is the size in bytes of the string
   *	On error:	return code is zero or a negative errno value
   */
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1051
1052
1053
  static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
  {
  	ssize_t rv;
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
1054
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1055
1056
  
  	mutex_lock(&nfsd_mutex);
9dd9845f0   Stanislav Kinsbursky   nfsd: make NFSd s...
1057
  	rv = __write_recoverydir(file, buf, size, nn);
3dd98a3bc   Jeff Layton   knfsd: clean up n...
1058
1059
1060
  	mutex_unlock(&nfsd_mutex);
  	return rv;
  }
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
  /**
   * write_v4_end_grace - release grace period for nfsd's v4.x lock manager
   *
   * Input:
   *			buf:		ignored
   *			size:		zero
   * OR
   *
   * Input:
   * 			buf:		any value
   *			size:		non-zero length of C string in @buf
   * Output:
   *			passed-in buffer filled with "Y" or "N" with a newline
   *			and NULL-terminated C string. This indicates whether
   *			the grace period has ended in the current net
   *			namespace. Return code is the size in bytes of the
   *			string. Writing a string that starts with 'Y', 'y', or
   *			'1' to the file will end the grace period for nfsd's v4
   *			lock manager.
   */
  static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
  {
244c7d444   Al Viro   nfsd/nfsctl.c: ne...
1083
  	struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  
  	if (size > 0) {
  		switch(buf[0]) {
  		case 'Y':
  		case 'y':
  		case '1':
  			nfsd4_end_grace(nn);
  			break;
  		default:
  			return -EINVAL;
  		}
  	}
  
  	return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%c
  ",
  			 nn->grace_ended ? 'Y' : 'N');
  }
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
1101
  #endif
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1102

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1103
1104
1105
1106
1107
1108
1109
1110
  /*----------------------------------------------------------------------------*/
  /*
   *	populating the filesystem.
   */
  
  static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
  {
  	static struct tree_descr nfsd_files[] = {
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
1111
  		[NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
e8e8753f7   J. Bruce Fields   nfsd: new interfa...
1112
1113
  		[NFSD_Export_features] = {"export_features",
  					&export_features_operations, S_IRUGO},
4373ea84c   Wendy Cheng   lockd: unlock loc...
1114
1115
  		[NFSD_FO_UnlockIP] = {"unlock_ip",
  					&transaction_ops, S_IWUSR|S_IRUSR},
17efa372c   Wendy Cheng   lockd: unlock loc...
1116
1117
  		[NFSD_FO_UnlockFS] = {"unlock_filesystem",
  					&transaction_ops, S_IWUSR|S_IRUSR},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118
1119
  		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
  		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
eed2965af   Greg Banks   [PATCH] knfsd: al...
1120
  		[NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
03cf6c9f4   Greg Banks   knfsd: add file t...
1121
  		[NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
a2f999a37   Jeff Layton   nfsd: add new rep...
1122
  		[NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
70c3b76c2   NeilBrown   [PATCH] knfsd: Al...
1123
  		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
80212d59e   NeilBrown   [PATCH] knfsd: de...
1124
  		[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
596bbe53e   NeilBrown   [PATCH] knfsd: Al...
1125
  		[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
5b8db00ba   Jeff Layton   nfsd: add a new /...
1126
  		[NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO},
b084f598d   J. Bruce Fields   nfsd: fix depende...
1127
  #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
b0b0c0a26   Kevin Coffman   nfsd: add proc fi...
1128
  		[NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
b084f598d   J. Bruce Fields   nfsd: fix depende...
1129
  #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
  #ifdef CONFIG_NFSD_V4
  		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
efc4bb4fd   J. Bruce Fields   nfsd4: allow sett...
1132
  		[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
0964a3d3f   NeilBrown   [PATCH] knfsd: nf...
1133
  		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
7f5ef2e90   Jeff Layton   nfsd: add a v4_en...
1134
  		[NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
1136
1137
  #endif
  		/* last one */ {""}
  	};
d91ee87d8   Eric W. Biederman   vfs: Pass data, n...
1138
1139
  	get_net(sb->s_fs_info);
  	return simple_fill_super(sb, 0x6e667364, nfsd_files);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1140
  }
fc14f2fef   Al Viro   convert get_sb_si...
1141
1142
  static struct dentry *nfsd_mount(struct file_system_type *fs_type,
  	int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
  {
d91ee87d8   Eric W. Biederman   vfs: Pass data, n...
1144
1145
  	struct net *net = current->nsproxy->net_ns;
  	return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super);
11f779421   Stanislav Kinsbursky   nfsd: containeriz...
1146
1147
1148
1149
1150
1151
1152
1153
  }
  
  static void nfsd_umount(struct super_block *sb)
  {
  	struct net *net = sb->s_fs_info;
  
  	kill_litter_super(sb);
  	put_net(net);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1154
1155
1156
1157
1158
  }
  
  static struct file_system_type nfsd_fs_type = {
  	.owner		= THIS_MODULE,
  	.name		= "nfsd",
fc14f2fef   Al Viro   convert get_sb_si...
1159
  	.mount		= nfsd_mount,
11f779421   Stanislav Kinsbursky   nfsd: containeriz...
1160
  	.kill_sb	= nfsd_umount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1161
  };
7f78e0351   Eric W. Biederman   fs: Limit sys_mou...
1162
  MODULE_ALIAS_FS("nfsd");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1163

e331f606a   J. Bruce Fields   nfsd: fail init o...
1164
1165
1166
1167
1168
1169
1170
1171
  #ifdef CONFIG_PROC_FS
  static int create_proc_exports_entry(void)
  {
  	struct proc_dir_entry *entry;
  
  	entry = proc_mkdir("fs/nfs", NULL);
  	if (!entry)
  		return -ENOMEM;
96d851c4d   Stanislav Kinsbursky   nfsd: use proper ...
1172
1173
  	entry = proc_create("exports", 0, entry,
  				 &exports_proc_operations);
ff7c4b369   fanchaoting   nfsd: remove /pro...
1174
1175
  	if (!entry) {
  		remove_proc_entry("fs/nfs", NULL);
e331f606a   J. Bruce Fields   nfsd: fail init o...
1176
  		return -ENOMEM;
ff7c4b369   fanchaoting   nfsd: remove /pro...
1177
  	}
e331f606a   J. Bruce Fields   nfsd: fail init o...
1178
1179
1180
1181
1182
1183
1184
1185
  	return 0;
  }
  #else /* CONFIG_PROC_FS */
  static int create_proc_exports_entry(void)
  {
  	return 0;
  }
  #endif
7ea34ac15   Jeff Layton   nfsd: add a per-n...
1186
  int nfsd_net_id;
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1187
1188
1189
1190
  
  static __net_init int nfsd_init_net(struct net *net)
  {
  	int retval;
3d7337115   Stanislav Kinsbursky   nfsd: make NFSv4 ...
1191
  	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1192
1193
1194
1195
  
  	retval = nfsd_export_init(net);
  	if (retval)
  		goto out_export_error;
f69adb2fe   Stanislav Kinsbursky   nfsd: allocate id...
1196
1197
1198
  	retval = nfsd_idmap_init(net);
  	if (retval)
  		goto out_idmap_error;
3d7337115   Stanislav Kinsbursky   nfsd: make NFSv4 ...
1199
  	nn->nfsd4_lease = 90;	/* default lease time */
5284b44e4   Stanislav Kinsbursky   nfsd: make NFSv4 ...
1200
  	nn->nfsd4_grace = 90;
ebd7c72c6   J. Bruce Fields   nfsd: randomize S...
1201
1202
  	nn->clverifier_counter = prandom_u32();
  	nn->clientid_counter = prandom_u32();
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1203
  	return 0;
f69adb2fe   Stanislav Kinsbursky   nfsd: allocate id...
1204
1205
  out_idmap_error:
  	nfsd_export_shutdown(net);
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1206
1207
1208
1209
1210
1211
  out_export_error:
  	return retval;
  }
  
  static __net_exit void nfsd_exit_net(struct net *net)
  {
f69adb2fe   Stanislav Kinsbursky   nfsd: allocate id...
1212
  	nfsd_idmap_shutdown(net);
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1213
1214
  	nfsd_export_shutdown(net);
  }
7ea34ac15   Jeff Layton   nfsd: add a per-n...
1215
  static struct pernet_operations nfsd_net_ops = {
5717e0128   Stanislav Kinsbursky   nfsd: allocate ex...
1216
1217
  	.init = nfsd_init_net,
  	.exit = nfsd_exit_net,
7ea34ac15   Jeff Layton   nfsd: add a per-n...
1218
1219
1220
  	.id   = &nfsd_net_id,
  	.size = sizeof(struct nfsd_net),
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
1222
1223
1224
1225
  static int __init init_nfsd(void)
  {
  	int retval;
  	printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
  ");
7ea34ac15   Jeff Layton   nfsd: add a per-n...
1226
1227
  	retval = register_pernet_subsys(&nfsd_net_ops);
  	if (retval < 0)
bb7ffbf29   Giuseppe Cantavenera   nfsd: fix nsfd st...
1228
1229
  		return retval;
  	retval = register_cld_notifier();
e8ff2a845   J. Bruce Fields   knfsd: move nfsv4...
1230
  	if (retval)
7ea34ac15   Jeff Layton   nfsd: add a per-n...
1231
  		goto out_unregister_pernet;
bb7ffbf29   Giuseppe Cantavenera   nfsd: fix nsfd st...
1232
1233
1234
  	retval = nfsd4_init_slabs();
  	if (retval)
  		goto out_unregister_notifier;
9cf514ccf   Christoph Hellwig   nfsd: implement p...
1235
  	retval = nfsd4_init_pnfs();
65178db42   Bryan Schumaker   NFSD: Added fault...
1236
1237
  	if (retval)
  		goto out_free_slabs;
9cf514ccf   Christoph Hellwig   nfsd: implement p...
1238
1239
1240
  	retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */
  	if (retval)
  		goto out_exit_pnfs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1241
  	nfsd_stat_init();	/* Statistics */
d5c3428b2   J. Bruce Fields   nfsd: fail module...
1242
1243
1244
  	retval = nfsd_reply_cache_init();
  	if (retval)
  		goto out_free_stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
  	nfsd_lockd_init();	/* lockd->nfsd callbacks */
e331f606a   J. Bruce Fields   nfsd: fail init o...
1246
1247
  	retval = create_proc_exports_entry();
  	if (retval)
f69adb2fe   Stanislav Kinsbursky   nfsd: allocate id...
1248
  		goto out_free_lockd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  	retval = register_filesystem(&nfsd_fs_type);
26808d3f1   J. Bruce Fields   nfsd: cleanup nfs...
1250
1251
1252
1253
  	if (retval)
  		goto out_free_all;
  	return 0;
  out_free_all:
26808d3f1   J. Bruce Fields   nfsd: cleanup nfs...
1254
1255
  	remove_proc_entry("fs/nfs/exports", NULL);
  	remove_proc_entry("fs/nfs", NULL);
dbf847ecb   J. Bruce Fields   knfsd: allow cach...
1256
  out_free_lockd:
26808d3f1   J. Bruce Fields   nfsd: cleanup nfs...
1257
  	nfsd_lockd_shutdown();
e331f606a   J. Bruce Fields   nfsd: fail init o...
1258
  	nfsd_reply_cache_shutdown();
d5c3428b2   J. Bruce Fields   nfsd: fail module...
1259
1260
  out_free_stat:
  	nfsd_stat_shutdown();
65178db42   Bryan Schumaker   NFSD: Added fault...
1261
  	nfsd_fault_inject_cleanup();
9cf514ccf   Christoph Hellwig   nfsd: implement p...
1262
1263
  out_exit_pnfs:
  	nfsd4_exit_pnfs();
65178db42   Bryan Schumaker   NFSD: Added fault...
1264
  out_free_slabs:
26808d3f1   J. Bruce Fields   nfsd: cleanup nfs...
1265
  	nfsd4_free_slabs();
813fd320c   Jeff Layton   nfsd: add notifie...
1266
  out_unregister_notifier:
797a9d797   Jeff Layton   nfsd: only regist...
1267
  	unregister_cld_notifier();
bb7ffbf29   Giuseppe Cantavenera   nfsd: fix nsfd st...
1268
1269
  out_unregister_pernet:
  	unregister_pernet_subsys(&nfsd_net_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1270
1271
1272
1273
1274
  	return retval;
  }
  
  static void __exit exit_nfsd(void)
  {
d5c3428b2   J. Bruce Fields   nfsd: fail module...
1275
  	nfsd_reply_cache_shutdown();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
1277
1278
1279
  	remove_proc_entry("fs/nfs/exports", NULL);
  	remove_proc_entry("fs/nfs", NULL);
  	nfsd_stat_shutdown();
  	nfsd_lockd_shutdown();
e8ff2a845   J. Bruce Fields   knfsd: move nfsv4...
1280
  	nfsd4_free_slabs();
9cf514ccf   Christoph Hellwig   nfsd: implement p...
1281
  	nfsd4_exit_pnfs();
65178db42   Bryan Schumaker   NFSD: Added fault...
1282
  	nfsd_fault_inject_cleanup();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
  	unregister_filesystem(&nfsd_fs_type);
797a9d797   Jeff Layton   nfsd: only regist...
1284
  	unregister_cld_notifier();
bb7ffbf29   Giuseppe Cantavenera   nfsd: fix nsfd st...
1285
  	unregister_pernet_subsys(&nfsd_net_ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
1287
1288
1289
1290
1291
  }
  
  MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
  MODULE_LICENSE("GPL");
  module_init(init_nfsd)
  module_exit(exit_nfsd)