nfsctl.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. /*
  2. * Syscall interface to knfsd.
  3. *
  4. * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  5. */
  6. #include <linux/slab.h>
  7. #include <linux/namei.h>
  8. #include <linux/ctype.h>
  9. #include <linux/sunrpc/svcsock.h>
  10. #include <linux/lockd/lockd.h>
  11. #include <linux/sunrpc/addr.h>
  12. #include <linux/sunrpc/gss_api.h>
  13. #include <linux/sunrpc/gss_krb5_enctypes.h>
  14. #include <linux/sunrpc/rpc_pipe_fs.h>
  15. #include <linux/module.h>
  16. #include "idmap.h"
  17. #include "nfsd.h"
  18. #include "cache.h"
  19. #include "state.h"
  20. #include "netns.h"
  21. /*
  22. * We have a single directory with several nodes in it.
  23. */
  24. enum {
  25. NFSD_Root = 1,
  26. NFSD_List,
  27. NFSD_Export_features,
  28. NFSD_Fh,
  29. NFSD_FO_UnlockIP,
  30. NFSD_FO_UnlockFS,
  31. NFSD_Threads,
  32. NFSD_Pool_Threads,
  33. NFSD_Pool_Stats,
  34. NFSD_Reply_Cache_Stats,
  35. NFSD_Versions,
  36. NFSD_Ports,
  37. NFSD_MaxBlkSize,
  38. NFSD_SupportedEnctypes,
  39. /*
  40. * The below MUST come last. Otherwise we leave a hole in nfsd_files[]
  41. * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
  42. */
  43. #ifdef CONFIG_NFSD_V4
  44. NFSD_Leasetime,
  45. NFSD_Gracetime,
  46. NFSD_RecoveryDir,
  47. #endif
  48. };
  49. /*
  50. * write() for these nodes.
  51. */
  52. static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
  53. static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size);
  54. static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size);
  55. static ssize_t write_threads(struct file *file, char *buf, size_t size);
  56. static ssize_t write_pool_threads(struct file *file, char *buf, size_t size);
  57. static ssize_t write_versions(struct file *file, char *buf, size_t size);
  58. static ssize_t write_ports(struct file *file, char *buf, size_t size);
  59. static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
  60. #ifdef CONFIG_NFSD_V4
  61. static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
  62. static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
  63. static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
  64. #endif
  65. static ssize_t (*write_op[])(struct file *, char *, size_t) = {
  66. [NFSD_Fh] = write_filehandle,
  67. [NFSD_FO_UnlockIP] = write_unlock_ip,
  68. [NFSD_FO_UnlockFS] = write_unlock_fs,
  69. [NFSD_Threads] = write_threads,
  70. [NFSD_Pool_Threads] = write_pool_threads,
  71. [NFSD_Versions] = write_versions,
  72. [NFSD_Ports] = write_ports,
  73. [NFSD_MaxBlkSize] = write_maxblksize,
  74. #ifdef CONFIG_NFSD_V4
  75. [NFSD_Leasetime] = write_leasetime,
  76. [NFSD_Gracetime] = write_gracetime,
  77. [NFSD_RecoveryDir] = write_recoverydir,
  78. #endif
  79. };
  80. static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
  81. {
  82. ino_t ino = file_inode(file)->i_ino;
  83. char *data;
  84. ssize_t rv;
  85. if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
  86. return -EINVAL;
  87. data = simple_transaction_get(file, buf, size);
  88. if (IS_ERR(data))
  89. return PTR_ERR(data);
  90. rv = write_op[ino](file, data, size);
  91. if (rv >= 0) {
  92. simple_transaction_set(file, rv);
  93. rv = size;
  94. }
  95. return rv;
  96. }
  97. static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
  98. {
  99. if (! file->private_data) {
  100. /* An attempt to read a transaction file without writing
  101. * causes a 0-byte write so that the file can return
  102. * state information
  103. */
  104. ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
  105. if (rv < 0)
  106. return rv;
  107. }
  108. return simple_transaction_read(file, buf, size, pos);
  109. }
  110. static const struct file_operations transaction_ops = {
  111. .write = nfsctl_transaction_write,
  112. .read = nfsctl_transaction_read,
  113. .release = simple_transaction_release,
  114. .llseek = default_llseek,
  115. };
  116. static int exports_net_open(struct net *net, struct file *file)
  117. {
  118. int err;
  119. struct seq_file *seq;
  120. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  121. err = seq_open(file, &nfs_exports_op);
  122. if (err)
  123. return err;
  124. seq = file->private_data;
  125. seq->private = nn->svc_export_cache;
  126. return 0;
  127. }
  128. static int exports_proc_open(struct inode *inode, struct file *file)
  129. {
  130. return exports_net_open(current->nsproxy->net_ns, file);
  131. }
  132. static const struct file_operations exports_proc_operations = {
  133. .open = exports_proc_open,
  134. .read = seq_read,
  135. .llseek = seq_lseek,
  136. .release = seq_release,
  137. .owner = THIS_MODULE,
  138. };
  139. static int exports_nfsd_open(struct inode *inode, struct file *file)
  140. {
  141. return exports_net_open(inode->i_sb->s_fs_info, file);
  142. }
  143. static const struct file_operations exports_nfsd_operations = {
  144. .open = exports_nfsd_open,
  145. .read = seq_read,
  146. .llseek = seq_lseek,
  147. .release = seq_release,
  148. .owner = THIS_MODULE,
  149. };
  150. static int export_features_show(struct seq_file *m, void *v)
  151. {
  152. seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS);
  153. return 0;
  154. }
  155. static int export_features_open(struct inode *inode, struct file *file)
  156. {
  157. return single_open(file, export_features_show, NULL);
  158. }
  159. static const struct file_operations export_features_operations = {
  160. .open = export_features_open,
  161. .read = seq_read,
  162. .llseek = seq_lseek,
  163. .release = single_release,
  164. };
  165. #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
  166. static int supported_enctypes_show(struct seq_file *m, void *v)
  167. {
  168. seq_printf(m, KRB5_SUPPORTED_ENCTYPES);
  169. return 0;
  170. }
  171. static int supported_enctypes_open(struct inode *inode, struct file *file)
  172. {
  173. return single_open(file, supported_enctypes_show, NULL);
  174. }
  175. static const struct file_operations supported_enctypes_ops = {
  176. .open = supported_enctypes_open,
  177. .read = seq_read,
  178. .llseek = seq_lseek,
  179. .release = single_release,
  180. };
  181. #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
  182. static const struct file_operations pool_stats_operations = {
  183. .open = nfsd_pool_stats_open,
  184. .read = seq_read,
  185. .llseek = seq_lseek,
  186. .release = nfsd_pool_stats_release,
  187. .owner = THIS_MODULE,
  188. };
  189. static struct file_operations reply_cache_stats_operations = {
  190. .open = nfsd_reply_cache_stats_open,
  191. .read = seq_read,
  192. .llseek = seq_lseek,
  193. .release = single_release,
  194. };
  195. /*----------------------------------------------------------------------------*/
  196. /*
  197. * payload - write methods
  198. */
  199. /**
  200. * write_unlock_ip - Release all locks used by a client
  201. *
  202. * Experimental.
  203. *
  204. * Input:
  205. * buf: '\n'-terminated C string containing a
  206. * presentation format IP address
  207. * size: length of C string in @buf
  208. * Output:
  209. * On success: returns zero if all specified locks were released;
  210. * returns one if one or more locks were not released
  211. * On error: return code is negative errno value
  212. */
  213. static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
  214. {
  215. struct sockaddr_storage address;
  216. struct sockaddr *sap = (struct sockaddr *)&address;
  217. size_t salen = sizeof(address);
  218. char *fo_path;
  219. struct net *net = file->f_dentry->d_sb->s_fs_info;
  220. /* sanity check */
  221. if (size == 0)
  222. return -EINVAL;
  223. if (buf[size-1] != '\n')
  224. return -EINVAL;
  225. fo_path = buf;
  226. if (qword_get(&buf, fo_path, size) < 0)
  227. return -EINVAL;
  228. if (rpc_pton(net, fo_path, size, sap, salen) == 0)
  229. return -EINVAL;
  230. return nlmsvc_unlock_all_by_ip(sap);
  231. }
  232. /**
  233. * write_unlock_fs - Release all locks on a local file system
  234. *
  235. * Experimental.
  236. *
  237. * Input:
  238. * buf: '\n'-terminated C string containing the
  239. * absolute pathname of a local file system
  240. * size: length of C string in @buf
  241. * Output:
  242. * On success: returns zero if all specified locks were released;
  243. * returns one if one or more locks were not released
  244. * On error: return code is negative errno value
  245. */
  246. static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
  247. {
  248. struct path path;
  249. char *fo_path;
  250. int error;
  251. /* sanity check */
  252. if (size == 0)
  253. return -EINVAL;
  254. if (buf[size-1] != '\n')
  255. return -EINVAL;
  256. fo_path = buf;
  257. if (qword_get(&buf, fo_path, size) < 0)
  258. return -EINVAL;
  259. error = kern_path(fo_path, 0, &path);
  260. if (error)
  261. return error;
  262. /*
  263. * XXX: Needs better sanity checking. Otherwise we could end up
  264. * releasing locks on the wrong file system.
  265. *
  266. * For example:
  267. * 1. Does the path refer to a directory?
  268. * 2. Is that directory a mount point, or
  269. * 3. Is that directory the root of an exported file system?
  270. */
  271. error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
  272. path_put(&path);
  273. return error;
  274. }
  275. /**
  276. * write_filehandle - Get a variable-length NFS file handle by path
  277. *
  278. * On input, the buffer contains a '\n'-terminated C string comprised of
  279. * three alphanumeric words separated by whitespace. The string may
  280. * contain escape sequences.
  281. *
  282. * Input:
  283. * buf:
  284. * domain: client domain name
  285. * path: export pathname
  286. * maxsize: numeric maximum size of
  287. * @buf
  288. * size: length of C string in @buf
  289. * Output:
  290. * On success: passed-in buffer filled with '\n'-terminated C
  291. * string containing a ASCII hex text version
  292. * of the NFS file handle;
  293. * return code is the size in bytes of the string
  294. * On error: return code is negative errno value
  295. */
  296. static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
  297. {
  298. char *dname, *path;
  299. int uninitialized_var(maxsize);
  300. char *mesg = buf;
  301. int len;
  302. struct auth_domain *dom;
  303. struct knfsd_fh fh;
  304. struct net *net = file->f_dentry->d_sb->s_fs_info;
  305. if (size == 0)
  306. return -EINVAL;
  307. if (buf[size-1] != '\n')
  308. return -EINVAL;
  309. buf[size-1] = 0;
  310. dname = mesg;
  311. len = qword_get(&mesg, dname, size);
  312. if (len <= 0)
  313. return -EINVAL;
  314. path = dname+len+1;
  315. len = qword_get(&mesg, path, size);
  316. if (len <= 0)
  317. return -EINVAL;
  318. len = get_int(&mesg, &maxsize);
  319. if (len)
  320. return len;
  321. if (maxsize < NFS_FHSIZE)
  322. return -EINVAL;
  323. if (maxsize > NFS3_FHSIZE)
  324. maxsize = NFS3_FHSIZE;
  325. if (qword_get(&mesg, mesg, size)>0)
  326. return -EINVAL;
  327. /* we have all the words, they are in buf.. */
  328. dom = unix_domain_find(dname);
  329. if (!dom)
  330. return -ENOMEM;
  331. len = exp_rootfh(net, dom, path, &fh, maxsize);
  332. auth_domain_put(dom);
  333. if (len)
  334. return len;
  335. mesg = buf;
  336. len = SIMPLE_TRANSACTION_LIMIT;
  337. qword_addhex(&mesg, &len, (char*)&fh.fh_base, fh.fh_size);
  338. mesg[-1] = '\n';
  339. return mesg - buf;
  340. }
  341. /**
  342. * write_threads - Start NFSD, or report the current number of running threads
  343. *
  344. * Input:
  345. * buf: ignored
  346. * size: zero
  347. * Output:
  348. * On success: passed-in buffer filled with '\n'-terminated C
  349. * string numeric value representing the number of
  350. * running NFSD threads;
  351. * return code is the size in bytes of the string
  352. * On error: return code is zero
  353. *
  354. * OR
  355. *
  356. * Input:
  357. * buf: C string containing an unsigned
  358. * integer value representing the
  359. * number of NFSD threads to start
  360. * size: non-zero length of C string in @buf
  361. * Output:
  362. * On success: NFS service is started;
  363. * passed-in buffer filled with '\n'-terminated C
  364. * string numeric value representing the number of
  365. * running NFSD threads;
  366. * return code is the size in bytes of the string
  367. * On error: return code is zero or a negative errno value
  368. */
  369. static ssize_t write_threads(struct file *file, char *buf, size_t size)
  370. {
  371. char *mesg = buf;
  372. int rv;
  373. struct net *net = file->f_dentry->d_sb->s_fs_info;
  374. if (size > 0) {
  375. int newthreads;
  376. rv = get_int(&mesg, &newthreads);
  377. if (rv)
  378. return rv;
  379. if (newthreads < 0)
  380. return -EINVAL;
  381. rv = nfsd_svc(newthreads, net);
  382. if (rv < 0)
  383. return rv;
  384. } else
  385. rv = nfsd_nrthreads(net);
  386. return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv);
  387. }
  388. /**
  389. * write_pool_threads - Set or report the current number of threads per pool
  390. *
  391. * Input:
  392. * buf: ignored
  393. * size: zero
  394. *
  395. * OR
  396. *
  397. * Input:
  398. * buf: C string containing whitespace-
  399. * separated unsigned integer values
  400. * representing the number of NFSD
  401. * threads to start in each pool
  402. * size: non-zero length of C string in @buf
  403. * Output:
  404. * On success: passed-in buffer filled with '\n'-terminated C
  405. * string containing integer values representing the
  406. * number of NFSD threads in each pool;
  407. * return code is the size in bytes of the string
  408. * On error: return code is zero or a negative errno value
  409. */
  410. static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
  411. {
  412. /* if size > 0, look for an array of number of threads per node
  413. * and apply them then write out number of threads per node as reply
  414. */
  415. char *mesg = buf;
  416. int i;
  417. int rv;
  418. int len;
  419. int npools;
  420. int *nthreads;
  421. struct net *net = file->f_dentry->d_sb->s_fs_info;
  422. mutex_lock(&nfsd_mutex);
  423. npools = nfsd_nrpools(net);
  424. if (npools == 0) {
  425. /*
  426. * NFS is shut down. The admin can start it by
  427. * writing to the threads file but NOT the pool_threads
  428. * file, sorry. Report zero threads.
  429. */
  430. mutex_unlock(&nfsd_mutex);
  431. strcpy(buf, "0\n");
  432. return strlen(buf);
  433. }
  434. nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
  435. rv = -ENOMEM;
  436. if (nthreads == NULL)
  437. goto out_free;
  438. if (size > 0) {
  439. for (i = 0; i < npools; i++) {
  440. rv = get_int(&mesg, &nthreads[i]);
  441. if (rv == -ENOENT)
  442. break; /* fewer numbers than pools */
  443. if (rv)
  444. goto out_free; /* syntax error */
  445. rv = -EINVAL;
  446. if (nthreads[i] < 0)
  447. goto out_free;
  448. }
  449. rv = nfsd_set_nrthreads(i, nthreads, net);
  450. if (rv)
  451. goto out_free;
  452. }
  453. rv = nfsd_get_nrthreads(npools, nthreads, net);
  454. if (rv)
  455. goto out_free;
  456. mesg = buf;
  457. size = SIMPLE_TRANSACTION_LIMIT;
  458. for (i = 0; i < npools && size > 0; i++) {
  459. snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' '));
  460. len = strlen(mesg);
  461. size -= len;
  462. mesg += len;
  463. }
  464. rv = mesg - buf;
  465. out_free:
  466. kfree(nthreads);
  467. mutex_unlock(&nfsd_mutex);
  468. return rv;
  469. }
  470. static ssize_t __write_versions(struct file *file, char *buf, size_t size)
  471. {
  472. char *mesg = buf;
  473. char *vers, *minorp, sign;
  474. int len, num, remaining;
  475. unsigned minor;
  476. ssize_t tlen = 0;
  477. char *sep;
  478. struct net *net = file->f_dentry->d_sb->s_fs_info;
  479. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  480. if (size>0) {
  481. if (nn->nfsd_serv)
  482. /* Cannot change versions without updating
  483. * nn->nfsd_serv->sv_xdrsize, and reallocing
  484. * rq_argp and rq_resp
  485. */
  486. return -EBUSY;
  487. if (buf[size-1] != '\n')
  488. return -EINVAL;
  489. buf[size-1] = 0;
  490. vers = mesg;
  491. len = qword_get(&mesg, vers, size);
  492. if (len <= 0) return -EINVAL;
  493. do {
  494. sign = *vers;
  495. if (sign == '+' || sign == '-')
  496. num = simple_strtol((vers+1), &minorp, 0);
  497. else
  498. num = simple_strtol(vers, &minorp, 0);
  499. if (*minorp == '.') {
  500. if (num != 4)
  501. return -EINVAL;
  502. minor = simple_strtoul(minorp+1, NULL, 0);
  503. if (minor == 0)
  504. return -EINVAL;
  505. if (nfsd_minorversion(minor, sign == '-' ?
  506. NFSD_CLEAR : NFSD_SET) < 0)
  507. return -EINVAL;
  508. goto next;
  509. }
  510. switch(num) {
  511. case 2:
  512. case 3:
  513. case 4:
  514. nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET);
  515. break;
  516. default:
  517. return -EINVAL;
  518. }
  519. next:
  520. vers += len + 1;
  521. } while ((len = qword_get(&mesg, vers, size)) > 0);
  522. /* If all get turned off, turn them back on, as
  523. * having no versions is BAD
  524. */
  525. nfsd_reset_versions();
  526. }
  527. /* Now write current state into reply buffer */
  528. len = 0;
  529. sep = "";
  530. remaining = SIMPLE_TRANSACTION_LIMIT;
  531. for (num=2 ; num <= 4 ; num++)
  532. if (nfsd_vers(num, NFSD_AVAIL)) {
  533. len = snprintf(buf, remaining, "%s%c%d", sep,
  534. nfsd_vers(num, NFSD_TEST)?'+':'-',
  535. num);
  536. sep = " ";
  537. if (len > remaining)
  538. break;
  539. remaining -= len;
  540. buf += len;
  541. tlen += len;
  542. }
  543. if (nfsd_vers(4, NFSD_AVAIL))
  544. for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION;
  545. minor++) {
  546. len = snprintf(buf, remaining, " %c4.%u",
  547. (nfsd_vers(4, NFSD_TEST) &&
  548. nfsd_minorversion(minor, NFSD_TEST)) ?
  549. '+' : '-',
  550. minor);
  551. if (len > remaining)
  552. break;
  553. remaining -= len;
  554. buf += len;
  555. tlen += len;
  556. }
  557. len = snprintf(buf, remaining, "\n");
  558. if (len > remaining)
  559. return -EINVAL;
  560. return tlen + len;
  561. }
  562. /**
  563. * write_versions - Set or report the available NFS protocol versions
  564. *
  565. * Input:
  566. * buf: ignored
  567. * size: zero
  568. * Output:
  569. * On success: passed-in buffer filled with '\n'-terminated C
  570. * string containing positive or negative integer
  571. * values representing the current status of each
  572. * protocol version;
  573. * return code is the size in bytes of the string
  574. * On error: return code is zero or a negative errno value
  575. *
  576. * OR
  577. *
  578. * Input:
  579. * buf: C string containing whitespace-
  580. * separated positive or negative
  581. * integer values representing NFS
  582. * protocol versions to enable ("+n")
  583. * or disable ("-n")
  584. * size: non-zero length of C string in @buf
  585. * Output:
  586. * On success: status of zero or more protocol versions has
  587. * been updated; passed-in buffer filled with
  588. * '\n'-terminated C string containing positive
  589. * or negative integer values representing the
  590. * current status of each protocol version;
  591. * return code is the size in bytes of the string
  592. * On error: return code is zero or a negative errno value
  593. */
  594. static ssize_t write_versions(struct file *file, char *buf, size_t size)
  595. {
  596. ssize_t rv;
  597. mutex_lock(&nfsd_mutex);
  598. rv = __write_versions(file, buf, size);
  599. mutex_unlock(&nfsd_mutex);
  600. return rv;
  601. }
  602. /*
  603. * Zero-length write. Return a list of NFSD's current listener
  604. * transports.
  605. */
  606. static ssize_t __write_ports_names(char *buf, struct net *net)
  607. {
  608. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  609. if (nn->nfsd_serv == NULL)
  610. return 0;
  611. return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT);
  612. }
  613. /*
  614. * A single 'fd' number was written, in which case it must be for
  615. * a socket of a supported family/protocol, and we use it as an
  616. * nfsd listener.
  617. */
  618. static ssize_t __write_ports_addfd(char *buf, struct net *net)
  619. {
  620. char *mesg = buf;
  621. int fd, err;
  622. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  623. err = get_int(&mesg, &fd);
  624. if (err != 0 || fd < 0)
  625. return -EINVAL;
  626. if (svc_alien_sock(net, fd)) {
  627. printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__);
  628. return -EINVAL;
  629. }
  630. err = nfsd_create_serv(net);
  631. if (err != 0)
  632. return err;
  633. err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
  634. if (err < 0) {
  635. nfsd_destroy(net);
  636. return err;
  637. }
  638. /* Decrease the count, but don't shut down the service */
  639. nn->nfsd_serv->sv_nrthreads--;
  640. return err;
  641. }
  642. /*
  643. * A transport listener is added by writing it's transport name and
  644. * a port number.
  645. */
  646. static ssize_t __write_ports_addxprt(char *buf, struct net *net)
  647. {
  648. char transport[16];
  649. struct svc_xprt *xprt;
  650. int port, err;
  651. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  652. if (sscanf(buf, "%15s %5u", transport, &port) != 2)
  653. return -EINVAL;
  654. if (port < 1 || port > USHRT_MAX)
  655. return -EINVAL;
  656. err = nfsd_create_serv(net);
  657. if (err != 0)
  658. return err;
  659. err = svc_create_xprt(nn->nfsd_serv, transport, net,
  660. PF_INET, port, SVC_SOCK_ANONYMOUS);
  661. if (err < 0)
  662. goto out_err;
  663. err = svc_create_xprt(nn->nfsd_serv, transport, net,
  664. PF_INET6, port, SVC_SOCK_ANONYMOUS);
  665. if (err < 0 && err != -EAFNOSUPPORT)
  666. goto out_close;
  667. /* Decrease the count, but don't shut down the service */
  668. nn->nfsd_serv->sv_nrthreads--;
  669. return 0;
  670. out_close:
  671. xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port);
  672. if (xprt != NULL) {
  673. svc_close_xprt(xprt);
  674. svc_xprt_put(xprt);
  675. }
  676. out_err:
  677. nfsd_destroy(net);
  678. return err;
  679. }
  680. static ssize_t __write_ports(struct file *file, char *buf, size_t size,
  681. struct net *net)
  682. {
  683. if (size == 0)
  684. return __write_ports_names(buf, net);
  685. if (isdigit(buf[0]))
  686. return __write_ports_addfd(buf, net);
  687. if (isalpha(buf[0]))
  688. return __write_ports_addxprt(buf, net);
  689. return -EINVAL;
  690. }
  691. /**
  692. * write_ports - Pass a socket file descriptor or transport name to listen on
  693. *
  694. * Input:
  695. * buf: ignored
  696. * size: zero
  697. * Output:
  698. * On success: passed-in buffer filled with a '\n'-terminated C
  699. * string containing a whitespace-separated list of
  700. * named NFSD listeners;
  701. * return code is the size in bytes of the string
  702. * On error: return code is zero or a negative errno value
  703. *
  704. * OR
  705. *
  706. * Input:
  707. * buf: C string containing an unsigned
  708. * integer value representing a bound
  709. * but unconnected socket that is to be
  710. * used as an NFSD listener; listen(3)
  711. * must be called for a SOCK_STREAM
  712. * socket, otherwise it is ignored
  713. * size: non-zero length of C string in @buf
  714. * Output:
  715. * On success: NFS service is started;
  716. * passed-in buffer filled with a '\n'-terminated C
  717. * string containing a unique alphanumeric name of
  718. * the listener;
  719. * return code is the size in bytes of the string
  720. * On error: return code is a negative errno value
  721. *
  722. * OR
  723. *
  724. * Input:
  725. * buf: C string containing a transport
  726. * name and an unsigned integer value
  727. * representing the port to listen on,
  728. * separated by whitespace
  729. * size: non-zero length of C string in @buf
  730. * Output:
  731. * On success: returns zero; NFS service is started
  732. * On error: return code is a negative errno value
  733. */
  734. static ssize_t write_ports(struct file *file, char *buf, size_t size)
  735. {
  736. ssize_t rv;
  737. struct net *net = file->f_dentry->d_sb->s_fs_info;
  738. mutex_lock(&nfsd_mutex);
  739. rv = __write_ports(file, buf, size, net);
  740. mutex_unlock(&nfsd_mutex);
  741. return rv;
  742. }
  743. int nfsd_max_blksize;
  744. /**
  745. * write_maxblksize - Set or report the current NFS blksize
  746. *
  747. * Input:
  748. * buf: ignored
  749. * size: zero
  750. *
  751. * OR
  752. *
  753. * Input:
  754. * buf: C string containing an unsigned
  755. * integer value representing the new
  756. * NFS blksize
  757. * size: non-zero length of C string in @buf
  758. * Output:
  759. * On success: passed-in buffer filled with '\n'-terminated C string
  760. * containing numeric value of the current NFS blksize
  761. * setting;
  762. * return code is the size in bytes of the string
  763. * On error: return code is zero or a negative errno value
  764. */
  765. static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
  766. {
  767. char *mesg = buf;
  768. struct net *net = file->f_dentry->d_sb->s_fs_info;
  769. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  770. if (size > 0) {
  771. int bsize;
  772. int rv = get_int(&mesg, &bsize);
  773. if (rv)
  774. return rv;
  775. /* force bsize into allowed range and
  776. * required alignment.
  777. */
  778. if (bsize < 1024)
  779. bsize = 1024;
  780. if (bsize > NFSSVC_MAXBLKSIZE)
  781. bsize = NFSSVC_MAXBLKSIZE;
  782. bsize &= ~(1024-1);
  783. mutex_lock(&nfsd_mutex);
  784. if (nn->nfsd_serv) {
  785. mutex_unlock(&nfsd_mutex);
  786. return -EBUSY;
  787. }
  788. nfsd_max_blksize = bsize;
  789. mutex_unlock(&nfsd_mutex);
  790. }
  791. return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n",
  792. nfsd_max_blksize);
  793. }
  794. #ifdef CONFIG_NFSD_V4
  795. static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
  796. time_t *time, struct nfsd_net *nn)
  797. {
  798. char *mesg = buf;
  799. int rv, i;
  800. if (size > 0) {
  801. if (nn->nfsd_serv)
  802. return -EBUSY;
  803. rv = get_int(&mesg, &i);
  804. if (rv)
  805. return rv;
  806. /*
  807. * Some sanity checking. We don't have a reason for
  808. * these particular numbers, but problems with the
  809. * extremes are:
  810. * - Too short: the briefest network outage may
  811. * cause clients to lose all their locks. Also,
  812. * the frequent polling may be wasteful.
  813. * - Too long: do you really want reboot recovery
  814. * to take more than an hour? Or to make other
  815. * clients wait an hour before being able to
  816. * revoke a dead client's locks?
  817. */
  818. if (i < 10 || i > 3600)
  819. return -EINVAL;
  820. *time = i;
  821. }
  822. return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
  823. }
  824. static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
  825. time_t *time, struct nfsd_net *nn)
  826. {
  827. ssize_t rv;
  828. mutex_lock(&nfsd_mutex);
  829. rv = __nfsd4_write_time(file, buf, size, time, nn);
  830. mutex_unlock(&nfsd_mutex);
  831. return rv;
  832. }
  833. /**
  834. * write_leasetime - Set or report the current NFSv4 lease time
  835. *
  836. * Input:
  837. * buf: ignored
  838. * size: zero
  839. *
  840. * OR
  841. *
  842. * Input:
  843. * buf: C string containing an unsigned
  844. * integer value representing the new
  845. * NFSv4 lease expiry time
  846. * size: non-zero length of C string in @buf
  847. * Output:
  848. * On success: passed-in buffer filled with '\n'-terminated C
  849. * string containing unsigned integer value of the
  850. * current lease expiry time;
  851. * return code is the size in bytes of the string
  852. * On error: return code is zero or a negative errno value
  853. */
  854. static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
  855. {
  856. struct net *net = file->f_dentry->d_sb->s_fs_info;
  857. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  858. return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
  859. }
  860. /**
  861. * write_gracetime - Set or report current NFSv4 grace period time
  862. *
  863. * As above, but sets the time of the NFSv4 grace period.
  864. *
  865. * Note this should never be set to less than the *previous*
  866. * lease-period time, but we don't try to enforce this. (In the common
  867. * case (a new boot), we don't know what the previous lease time was
  868. * anyway.)
  869. */
  870. static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
  871. {
  872. struct net *net = file->f_dentry->d_sb->s_fs_info;
  873. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  874. return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
  875. }
  876. static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
  877. struct nfsd_net *nn)
  878. {
  879. char *mesg = buf;
  880. char *recdir;
  881. int len, status;
  882. if (size > 0) {
  883. if (nn->nfsd_serv)
  884. return -EBUSY;
  885. if (size > PATH_MAX || buf[size-1] != '\n')
  886. return -EINVAL;
  887. buf[size-1] = 0;
  888. recdir = mesg;
  889. len = qword_get(&mesg, recdir, size);
  890. if (len <= 0)
  891. return -EINVAL;
  892. status = nfs4_reset_recoverydir(recdir);
  893. if (status)
  894. return status;
  895. }
  896. return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
  897. nfs4_recoverydir());
  898. }
  899. /**
  900. * write_recoverydir - Set or report the pathname of the recovery directory
  901. *
  902. * Input:
  903. * buf: ignored
  904. * size: zero
  905. *
  906. * OR
  907. *
  908. * Input:
  909. * buf: C string containing the pathname
  910. * of the directory on a local file
  911. * system containing permanent NFSv4
  912. * recovery data
  913. * size: non-zero length of C string in @buf
  914. * Output:
  915. * On success: passed-in buffer filled with '\n'-terminated C string
  916. * containing the current recovery pathname setting;
  917. * return code is the size in bytes of the string
  918. * On error: return code is zero or a negative errno value
  919. */
  920. static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
  921. {
  922. ssize_t rv;
  923. struct net *net = file->f_dentry->d_sb->s_fs_info;
  924. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  925. mutex_lock(&nfsd_mutex);
  926. rv = __write_recoverydir(file, buf, size, nn);
  927. mutex_unlock(&nfsd_mutex);
  928. return rv;
  929. }
  930. #endif
  931. /*----------------------------------------------------------------------------*/
  932. /*
  933. * populating the filesystem.
  934. */
  935. static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
  936. {
  937. static struct tree_descr nfsd_files[] = {
  938. [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
  939. [NFSD_Export_features] = {"export_features",
  940. &export_features_operations, S_IRUGO},
  941. [NFSD_FO_UnlockIP] = {"unlock_ip",
  942. &transaction_ops, S_IWUSR|S_IRUSR},
  943. [NFSD_FO_UnlockFS] = {"unlock_filesystem",
  944. &transaction_ops, S_IWUSR|S_IRUSR},
  945. [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
  946. [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
  947. [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
  948. [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
  949. [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
  950. [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
  951. [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
  952. [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
  953. #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE)
  954. [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO},
  955. #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */
  956. #ifdef CONFIG_NFSD_V4
  957. [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
  958. [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
  959. [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
  960. #endif
  961. /* last one */ {""}
  962. };
  963. struct net *net = data;
  964. int ret;
  965. ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
  966. if (ret)
  967. return ret;
  968. sb->s_fs_info = get_net(net);
  969. return 0;
  970. }
  971. static struct dentry *nfsd_mount(struct file_system_type *fs_type,
  972. int flags, const char *dev_name, void *data)
  973. {
  974. return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
  975. }
  976. static void nfsd_umount(struct super_block *sb)
  977. {
  978. struct net *net = sb->s_fs_info;
  979. kill_litter_super(sb);
  980. put_net(net);
  981. }
  982. static struct file_system_type nfsd_fs_type = {
  983. .owner = THIS_MODULE,
  984. .name = "nfsd",
  985. .mount = nfsd_mount,
  986. .kill_sb = nfsd_umount,
  987. };
  988. MODULE_ALIAS_FS("nfsd");
  989. #ifdef CONFIG_PROC_FS
  990. static int create_proc_exports_entry(void)
  991. {
  992. struct proc_dir_entry *entry;
  993. entry = proc_mkdir("fs/nfs", NULL);
  994. if (!entry)
  995. return -ENOMEM;
  996. entry = proc_create("exports", 0, entry,
  997. &exports_proc_operations);
  998. if (!entry) {
  999. remove_proc_entry("fs/nfs", NULL);
  1000. return -ENOMEM;
  1001. }
  1002. return 0;
  1003. }
  1004. #else /* CONFIG_PROC_FS */
  1005. static int create_proc_exports_entry(void)
  1006. {
  1007. return 0;
  1008. }
  1009. #endif
  1010. int nfsd_net_id;
  1011. static __net_init int nfsd_init_net(struct net *net)
  1012. {
  1013. int retval;
  1014. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  1015. retval = nfsd_export_init(net);
  1016. if (retval)
  1017. goto out_export_error;
  1018. retval = nfsd_idmap_init(net);
  1019. if (retval)
  1020. goto out_idmap_error;
  1021. nn->nfsd4_lease = 90; /* default lease time */
  1022. nn->nfsd4_grace = 90;
  1023. return 0;
  1024. out_idmap_error:
  1025. nfsd_export_shutdown(net);
  1026. out_export_error:
  1027. return retval;
  1028. }
  1029. static __net_exit void nfsd_exit_net(struct net *net)
  1030. {
  1031. nfsd_idmap_shutdown(net);
  1032. nfsd_export_shutdown(net);
  1033. }
  1034. static struct pernet_operations nfsd_net_ops = {
  1035. .init = nfsd_init_net,
  1036. .exit = nfsd_exit_net,
  1037. .id = &nfsd_net_id,
  1038. .size = sizeof(struct nfsd_net),
  1039. };
  1040. static int __init init_nfsd(void)
  1041. {
  1042. int retval;
  1043. printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
  1044. retval = register_cld_notifier();
  1045. if (retval)
  1046. return retval;
  1047. retval = register_pernet_subsys(&nfsd_net_ops);
  1048. if (retval < 0)
  1049. goto out_unregister_notifier;
  1050. retval = nfsd4_init_slabs();
  1051. if (retval)
  1052. goto out_unregister_pernet;
  1053. nfs4_state_init();
  1054. retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */
  1055. if (retval)
  1056. goto out_free_slabs;
  1057. nfsd_stat_init(); /* Statistics */
  1058. retval = nfsd_reply_cache_init();
  1059. if (retval)
  1060. goto out_free_stat;
  1061. nfsd_lockd_init(); /* lockd->nfsd callbacks */
  1062. retval = create_proc_exports_entry();
  1063. if (retval)
  1064. goto out_free_lockd;
  1065. retval = register_filesystem(&nfsd_fs_type);
  1066. if (retval)
  1067. goto out_free_all;
  1068. return 0;
  1069. out_free_all:
  1070. remove_proc_entry("fs/nfs/exports", NULL);
  1071. remove_proc_entry("fs/nfs", NULL);
  1072. out_free_lockd:
  1073. nfsd_lockd_shutdown();
  1074. nfsd_reply_cache_shutdown();
  1075. out_free_stat:
  1076. nfsd_stat_shutdown();
  1077. nfsd_fault_inject_cleanup();
  1078. out_free_slabs:
  1079. nfsd4_free_slabs();
  1080. out_unregister_pernet:
  1081. unregister_pernet_subsys(&nfsd_net_ops);
  1082. out_unregister_notifier:
  1083. unregister_cld_notifier();
  1084. return retval;
  1085. }
  1086. static void __exit exit_nfsd(void)
  1087. {
  1088. nfsd_reply_cache_shutdown();
  1089. remove_proc_entry("fs/nfs/exports", NULL);
  1090. remove_proc_entry("fs/nfs", NULL);
  1091. nfsd_stat_shutdown();
  1092. nfsd_lockd_shutdown();
  1093. nfsd4_free_slabs();
  1094. nfsd_fault_inject_cleanup();
  1095. unregister_filesystem(&nfsd_fs_type);
  1096. unregister_pernet_subsys(&nfsd_net_ops);
  1097. unregister_cld_notifier();
  1098. }
  1099. MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
  1100. MODULE_LICENSE("GPL");
  1101. module_init(init_nfsd)
  1102. module_exit(exit_nfsd)