Blame view
fs/nfsd/nfsctl.c
33.5 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 |
* Syscall interface to knfsd. * * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */ |
5a0e3ad6a include cleanup: ... |
6 |
#include <linux/slab.h> |
3f8206d49 [PATCH] get rid o... |
7 |
#include <linux/namei.h> |
b41b66d63 [PATCH] knfsd: al... |
8 |
#include <linux/ctype.h> |
1da177e4c Linux-2.6.12-rc2 |
9 |
|
80212d59e [PATCH] knfsd: de... |
10 |
#include <linux/sunrpc/svcsock.h> |
4373ea84c lockd: unlock loc... |
11 |
#include <linux/lockd/lockd.h> |
5976687a2 sunrpc: move addr... |
12 |
#include <linux/sunrpc/addr.h> |
b0b0c0a26 nfsd: add proc fi... |
13 |
#include <linux/sunrpc/gss_api.h> |
b084f598d nfsd: fix depende... |
14 |
#include <linux/sunrpc/gss_krb5_enctypes.h> |
813fd320c nfsd: add notifie... |
15 |
#include <linux/sunrpc/rpc_pipe_fs.h> |
143cb494c fs: add module.h ... |
16 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
|
2ca72e17e nfsd4: move idmap... |
18 |
#include "idmap.h" |
9a74af213 nfsd: Move privat... |
19 20 |
#include "nfsd.h" #include "cache.h" |
f3c7521fe NFSD: Fold fault_... |
21 |
#include "state.h" |
7ea34ac15 nfsd: add a per-n... |
22 |
#include "netns.h" |
9cf514ccf nfsd: implement p... |
23 |
#include "pnfs.h" |
9a74af213 nfsd: Move privat... |
24 |
|
1da177e4c Linux-2.6.12-rc2 |
25 |
/* |
b0b0c0a26 nfsd: add proc fi... |
26 |
* We have a single directory with several nodes in it. |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 |
*/ enum { NFSD_Root = 1, |
1da177e4c Linux-2.6.12-rc2 |
30 |
NFSD_List, |
e8e8753f7 nfsd: new interfa... |
31 |
NFSD_Export_features, |
1da177e4c Linux-2.6.12-rc2 |
32 |
NFSD_Fh, |
4373ea84c lockd: unlock loc... |
33 |
NFSD_FO_UnlockIP, |
17efa372c lockd: unlock loc... |
34 |
NFSD_FO_UnlockFS, |
1da177e4c Linux-2.6.12-rc2 |
35 |
NFSD_Threads, |
eed2965af [PATCH] knfsd: al... |
36 |
NFSD_Pool_Threads, |
03cf6c9f4 knfsd: add file t... |
37 |
NFSD_Pool_Stats, |
a2f999a37 nfsd: add new rep... |
38 |
NFSD_Reply_Cache_Stats, |
70c3b76c2 [PATCH] knfsd: Al... |
39 |
NFSD_Versions, |
80212d59e [PATCH] knfsd: de... |
40 |
NFSD_Ports, |
596bbe53e [PATCH] knfsd: Al... |
41 |
NFSD_MaxBlkSize, |
5b8db00ba nfsd: add a new /... |
42 |
NFSD_MaxConnections, |
b0b0c0a26 nfsd: add proc fi... |
43 |
NFSD_SupportedEnctypes, |
70c3b76c2 [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 Linux-2.6.12-rc2 |
49 |
NFSD_Leasetime, |
efc4bb4fd nfsd4: allow sett... |
50 |
NFSD_Gracetime, |
0964a3d3f [PATCH] knfsd: nf... |
51 |
NFSD_RecoveryDir, |
7f5ef2e90 nfsd: add a v4_en... |
52 |
NFSD_V4EndGrace, |
70c3b76c2 [PATCH] knfsd: Al... |
53 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
54 55 56 57 58 |
}; /* * write() for these nodes. */ |
1da177e4c Linux-2.6.12-rc2 |
59 |
static ssize_t write_filehandle(struct file *file, char *buf, size_t size); |
b046ccdc1 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 Linux-2.6.12-rc2 |
62 |
static ssize_t write_threads(struct file *file, char *buf, size_t size); |
eed2965af [PATCH] knfsd: al... |
63 |
static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); |
70c3b76c2 [PATCH] knfsd: Al... |
64 |
static ssize_t write_versions(struct file *file, char *buf, size_t size); |
80212d59e [PATCH] knfsd: de... |
65 |
static ssize_t write_ports(struct file *file, char *buf, size_t size); |
596bbe53e [PATCH] knfsd: Al... |
66 |
static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); |
5b8db00ba nfsd: add a new /... |
67 |
static ssize_t write_maxconn(struct file *file, char *buf, size_t size); |
70c3b76c2 [PATCH] knfsd: Al... |
68 |
#ifdef CONFIG_NFSD_V4 |
1da177e4c Linux-2.6.12-rc2 |
69 |
static ssize_t write_leasetime(struct file *file, char *buf, size_t size); |
efc4bb4fd nfsd4: allow sett... |
70 |
static ssize_t write_gracetime(struct file *file, char *buf, size_t size); |
0964a3d3f [PATCH] knfsd: nf... |
71 |
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); |
7f5ef2e90 nfsd: add a v4_en... |
72 |
static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size); |
70c3b76c2 [PATCH] knfsd: Al... |
73 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
74 75 |
static ssize_t (*write_op[])(struct file *, char *, size_t) = { |
1da177e4c Linux-2.6.12-rc2 |
76 |
[NFSD_Fh] = write_filehandle, |
b046ccdc1 NFSD: clean up fa... |
77 78 |
[NFSD_FO_UnlockIP] = write_unlock_ip, [NFSD_FO_UnlockFS] = write_unlock_fs, |
1da177e4c Linux-2.6.12-rc2 |
79 |
[NFSD_Threads] = write_threads, |
eed2965af [PATCH] knfsd: al... |
80 |
[NFSD_Pool_Threads] = write_pool_threads, |
70c3b76c2 [PATCH] knfsd: Al... |
81 |
[NFSD_Versions] = write_versions, |
80212d59e [PATCH] knfsd: de... |
82 |
[NFSD_Ports] = write_ports, |
596bbe53e [PATCH] knfsd: Al... |
83 |
[NFSD_MaxBlkSize] = write_maxblksize, |
5b8db00ba nfsd: add a new /... |
84 |
[NFSD_MaxConnections] = write_maxconn, |
70c3b76c2 [PATCH] knfsd: Al... |
85 |
#ifdef CONFIG_NFSD_V4 |
1da177e4c Linux-2.6.12-rc2 |
86 |
[NFSD_Leasetime] = write_leasetime, |
efc4bb4fd nfsd4: allow sett... |
87 |
[NFSD_Gracetime] = write_gracetime, |
0964a3d3f [PATCH] knfsd: nf... |
88 |
[NFSD_RecoveryDir] = write_recoverydir, |
7f5ef2e90 nfsd: add a v4_en... |
89 |
[NFSD_V4EndGrace] = write_v4_end_grace, |
70c3b76c2 [PATCH] knfsd: Al... |
90 |
#endif |
1da177e4c 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 new helper: file_... |
95 |
ino_t ino = file_inode(file)->i_ino; |
1da177e4c Linux-2.6.12-rc2 |
96 97 |
char *data; ssize_t rv; |
e8c96f8c2 [PATCH] fs: Use A... |
98 |
if (ino >= ARRAY_SIZE(write_op) || !write_op[ino]) |
1da177e4c 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 [PATCH] knfsd: fi... |
106 |
if (rv >= 0) { |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 110 111 |
simple_transaction_set(file, rv); rv = size; } return rv; } |
7390022d6 [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 [PATCH] Make most... |
125 |
static const struct file_operations transaction_ops = { |
1da177e4c Linux-2.6.12-rc2 |
126 |
.write = nfsctl_transaction_write, |
7390022d6 [PATCH] knfsd: Re... |
127 |
.read = nfsctl_transaction_read, |
1da177e4c Linux-2.6.12-rc2 |
128 |
.release = simple_transaction_release, |
6038f373a llseek: automatic... |
129 |
.llseek = default_llseek, |
1da177e4c Linux-2.6.12-rc2 |
130 |
}; |
96d851c4d nfsd: use proper ... |
131 |
static int exports_net_open(struct net *net, struct file *file) |
1da177e4c Linux-2.6.12-rc2 |
132 |
{ |
f2c7ea10f nfsd: pass svc_ex... |
133 134 |
int err; struct seq_file *seq; |
96d851c4d nfsd: use proper ... |
135 |
struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
f2c7ea10f 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 nfsd: make expkey... |
142 |
seq->private = nn->svc_export_cache; |
f2c7ea10f nfsd: pass svc_ex... |
143 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
144 |
} |
96d851c4d 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 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 Linux-2.6.12-rc2 |
164 165 166 167 |
.read = seq_read, .llseek = seq_lseek, .release = seq_release, }; |
e8e8753f7 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 constify a bunch ... |
179 |
static const struct file_operations export_features_operations = { |
e8e8753f7 nfsd: new interfa... |
180 181 182 183 184 |
.open = export_features_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
b084f598d nfsd: fix depende... |
185 |
#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) |
b0b0c0a26 nfsd: add proc fi... |
186 187 |
static int supported_enctypes_show(struct seq_file *m, void *v) { |
b084f598d nfsd: fix depende... |
188 |
seq_printf(m, KRB5_SUPPORTED_ENCTYPES); |
b0b0c0a26 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 constify a bunch ... |
196 |
static const struct file_operations supported_enctypes_ops = { |
b0b0c0a26 nfsd: add proc fi... |
197 198 199 200 201 |
.open = supported_enctypes_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
b084f598d nfsd: fix depende... |
202 |
#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ |
b0b0c0a26 nfsd: add proc fi... |
203 |
|
828c09509 const: constify r... |
204 |
static const struct file_operations pool_stats_operations = { |
03cf6c9f4 knfsd: add file t... |
205 206 207 |
.open = nfsd_pool_stats_open, .read = seq_read, .llseek = seq_lseek, |
ed2d8aed5 knfsd: Replace lo... |
208 |
.release = nfsd_pool_stats_release, |
03cf6c9f4 knfsd: add file t... |
209 |
}; |
7ba630f54 nfsd: constify re... |
210 |
static const struct file_operations reply_cache_stats_operations = { |
a2f999a37 nfsd: add new rep... |
211 212 213 214 215 |
.open = nfsd_reply_cache_stats_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 |
/*----------------------------------------------------------------------------*/ /* * payload - write methods |
1da177e4c Linux-2.6.12-rc2 |
219 |
*/ |
244c7d444 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 Linux-2.6.12-rc2 |
224 |
|
262a09823 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 NFSD: Support IPv... |
233 |
* presentation format IP address |
262a09823 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 NFSD: Add documen... |
239 |
*/ |
b046ccdc1 NFSD: clean up fa... |
240 |
static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size) |
4373ea84c lockd: unlock loc... |
241 |
{ |
4116092b9 NFSD: Support IPv... |
242 243 244 |
struct sockaddr_storage address; struct sockaddr *sap = (struct sockaddr *)&address; size_t salen = sizeof(address); |
367c8c7bd lockd: Pass "stru... |
245 |
char *fo_path; |
244c7d444 nfsd/nfsctl.c: ne... |
246 |
struct net *net = netns(file); |
4373ea84c 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 nfsd: containeriz... |
259 |
if (rpc_pton(net, fo_path, size, sap, salen) == 0) |
4373ea84c lockd: unlock loc... |
260 |
return -EINVAL; |
4373ea84c lockd: unlock loc... |
261 |
|
4116092b9 NFSD: Support IPv... |
262 |
return nlmsvc_unlock_all_by_ip(sap); |
4373ea84c lockd: unlock loc... |
263 |
} |
262a09823 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 NFSD: clean up fa... |
279 |
static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size) |
17efa372c lockd: unlock loc... |
280 |
{ |
a63bb9966 [PATCH] switch nf... |
281 |
struct path path; |
17efa372c 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 [PATCH] switch nf... |
296 |
error = kern_path(fo_path, 0, &path); |
17efa372c lockd: unlock loc... |
297 298 |
if (error) return error; |
262a09823 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 vfs: prefer ->den... |
308 |
error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb); |
17efa372c lockd: unlock loc... |
309 |
|
a63bb9966 [PATCH] switch nf... |
310 |
path_put(&path); |
17efa372c lockd: unlock loc... |
311 312 |
return error; } |
262a09823 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 Linux-2.6.12-rc2 |
336 337 |
static ssize_t write_filehandle(struct file *file, char *buf, size_t size) { |
1da177e4c Linux-2.6.12-rc2 |
338 |
char *dname, *path; |
246d95ba0 nfsd warning fix |
339 |
int uninitialized_var(maxsize); |
1da177e4c Linux-2.6.12-rc2 |
340 341 342 343 |
char *mesg = buf; int len; struct auth_domain *dom; struct knfsd_fh fh; |
87d26ea77 nfsd: more carefu... |
344 345 |
if (size == 0) return -EINVAL; |
1da177e4c 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 NFSD: Fix a handf... |
353 354 |
if (len <= 0) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
355 356 357 |
path = dname+len+1; len = qword_get(&mesg, path, size); |
54224f04a NFSD: Fix a handf... |
358 359 |
if (len <= 0) return -EINVAL; |
1da177e4c 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 NFSD: Using min/m... |
367 |
maxsize = min(maxsize, NFS3_FHSIZE); |
1da177e4c 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 nfsd/nfsctl.c: ne... |
376 |
len = exp_rootfh(netns(file), dom, path, &fh, maxsize); |
1da177e4c Linux-2.6.12-rc2 |
377 378 379 380 |
auth_domain_put(dom); if (len) return len; |
54224f04a NFSD: Fix a handf... |
381 382 |
mesg = buf; len = SIMPLE_TRANSACTION_LIMIT; |
1da177e4c 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 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 Linux-2.6.12-rc2 |
418 419 |
static ssize_t write_threads(struct file *file, char *buf, size_t size) { |
1da177e4c Linux-2.6.12-rc2 |
420 421 |
char *mesg = buf; int rv; |
244c7d444 nfsd/nfsctl.c: ne... |
422 |
struct net *net = netns(file); |
d41a9417c nfsd: pass net to... |
423 |
|
1da177e4c 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 NFSD: Replace ope... |
429 |
if (newthreads < 0) |
1da177e4c Linux-2.6.12-rc2 |
430 |
return -EINVAL; |
d41a9417c nfsd: pass net to... |
431 |
rv = nfsd_svc(newthreads, net); |
82e12fe92 nfsd: don't take ... |
432 |
if (rv < 0) |
1da177e4c Linux-2.6.12-rc2 |
433 |
return rv; |
82e12fe92 nfsd: don't take ... |
434 |
} else |
9dd9845f0 nfsd: make NFSd s... |
435 |
rv = nfsd_nrthreads(net); |
e06b64050 NFSD: Stricter bu... |
436 |
|
82e12fe92 nfsd: don't take ... |
437 438 |
return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d ", rv); |
1da177e4c Linux-2.6.12-rc2 |
439 |
} |
262a09823 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 [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 knfsd: Replace lo... |
472 |
int npools; |
eed2965af [PATCH] knfsd: al... |
473 |
int *nthreads; |
244c7d444 nfsd/nfsctl.c: ne... |
474 |
struct net *net = netns(file); |
eed2965af [PATCH] knfsd: al... |
475 |
|
bedbdd8ba knfsd: Replace lo... |
476 |
mutex_lock(&nfsd_mutex); |
9dd9845f0 nfsd: make NFSd s... |
477 |
npools = nfsd_nrpools(net); |
eed2965af [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 knfsd: Replace lo... |
484 |
mutex_unlock(&nfsd_mutex); |
eed2965af [PATCH] knfsd: al... |
485 486 487 488 489 490 |
strcpy(buf, "0 "); return strlen(buf); } nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); |
bedbdd8ba knfsd: Replace lo... |
491 |
rv = -ENOMEM; |
eed2965af [PATCH] knfsd: al... |
492 |
if (nthreads == NULL) |
bedbdd8ba knfsd: Replace lo... |
493 |
goto out_free; |
eed2965af [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 nfsd: pass net to... |
506 |
rv = nfsd_set_nrthreads(i, nthreads, net); |
eed2965af [PATCH] knfsd: al... |
507 508 509 |
if (rv) goto out_free; } |
9dd9845f0 nfsd: make NFSd s... |
510 |
rv = nfsd_get_nrthreads(npools, nthreads, net); |
eed2965af [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 nfsd: minor write... |
523 |
rv = mesg - buf; |
eed2965af [PATCH] knfsd: al... |
524 525 |
out_free: kfree(nthreads); |
bedbdd8ba knfsd: Replace lo... |
526 |
mutex_unlock(&nfsd_mutex); |
eed2965af [PATCH] knfsd: al... |
527 528 |
return rv; } |
ff7d11797 nfsd: Fix display... |
529 530 |
static ssize_t nfsd_print_version_support(char *buf, int remaining, const char *sep, |
abcb4dacb NFSD: further ref... |
531 |
unsigned vers, int minor) |
ff7d11797 nfsd: Fix display... |
532 |
{ |
abcb4dacb NFSD: further ref... |
533 |
const char *format = minor < 0 ? "%s%c%u" : "%s%c%u.%u"; |
ff7d11797 nfsd: Fix display... |
534 |
bool supported = !!nfsd_vers(vers, NFSD_TEST); |
abcb4dacb NFSD: further ref... |
535 536 |
if (vers == 4 && minor >= 0 && !nfsd_minorversion(minor, NFSD_TEST)) |
ff7d11797 nfsd: Fix display... |
537 |
supported = false; |
abcb4dacb NFSD: further ref... |
538 539 540 541 542 543 544 |
if (minor == 0 && supported) /* * special case for backward compatability. * +4.0 is never reported, it is implied by * +4, unless -4.0 is present. */ return 0; |
ff7d11797 nfsd: Fix display... |
545 546 547 |
return snprintf(buf, remaining, format, sep, supported ? '+' : '-', vers, minor); } |
3dd98a3bc knfsd: clean up n... |
548 |
static ssize_t __write_versions(struct file *file, char *buf, size_t size) |
70c3b76c2 [PATCH] knfsd: Al... |
549 |
{ |
70c3b76c2 [PATCH] knfsd: Al... |
550 |
char *mesg = buf; |
8daf220a6 nfsd41: control n... |
551 |
char *vers, *minorp, sign; |
261758b5c NFSD: Stricter bu... |
552 |
int len, num, remaining; |
70c3b76c2 [PATCH] knfsd: Al... |
553 554 |
ssize_t tlen = 0; char *sep; |
244c7d444 nfsd/nfsctl.c: ne... |
555 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
70c3b76c2 [PATCH] knfsd: Al... |
556 557 |
if (size>0) { |
9dd9845f0 nfsd: make NFSd s... |
558 |
if (nn->nfsd_serv) |
6658d3a7b [PATCH] knfsd: re... |
559 |
/* Cannot change versions without updating |
9dd9845f0 nfsd: make NFSd s... |
560 |
* nn->nfsd_serv->sv_xdrsize, and reallocing |
6658d3a7b [PATCH] knfsd: re... |
561 562 |
* rq_argp and rq_resp */ |
70c3b76c2 [PATCH] knfsd: Al... |
563 564 565 566 567 568 569 570 571 572 |
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 { |
d3635ff07 nfsd: fix configu... |
573 |
enum vers_op cmd; |
abcb4dacb NFSD: further ref... |
574 |
unsigned minor; |
70c3b76c2 [PATCH] knfsd: Al... |
575 576 |
sign = *vers; if (sign == '+' || sign == '-') |
8daf220a6 nfsd41: control n... |
577 |
num = simple_strtol((vers+1), &minorp, 0); |
70c3b76c2 [PATCH] knfsd: Al... |
578 |
else |
8daf220a6 nfsd41: control n... |
579 580 |
num = simple_strtol(vers, &minorp, 0); if (*minorp == '.') { |
ff89be87c nfsd4: require ve... |
581 |
if (num != 4) |
8daf220a6 nfsd41: control n... |
582 |
return -EINVAL; |
e35659f1b NFSD: correctly r... |
583 |
if (kstrtouint(minorp+1, 0, &minor) < 0) |
8daf220a6 nfsd41: control n... |
584 |
return -EINVAL; |
abcb4dacb NFSD: further ref... |
585 |
} |
d3635ff07 nfsd: fix configu... |
586 |
cmd = sign == '-' ? NFSD_CLEAR : NFSD_SET; |
70c3b76c2 [PATCH] knfsd: Al... |
587 588 589 |
switch(num) { case 2: case 3: |
d3635ff07 nfsd: fix configu... |
590 |
nfsd_vers(num, cmd); |
70c3b76c2 [PATCH] knfsd: Al... |
591 |
break; |
d3635ff07 nfsd: fix configu... |
592 |
case 4: |
abcb4dacb NFSD: further ref... |
593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
if (*minorp == '.') { if (nfsd_minorversion(minor, cmd) < 0) return -EINVAL; } else if ((cmd == NFSD_SET) != nfsd_vers(num, NFSD_TEST)) { /* * Either we have +4 and no minors are enabled, * or we have -4 and at least one minor is enabled. * In either case, propagate 'cmd' to all minors. */ minor = 0; while (nfsd_minorversion(minor, cmd) >= 0) minor++; } break; |
70c3b76c2 [PATCH] knfsd: Al... |
607 608 609 610 |
default: return -EINVAL; } vers += len + 1; |
70c3b76c2 [PATCH] knfsd: Al... |
611 612 613 614 |
} while ((len = qword_get(&mesg, vers, size)) > 0); /* If all get turned off, turn them back on, as * having no versions is BAD */ |
6658d3a7b [PATCH] knfsd: re... |
615 |
nfsd_reset_versions(); |
70c3b76c2 [PATCH] knfsd: Al... |
616 |
} |
261758b5c NFSD: Stricter bu... |
617 |
|
70c3b76c2 [PATCH] knfsd: Al... |
618 619 620 |
/* Now write current state into reply buffer */ len = 0; sep = ""; |
261758b5c NFSD: Stricter bu... |
621 |
remaining = SIMPLE_TRANSACTION_LIMIT; |
ff7d11797 nfsd: Fix display... |
622 |
for (num=2 ; num <= 4 ; num++) { |
abcb4dacb NFSD: further ref... |
623 |
int minor; |
ff7d11797 nfsd: Fix display... |
624 625 |
if (!nfsd_vers(num, NFSD_AVAIL)) continue; |
abcb4dacb NFSD: further ref... |
626 627 |
minor = -1; |
ff7d11797 nfsd: Fix display... |
628 629 630 |
do { len = nfsd_print_version_support(buf, remaining, sep, num, minor); |
818f2f57f nfsd: minor off b... |
631 |
if (len >= remaining) |
ff7d11797 nfsd: Fix display... |
632 |
goto out; |
261758b5c NFSD: Stricter bu... |
633 634 635 |
remaining -= len; buf += len; tlen += len; |
ff7d11797 nfsd: Fix display... |
636 |
minor++; |
abcb4dacb NFSD: further ref... |
637 638 |
if (len) sep = " "; |
ff7d11797 nfsd: Fix display... |
639 640 641 |
} while (num == 4 && minor <= NFSD_SUPPORTED_MINOR_VERSION); } out: |
261758b5c NFSD: Stricter bu... |
642 643 |
len = snprintf(buf, remaining, " "); |
818f2f57f nfsd: minor off b... |
644 |
if (len >= remaining) |
261758b5c NFSD: Stricter bu... |
645 646 |
return -EINVAL; return tlen + len; |
70c3b76c2 [PATCH] knfsd: Al... |
647 |
} |
262a09823 NFSD: Add documen... |
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 |
/** * 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 knfsd: clean up n... |
682 683 684 685 686 687 688 689 690 |
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 NFSD: Refactor tr... |
691 |
/* |
0a5372d8a NFSD: Finish refa... |
692 693 694 |
* Zero-length write. Return a list of NFSD's current listener * transports. */ |
9dd9845f0 nfsd: make NFSd s... |
695 |
static ssize_t __write_ports_names(char *buf, struct net *net) |
0a5372d8a NFSD: Finish refa... |
696 |
{ |
9dd9845f0 nfsd: make NFSd s... |
697 698 699 |
struct nfsd_net *nn = net_generic(net, nfsd_net_id); if (nn->nfsd_serv == NULL) |
0a5372d8a NFSD: Finish refa... |
700 |
return 0; |
9dd9845f0 nfsd: make NFSd s... |
701 |
return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT); |
0a5372d8a NFSD: Finish refa... |
702 703 704 |
} /* |
0b7c2f6fc NFSD: Refactor so... |
705 706 707 708 |
* 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 nfsd: pass net to... |
709 |
static ssize_t __write_ports_addfd(char *buf, struct net *net) |
0b7c2f6fc NFSD: Refactor so... |
710 711 712 |
{ char *mesg = buf; int fd, err; |
9dd9845f0 nfsd: make NFSd s... |
713 |
struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
0b7c2f6fc NFSD: Refactor so... |
714 715 716 717 |
err = get_int(&mesg, &fd); if (err != 0 || fd < 0) return -EINVAL; |
306463942 nfsd: check passe... |
718 719 720 721 722 |
if (svc_alien_sock(net, fd)) { printk(KERN_ERR "%s: socket net is different to NFSd's one ", __func__); return -EINVAL; } |
6777436b0 nfsd: pass net to... |
723 |
err = nfsd_create_serv(net); |
0b7c2f6fc NFSD: Refactor so... |
724 725 |
if (err != 0) return err; |
9dd9845f0 nfsd: make NFSd s... |
726 |
err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); |
78a8d7c8c nfsd: fix error h... |
727 |
if (err < 0) { |
19f7e2ca4 NFSd: introduce n... |
728 |
nfsd_destroy(net); |
78a8d7c8c nfsd: fix error h... |
729 730 |
return err; } |
0b7c2f6fc NFSD: Refactor so... |
731 |
|
ea068bad2 NFSD: move lockd_... |
732 |
/* Decrease the count, but don't shut down the service */ |
9dd9845f0 nfsd: make NFSd s... |
733 |
nn->nfsd_serv->sv_nrthreads--; |
ea068bad2 NFSD: move lockd_... |
734 |
return err; |
0b7c2f6fc NFSD: Refactor so... |
735 736 737 |
} /* |
4eb68c266 NFSD: Refactor tr... |
738 739 740 |
* A transport listener is added by writing it's transport name and * a port number. */ |
081603520 nfsd: pass net to... |
741 |
static ssize_t __write_ports_addxprt(char *buf, struct net *net) |
4eb68c266 NFSD: Refactor tr... |
742 743 |
{ char transport[16]; |
37498292a NFSD: Create PF_I... |
744 |
struct svc_xprt *xprt; |
4eb68c266 NFSD: Refactor tr... |
745 |
int port, err; |
9dd9845f0 nfsd: make NFSd s... |
746 |
struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
4eb68c266 NFSD: Refactor tr... |
747 |
|
a10fded18 nfsd: allow confi... |
748 |
if (sscanf(buf, "%15s %5u", transport, &port) != 2) |
4eb68c266 NFSD: Refactor tr... |
749 |
return -EINVAL; |
4be929be3 kernel-wide: repl... |
750 |
if (port < 1 || port > USHRT_MAX) |
4eb68c266 NFSD: Refactor tr... |
751 |
return -EINVAL; |
6777436b0 nfsd: pass net to... |
752 |
err = nfsd_create_serv(net); |
4eb68c266 NFSD: Refactor tr... |
753 754 |
if (err != 0) return err; |
9dd9845f0 nfsd: make NFSd s... |
755 |
err = svc_create_xprt(nn->nfsd_serv, transport, net, |
4eb68c266 NFSD: Refactor tr... |
756 |
PF_INET, port, SVC_SOCK_ANONYMOUS); |
687179081 SUNRPC: NFS kerne... |
757 |
if (err < 0) |
37498292a NFSD: Create PF_I... |
758 |
goto out_err; |
9dd9845f0 nfsd: make NFSd s... |
759 |
err = svc_create_xprt(nn->nfsd_serv, transport, net, |
37498292a NFSD: Create PF_I... |
760 761 762 |
PF_INET6, port, SVC_SOCK_ANONYMOUS); if (err < 0 && err != -EAFNOSUPPORT) goto out_close; |
0cd14a061 nfsd: fix error h... |
763 764 |
/* Decrease the count, but don't shut down the service */ |
9dd9845f0 nfsd: make NFSd s... |
765 |
nn->nfsd_serv->sv_nrthreads--; |
4eb68c266 NFSD: Refactor tr... |
766 |
return 0; |
37498292a NFSD: Create PF_I... |
767 |
out_close: |
9dd9845f0 nfsd: make NFSd s... |
768 |
xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port); |
37498292a NFSD: Create PF_I... |
769 770 771 772 773 |
if (xprt != NULL) { svc_close_xprt(xprt); svc_xprt_put(xprt); } out_err: |
19f7e2ca4 NFSd: introduce n... |
774 |
nfsd_destroy(net); |
37498292a NFSD: Create PF_I... |
775 |
return err; |
4eb68c266 NFSD: Refactor tr... |
776 |
} |
081603520 nfsd: pass net to... |
777 778 |
static ssize_t __write_ports(struct file *file, char *buf, size_t size, struct net *net) |
80212d59e [PATCH] knfsd: de... |
779 |
{ |
0a5372d8a NFSD: Finish refa... |
780 |
if (size == 0) |
9dd9845f0 nfsd: make NFSd s... |
781 |
return __write_ports_names(buf, net); |
0b7c2f6fc NFSD: Refactor so... |
782 783 |
if (isdigit(buf[0])) |
081603520 nfsd: pass net to... |
784 |
return __write_ports_addfd(buf, net); |
82d565919 NFSD: Refactor po... |
785 |
|
4eb68c266 NFSD: Refactor tr... |
786 |
if (isalpha(buf[0])) |
081603520 nfsd: pass net to... |
787 |
return __write_ports_addxprt(buf, net); |
4cd5dc751 NFSD: Refactor tr... |
788 |
|
b41b66d63 [PATCH] knfsd: al... |
789 |
return -EINVAL; |
80212d59e [PATCH] knfsd: de... |
790 |
} |
262a09823 NFSD: Add documen... |
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 |
/** * 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 NFSD: Note an add... |
811 812 813 |
* used as an NFSD listener; listen(3) * must be called for a SOCK_STREAM * socket, otherwise it is ignored |
262a09823 NFSD: Add documen... |
814 815 816 817 818 819 820 821 822 823 824 825 826 |
* 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 NFSD: Add documen... |
827 828 829 830 831 832 833 834 |
* 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 NFSD: Add documen... |
835 |
*/ |
bedbdd8ba knfsd: Replace lo... |
836 837 838 |
static ssize_t write_ports(struct file *file, char *buf, size_t size) { ssize_t rv; |
3dd98a3bc knfsd: clean up n... |
839 |
|
bedbdd8ba knfsd: Replace lo... |
840 |
mutex_lock(&nfsd_mutex); |
244c7d444 nfsd/nfsctl.c: ne... |
841 |
rv = __write_ports(file, buf, size, netns(file)); |
bedbdd8ba knfsd: Replace lo... |
842 843 844 |
mutex_unlock(&nfsd_mutex); return rv; } |
596bbe53e [PATCH] knfsd: Al... |
845 |
int nfsd_max_blksize; |
262a09823 NFSD: Add documen... |
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 |
/** * 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 [PATCH] knfsd: Al... |
868 869 870 |
static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) { char *mesg = buf; |
244c7d444 nfsd/nfsctl.c: ne... |
871 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
9dd9845f0 nfsd: make NFSd s... |
872 |
|
596bbe53e [PATCH] knfsd: Al... |
873 874 875 876 877 878 879 880 |
if (size > 0) { int bsize; int rv = get_int(&mesg, &bsize); if (rv) return rv; /* force bsize into allowed range and * required alignment. */ |
3c7aa15d2 NFSD: Using min/m... |
881 882 |
bsize = max_t(int, bsize, 1024); bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE); |
596bbe53e [PATCH] knfsd: Al... |
883 |
bsize &= ~(1024-1); |
bedbdd8ba knfsd: Replace lo... |
884 |
mutex_lock(&nfsd_mutex); |
9dd9845f0 nfsd: make NFSd s... |
885 |
if (nn->nfsd_serv) { |
bedbdd8ba knfsd: Replace lo... |
886 |
mutex_unlock(&nfsd_mutex); |
596bbe53e [PATCH] knfsd: Al... |
887 888 889 |
return -EBUSY; } nfsd_max_blksize = bsize; |
bedbdd8ba knfsd: Replace lo... |
890 |
mutex_unlock(&nfsd_mutex); |
596bbe53e [PATCH] knfsd: Al... |
891 |
} |
e06b64050 NFSD: Stricter bu... |
892 893 894 895 |
return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d ", nfsd_max_blksize); |
596bbe53e [PATCH] knfsd: Al... |
896 |
} |
5b8db00ba nfsd: add a new /... |
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 |
/** * 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 nfsd/nfsctl.c: ne... |
921 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
5b8db00ba nfsd: add a new /... |
922 923 924 925 926 927 928 929 930 931 932 933 934 |
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 [PATCH] knfsd: Al... |
935 |
#ifdef CONFIG_NFSD_V4 |
9dd9845f0 nfsd: make NFSd s... |
936 937 |
static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time, struct nfsd_net *nn) |
1da177e4c Linux-2.6.12-rc2 |
938 |
{ |
1da177e4c Linux-2.6.12-rc2 |
939 |
char *mesg = buf; |
f01357401 nfsd4: reshuffle ... |
940 |
int rv, i; |
1da177e4c Linux-2.6.12-rc2 |
941 942 |
if (size > 0) { |
9dd9845f0 nfsd: make NFSd s... |
943 |
if (nn->nfsd_serv) |
3dd98a3bc knfsd: clean up n... |
944 |
return -EBUSY; |
f01357401 nfsd4: reshuffle ... |
945 |
rv = get_int(&mesg, &i); |
1da177e4c Linux-2.6.12-rc2 |
946 947 |
if (rv) return rv; |
e7b184f19 nfsd4: document l... |
948 949 950 951 952 953 954 955 956 957 958 959 |
/* * 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 nfsd4: reshuffle ... |
960 |
if (i < 10 || i > 3600) |
1da177e4c Linux-2.6.12-rc2 |
961 |
return -EINVAL; |
f01357401 nfsd4: reshuffle ... |
962 |
*time = i; |
1da177e4c Linux-2.6.12-rc2 |
963 |
} |
e06b64050 NFSD: Stricter bu... |
964 |
|
f01357401 nfsd4: reshuffle ... |
965 966 967 |
return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld ", *time); } |
9dd9845f0 nfsd: make NFSd s... |
968 969 |
static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time, struct nfsd_net *nn) |
f01357401 nfsd4: reshuffle ... |
970 971 972 973 |
{ ssize_t rv; mutex_lock(&nfsd_mutex); |
9dd9845f0 nfsd: make NFSd s... |
974 |
rv = __nfsd4_write_time(file, buf, size, time, nn); |
f01357401 nfsd4: reshuffle ... |
975 976 |
mutex_unlock(&nfsd_mutex); return rv; |
1da177e4c Linux-2.6.12-rc2 |
977 |
} |
262a09823 NFSD: Add documen... |
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 |
/** * 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 knfsd: clean up n... |
1000 1001 |
static ssize_t write_leasetime(struct file *file, char *buf, size_t size) { |
244c7d444 nfsd/nfsctl.c: ne... |
1002 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
9dd9845f0 nfsd: make NFSd s... |
1003 |
return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); |
3dd98a3bc knfsd: clean up n... |
1004 |
} |
efc4bb4fd nfsd4: allow sett... |
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 |
/** * 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 nfsd/nfsctl.c: ne... |
1017 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
9dd9845f0 nfsd: make NFSd s... |
1018 |
return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); |
efc4bb4fd nfsd4: allow sett... |
1019 |
} |
9dd9845f0 nfsd: make NFSd s... |
1020 1021 |
static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size, struct nfsd_net *nn) |
0964a3d3f [PATCH] knfsd: nf... |
1022 1023 1024 1025 |
{ char *mesg = buf; char *recdir; int len, status; |
3dd98a3bc knfsd: clean up n... |
1026 |
if (size > 0) { |
9dd9845f0 nfsd: make NFSd s... |
1027 |
if (nn->nfsd_serv) |
3dd98a3bc knfsd: clean up n... |
1028 1029 1030 1031 1032 |
return -EBUSY; if (size > PATH_MAX || buf[size-1] != ' ') return -EINVAL; buf[size-1] = 0; |
0964a3d3f [PATCH] knfsd: nf... |
1033 |
|
3dd98a3bc knfsd: clean up n... |
1034 1035 1036 1037 |
recdir = mesg; len = qword_get(&mesg, recdir, size); if (len <= 0) return -EINVAL; |
0964a3d3f [PATCH] knfsd: nf... |
1038 |
|
3dd98a3bc knfsd: clean up n... |
1039 |
status = nfs4_reset_recoverydir(recdir); |
690499610 gcc-4.6: nfsd: fi... |
1040 1041 |
if (status) return status; |
3dd98a3bc knfsd: clean up n... |
1042 |
} |
3d72ab8fd NFSD: Stricter bu... |
1043 1044 1045 1046 |
return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s ", nfs4_recoverydir()); |
0964a3d3f [PATCH] knfsd: nf... |
1047 |
} |
3dd98a3bc knfsd: clean up n... |
1048 |
|
262a09823 NFSD: Add documen... |
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 |
/** * 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 knfsd: clean up n... |
1071 1072 1073 |
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) { ssize_t rv; |
244c7d444 nfsd/nfsctl.c: ne... |
1074 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
3dd98a3bc knfsd: clean up n... |
1075 1076 |
mutex_lock(&nfsd_mutex); |
9dd9845f0 nfsd: make NFSd s... |
1077 |
rv = __write_recoverydir(file, buf, size, nn); |
3dd98a3bc knfsd: clean up n... |
1078 1079 1080 |
mutex_unlock(&nfsd_mutex); return rv; } |
7f5ef2e90 nfsd: add a v4_en... |
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 |
/** * 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 nfsd/nfsctl.c: ne... |
1103 |
struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id); |
7f5ef2e90 nfsd: add a v4_en... |
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 |
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 [PATCH] knfsd: Al... |
1121 |
#endif |
0964a3d3f [PATCH] knfsd: nf... |
1122 |
|
1da177e4c Linux-2.6.12-rc2 |
1123 1124 1125 1126 1127 1128 1129 |
/*----------------------------------------------------------------------------*/ /* * populating the filesystem. */ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) { |
cda37124f fs: constify tree... |
1130 |
static const struct tree_descr nfsd_files[] = { |
96d851c4d nfsd: use proper ... |
1131 |
[NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO}, |
e8e8753f7 nfsd: new interfa... |
1132 1133 |
[NFSD_Export_features] = {"export_features", &export_features_operations, S_IRUGO}, |
4373ea84c lockd: unlock loc... |
1134 1135 |
[NFSD_FO_UnlockIP] = {"unlock_ip", &transaction_ops, S_IWUSR|S_IRUSR}, |
17efa372c lockd: unlock loc... |
1136 1137 |
[NFSD_FO_UnlockFS] = {"unlock_filesystem", &transaction_ops, S_IWUSR|S_IRUSR}, |
1da177e4c Linux-2.6.12-rc2 |
1138 1139 |
[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, |
eed2965af [PATCH] knfsd: al... |
1140 |
[NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, |
03cf6c9f4 knfsd: add file t... |
1141 |
[NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO}, |
a2f999a37 nfsd: add new rep... |
1142 |
[NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO}, |
70c3b76c2 [PATCH] knfsd: Al... |
1143 |
[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, |
80212d59e [PATCH] knfsd: de... |
1144 |
[NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, |
596bbe53e [PATCH] knfsd: Al... |
1145 |
[NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, |
5b8db00ba nfsd: add a new /... |
1146 |
[NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO}, |
b084f598d nfsd: fix depende... |
1147 |
#if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) |
b0b0c0a26 nfsd: add proc fi... |
1148 |
[NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, |
b084f598d nfsd: fix depende... |
1149 |
#endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ |
1da177e4c Linux-2.6.12-rc2 |
1150 1151 |
#ifdef CONFIG_NFSD_V4 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
efc4bb4fd nfsd4: allow sett... |
1152 |
[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
0964a3d3f [PATCH] knfsd: nf... |
1153 |
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, |
7f5ef2e90 nfsd: add a v4_en... |
1154 |
[NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO}, |
1da177e4c Linux-2.6.12-rc2 |
1155 1156 1157 |
#endif /* last one */ {""} }; |
d91ee87d8 vfs: Pass data, n... |
1158 1159 |
get_net(sb->s_fs_info); return simple_fill_super(sb, 0x6e667364, nfsd_files); |
1da177e4c Linux-2.6.12-rc2 |
1160 |
} |
fc14f2fef convert get_sb_si... |
1161 1162 |
static struct dentry *nfsd_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
1163 |
{ |
d91ee87d8 vfs: Pass data, n... |
1164 1165 |
struct net *net = current->nsproxy->net_ns; return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super); |
11f779421 nfsd: containeriz... |
1166 1167 1168 1169 1170 1171 1172 1173 |
} static void nfsd_umount(struct super_block *sb) { struct net *net = sb->s_fs_info; kill_litter_super(sb); put_net(net); |
1da177e4c Linux-2.6.12-rc2 |
1174 1175 1176 1177 1178 |
} static struct file_system_type nfsd_fs_type = { .owner = THIS_MODULE, .name = "nfsd", |
fc14f2fef convert get_sb_si... |
1179 |
.mount = nfsd_mount, |
11f779421 nfsd: containeriz... |
1180 |
.kill_sb = nfsd_umount, |
1da177e4c Linux-2.6.12-rc2 |
1181 |
}; |
7f78e0351 fs: Limit sys_mou... |
1182 |
MODULE_ALIAS_FS("nfsd"); |
1da177e4c Linux-2.6.12-rc2 |
1183 |
|
e331f606a nfsd: fail init o... |
1184 1185 1186 1187 1188 1189 1190 1191 |
#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 nfsd: use proper ... |
1192 1193 |
entry = proc_create("exports", 0, entry, &exports_proc_operations); |
ff7c4b369 nfsd: remove /pro... |
1194 1195 |
if (!entry) { remove_proc_entry("fs/nfs", NULL); |
e331f606a nfsd: fail init o... |
1196 |
return -ENOMEM; |
ff7c4b369 nfsd: remove /pro... |
1197 |
} |
e331f606a nfsd: fail init o... |
1198 1199 1200 1201 1202 1203 1204 1205 |
return 0; } #else /* CONFIG_PROC_FS */ static int create_proc_exports_entry(void) { return 0; } #endif |
c7d03a00b netns: make struc... |
1206 |
unsigned int nfsd_net_id; |
5717e0128 nfsd: allocate ex... |
1207 1208 1209 1210 |
static __net_init int nfsd_init_net(struct net *net) { int retval; |
3d7337115 nfsd: make NFSv4 ... |
1211 |
struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
5717e0128 nfsd: allocate ex... |
1212 1213 1214 1215 |
retval = nfsd_export_init(net); if (retval) goto out_export_error; |
f69adb2fe nfsd: allocate id... |
1216 1217 1218 |
retval = nfsd_idmap_init(net); if (retval) goto out_idmap_error; |
3d7337115 nfsd: make NFSv4 ... |
1219 |
nn->nfsd4_lease = 90; /* default lease time */ |
5284b44e4 nfsd: make NFSv4 ... |
1220 |
nn->nfsd4_grace = 90; |
ebd7c72c6 nfsd: randomize S... |
1221 1222 |
nn->clverifier_counter = prandom_u32(); nn->clientid_counter = prandom_u32(); |
5717e0128 nfsd: allocate ex... |
1223 |
return 0; |
f69adb2fe nfsd: allocate id... |
1224 1225 |
out_idmap_error: nfsd_export_shutdown(net); |
5717e0128 nfsd: allocate ex... |
1226 1227 1228 1229 1230 1231 |
out_export_error: return retval; } static __net_exit void nfsd_exit_net(struct net *net) { |
f69adb2fe nfsd: allocate id... |
1232 |
nfsd_idmap_shutdown(net); |
5717e0128 nfsd: allocate ex... |
1233 1234 |
nfsd_export_shutdown(net); } |
7ea34ac15 nfsd: add a per-n... |
1235 |
static struct pernet_operations nfsd_net_ops = { |
5717e0128 nfsd: allocate ex... |
1236 1237 |
.init = nfsd_init_net, .exit = nfsd_exit_net, |
7ea34ac15 nfsd: add a per-n... |
1238 1239 1240 |
.id = &nfsd_net_id, .size = sizeof(struct nfsd_net), }; |
1da177e4c Linux-2.6.12-rc2 |
1241 1242 1243 1244 1245 |
static int __init init_nfsd(void) { int retval; printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de). "); |
7ea34ac15 nfsd: add a per-n... |
1246 1247 |
retval = register_pernet_subsys(&nfsd_net_ops); if (retval < 0) |
bb7ffbf29 nfsd: fix nsfd st... |
1248 1249 |
return retval; retval = register_cld_notifier(); |
e8ff2a845 knfsd: move nfsv4... |
1250 |
if (retval) |
7ea34ac15 nfsd: add a per-n... |
1251 |
goto out_unregister_pernet; |
bb7ffbf29 nfsd: fix nsfd st... |
1252 1253 1254 |
retval = nfsd4_init_slabs(); if (retval) goto out_unregister_notifier; |
9cf514ccf nfsd: implement p... |
1255 |
retval = nfsd4_init_pnfs(); |
65178db42 NFSD: Added fault... |
1256 1257 |
if (retval) goto out_free_slabs; |
9cf514ccf nfsd: implement p... |
1258 1259 1260 |
retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ if (retval) goto out_exit_pnfs; |
1da177e4c Linux-2.6.12-rc2 |
1261 |
nfsd_stat_init(); /* Statistics */ |
d5c3428b2 nfsd: fail module... |
1262 1263 1264 |
retval = nfsd_reply_cache_init(); if (retval) goto out_free_stat; |
1da177e4c Linux-2.6.12-rc2 |
1265 |
nfsd_lockd_init(); /* lockd->nfsd callbacks */ |
e331f606a nfsd: fail init o... |
1266 1267 |
retval = create_proc_exports_entry(); if (retval) |
f69adb2fe nfsd: allocate id... |
1268 |
goto out_free_lockd; |
1da177e4c Linux-2.6.12-rc2 |
1269 |
retval = register_filesystem(&nfsd_fs_type); |
26808d3f1 nfsd: cleanup nfs... |
1270 1271 1272 1273 |
if (retval) goto out_free_all; return 0; out_free_all: |
26808d3f1 nfsd: cleanup nfs... |
1274 1275 |
remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs", NULL); |
dbf847ecb knfsd: allow cach... |
1276 |
out_free_lockd: |
26808d3f1 nfsd: cleanup nfs... |
1277 |
nfsd_lockd_shutdown(); |
e331f606a nfsd: fail init o... |
1278 |
nfsd_reply_cache_shutdown(); |
d5c3428b2 nfsd: fail module... |
1279 1280 |
out_free_stat: nfsd_stat_shutdown(); |
65178db42 NFSD: Added fault... |
1281 |
nfsd_fault_inject_cleanup(); |
9cf514ccf nfsd: implement p... |
1282 1283 |
out_exit_pnfs: nfsd4_exit_pnfs(); |
65178db42 NFSD: Added fault... |
1284 |
out_free_slabs: |
26808d3f1 nfsd: cleanup nfs... |
1285 |
nfsd4_free_slabs(); |
813fd320c nfsd: add notifie... |
1286 |
out_unregister_notifier: |
797a9d797 nfsd: only regist... |
1287 |
unregister_cld_notifier(); |
bb7ffbf29 nfsd: fix nsfd st... |
1288 1289 |
out_unregister_pernet: unregister_pernet_subsys(&nfsd_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
1290 1291 1292 1293 1294 |
return retval; } static void __exit exit_nfsd(void) { |
d5c3428b2 nfsd: fail module... |
1295 |
nfsd_reply_cache_shutdown(); |
1da177e4c Linux-2.6.12-rc2 |
1296 1297 1298 1299 |
remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs", NULL); nfsd_stat_shutdown(); nfsd_lockd_shutdown(); |
e8ff2a845 knfsd: move nfsv4... |
1300 |
nfsd4_free_slabs(); |
9cf514ccf nfsd: implement p... |
1301 |
nfsd4_exit_pnfs(); |
65178db42 NFSD: Added fault... |
1302 |
nfsd_fault_inject_cleanup(); |
1da177e4c Linux-2.6.12-rc2 |
1303 |
unregister_filesystem(&nfsd_fs_type); |
797a9d797 nfsd: only regist... |
1304 |
unregister_cld_notifier(); |
bb7ffbf29 nfsd: fix nsfd st... |
1305 |
unregister_pernet_subsys(&nfsd_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
1306 1307 1308 1309 1310 1311 |
} MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); MODULE_LICENSE("GPL"); module_init(init_nfsd) module_exit(exit_nfsd) |