export.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * NFS exporting and validation.
  4. *
  5. * We maintain a list of clients, each of which has a list of
  6. * exports. To export an fs to a given client, you first have
  7. * to create the client entry with NFSCTL_ADDCLIENT, which
  8. * creates a client control block and adds it to the hash
  9. * table. Then, you call NFSCTL_EXPORT for each fs.
  10. *
  11. *
  12. * Copyright (C) 1995, 1996 Olaf Kirch, <[email protected]>
  13. */
  14. #include <linux/slab.h>
  15. #include <linux/namei.h>
  16. #include <linux/module.h>
  17. #include <linux/exportfs.h>
  18. #include <linux/sunrpc/svc_xprt.h>
  19. #include "nfsd.h"
  20. #include "nfsfh.h"
  21. #include "netns.h"
  22. #include "pnfs.h"
  23. #include "filecache.h"
  24. #include "trace.h"
  25. #define NFSDDBG_FACILITY NFSDDBG_EXPORT
  26. /*
  27. * We have two caches.
  28. * One maps client+vfsmnt+dentry to export options - the export map
  29. * The other maps client+filehandle-fragment to export options. - the expkey map
  30. *
  31. * The export options are actually stored in the first map, and the
  32. * second map contains a reference to the entry in the first map.
  33. */
  34. #define EXPKEY_HASHBITS 8
  35. #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
  36. #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
  37. static void expkey_put(struct kref *ref)
  38. {
  39. struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
  40. if (test_bit(CACHE_VALID, &key->h.flags) &&
  41. !test_bit(CACHE_NEGATIVE, &key->h.flags))
  42. path_put(&key->ek_path);
  43. auth_domain_put(key->ek_client);
  44. kfree_rcu(key, ek_rcu);
  45. }
  46. static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
  47. {
  48. return sunrpc_cache_pipe_upcall(cd, h);
  49. }
  50. static void expkey_request(struct cache_detail *cd,
  51. struct cache_head *h,
  52. char **bpp, int *blen)
  53. {
  54. /* client fsidtype \xfsid */
  55. struct svc_expkey *ek = container_of(h, struct svc_expkey, h);
  56. char type[5];
  57. qword_add(bpp, blen, ek->ek_client->name);
  58. snprintf(type, 5, "%d", ek->ek_fsidtype);
  59. qword_add(bpp, blen, type);
  60. qword_addhex(bpp, blen, (char*)ek->ek_fsid, key_len(ek->ek_fsidtype));
  61. (*bpp)[-1] = '\n';
  62. }
  63. static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
  64. struct svc_expkey *old);
  65. static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *);
  66. static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
  67. {
  68. /* client fsidtype fsid expiry [path] */
  69. char *buf;
  70. int len;
  71. struct auth_domain *dom = NULL;
  72. int err;
  73. int fsidtype;
  74. char *ep;
  75. struct svc_expkey key;
  76. struct svc_expkey *ek = NULL;
  77. if (mesg[mlen - 1] != '\n')
  78. return -EINVAL;
  79. mesg[mlen-1] = 0;
  80. buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
  81. err = -ENOMEM;
  82. if (!buf)
  83. goto out;
  84. err = -EINVAL;
  85. if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
  86. goto out;
  87. err = -ENOENT;
  88. dom = auth_domain_find(buf);
  89. if (!dom)
  90. goto out;
  91. dprintk("found domain %s\n", buf);
  92. err = -EINVAL;
  93. if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
  94. goto out;
  95. fsidtype = simple_strtoul(buf, &ep, 10);
  96. if (*ep)
  97. goto out;
  98. dprintk("found fsidtype %d\n", fsidtype);
  99. if (key_len(fsidtype)==0) /* invalid type */
  100. goto out;
  101. if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
  102. goto out;
  103. dprintk("found fsid length %d\n", len);
  104. if (len != key_len(fsidtype))
  105. goto out;
  106. /* OK, we seem to have a valid key */
  107. key.h.flags = 0;
  108. key.h.expiry_time = get_expiry(&mesg);
  109. if (key.h.expiry_time == 0)
  110. goto out;
  111. key.ek_client = dom;
  112. key.ek_fsidtype = fsidtype;
  113. memcpy(key.ek_fsid, buf, len);
  114. ek = svc_expkey_lookup(cd, &key);
  115. err = -ENOMEM;
  116. if (!ek)
  117. goto out;
  118. /* now we want a pathname, or empty meaning NEGATIVE */
  119. err = -EINVAL;
  120. len = qword_get(&mesg, buf, PAGE_SIZE);
  121. if (len < 0)
  122. goto out;
  123. dprintk("Path seems to be <%s>\n", buf);
  124. err = 0;
  125. if (len == 0) {
  126. set_bit(CACHE_NEGATIVE, &key.h.flags);
  127. ek = svc_expkey_update(cd, &key, ek);
  128. if (ek)
  129. trace_nfsd_expkey_update(ek, NULL);
  130. else
  131. err = -ENOMEM;
  132. } else {
  133. err = kern_path(buf, 0, &key.ek_path);
  134. if (err)
  135. goto out;
  136. dprintk("Found the path %s\n", buf);
  137. ek = svc_expkey_update(cd, &key, ek);
  138. if (ek)
  139. trace_nfsd_expkey_update(ek, buf);
  140. else
  141. err = -ENOMEM;
  142. path_put(&key.ek_path);
  143. }
  144. cache_flush();
  145. out:
  146. if (ek)
  147. cache_put(&ek->h, cd);
  148. if (dom)
  149. auth_domain_put(dom);
  150. kfree(buf);
  151. return err;
  152. }
  153. static int expkey_show(struct seq_file *m,
  154. struct cache_detail *cd,
  155. struct cache_head *h)
  156. {
  157. struct svc_expkey *ek ;
  158. int i;
  159. if (h ==NULL) {
  160. seq_puts(m, "#domain fsidtype fsid [path]\n");
  161. return 0;
  162. }
  163. ek = container_of(h, struct svc_expkey, h);
  164. seq_printf(m, "%s %d 0x", ek->ek_client->name,
  165. ek->ek_fsidtype);
  166. for (i=0; i < key_len(ek->ek_fsidtype)/4; i++)
  167. seq_printf(m, "%08x", ek->ek_fsid[i]);
  168. if (test_bit(CACHE_VALID, &h->flags) &&
  169. !test_bit(CACHE_NEGATIVE, &h->flags)) {
  170. seq_printf(m, " ");
  171. seq_path(m, &ek->ek_path, "\\ \t\n");
  172. }
  173. seq_printf(m, "\n");
  174. return 0;
  175. }
  176. static inline int expkey_match (struct cache_head *a, struct cache_head *b)
  177. {
  178. struct svc_expkey *orig = container_of(a, struct svc_expkey, h);
  179. struct svc_expkey *new = container_of(b, struct svc_expkey, h);
  180. if (orig->ek_fsidtype != new->ek_fsidtype ||
  181. orig->ek_client != new->ek_client ||
  182. memcmp(orig->ek_fsid, new->ek_fsid, key_len(orig->ek_fsidtype)) != 0)
  183. return 0;
  184. return 1;
  185. }
  186. static inline void expkey_init(struct cache_head *cnew,
  187. struct cache_head *citem)
  188. {
  189. struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
  190. struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
  191. kref_get(&item->ek_client->ref);
  192. new->ek_client = item->ek_client;
  193. new->ek_fsidtype = item->ek_fsidtype;
  194. memcpy(new->ek_fsid, item->ek_fsid, sizeof(new->ek_fsid));
  195. }
  196. static inline void expkey_update(struct cache_head *cnew,
  197. struct cache_head *citem)
  198. {
  199. struct svc_expkey *new = container_of(cnew, struct svc_expkey, h);
  200. struct svc_expkey *item = container_of(citem, struct svc_expkey, h);
  201. new->ek_path = item->ek_path;
  202. path_get(&item->ek_path);
  203. }
  204. static struct cache_head *expkey_alloc(void)
  205. {
  206. struct svc_expkey *i = kmalloc(sizeof(*i), GFP_KERNEL);
  207. if (i)
  208. return &i->h;
  209. else
  210. return NULL;
  211. }
  212. static void expkey_flush(void)
  213. {
  214. /*
  215. * Take the nfsd_mutex here to ensure that the file cache is not
  216. * destroyed while we're in the middle of flushing.
  217. */
  218. mutex_lock(&nfsd_mutex);
  219. nfsd_file_cache_purge(current->nsproxy->net_ns);
  220. mutex_unlock(&nfsd_mutex);
  221. }
  222. static const struct cache_detail svc_expkey_cache_template = {
  223. .owner = THIS_MODULE,
  224. .hash_size = EXPKEY_HASHMAX,
  225. .name = "nfsd.fh",
  226. .cache_put = expkey_put,
  227. .cache_upcall = expkey_upcall,
  228. .cache_request = expkey_request,
  229. .cache_parse = expkey_parse,
  230. .cache_show = expkey_show,
  231. .match = expkey_match,
  232. .init = expkey_init,
  233. .update = expkey_update,
  234. .alloc = expkey_alloc,
  235. .flush = expkey_flush,
  236. };
  237. static int
  238. svc_expkey_hash(struct svc_expkey *item)
  239. {
  240. int hash = item->ek_fsidtype;
  241. char * cp = (char*)item->ek_fsid;
  242. int len = key_len(item->ek_fsidtype);
  243. hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
  244. hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
  245. hash &= EXPKEY_HASHMASK;
  246. return hash;
  247. }
  248. static struct svc_expkey *
  249. svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
  250. {
  251. struct cache_head *ch;
  252. int hash = svc_expkey_hash(item);
  253. ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
  254. if (ch)
  255. return container_of(ch, struct svc_expkey, h);
  256. else
  257. return NULL;
  258. }
  259. static struct svc_expkey *
  260. svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
  261. struct svc_expkey *old)
  262. {
  263. struct cache_head *ch;
  264. int hash = svc_expkey_hash(new);
  265. ch = sunrpc_cache_update(cd, &new->h, &old->h, hash);
  266. if (ch)
  267. return container_of(ch, struct svc_expkey, h);
  268. else
  269. return NULL;
  270. }
  271. #define EXPORT_HASHBITS 8
  272. #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
  273. static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
  274. {
  275. struct nfsd4_fs_location *locations = fsloc->locations;
  276. int i;
  277. if (!locations)
  278. return;
  279. for (i = 0; i < fsloc->locations_count; i++) {
  280. kfree(locations[i].path);
  281. kfree(locations[i].hosts);
  282. }
  283. kfree(locations);
  284. fsloc->locations = NULL;
  285. }
  286. static int export_stats_init(struct export_stats *stats)
  287. {
  288. stats->start_time = ktime_get_seconds();
  289. return nfsd_percpu_counters_init(stats->counter, EXP_STATS_COUNTERS_NUM);
  290. }
  291. static void export_stats_reset(struct export_stats *stats)
  292. {
  293. nfsd_percpu_counters_reset(stats->counter, EXP_STATS_COUNTERS_NUM);
  294. }
  295. static void export_stats_destroy(struct export_stats *stats)
  296. {
  297. nfsd_percpu_counters_destroy(stats->counter, EXP_STATS_COUNTERS_NUM);
  298. }
  299. static void svc_export_put(struct kref *ref)
  300. {
  301. struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
  302. path_put(&exp->ex_path);
  303. auth_domain_put(exp->ex_client);
  304. nfsd4_fslocs_free(&exp->ex_fslocs);
  305. export_stats_destroy(&exp->ex_stats);
  306. kfree(exp->ex_uuid);
  307. kfree_rcu(exp, ex_rcu);
  308. }
  309. static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
  310. {
  311. return sunrpc_cache_pipe_upcall(cd, h);
  312. }
  313. static void svc_export_request(struct cache_detail *cd,
  314. struct cache_head *h,
  315. char **bpp, int *blen)
  316. {
  317. /* client path */
  318. struct svc_export *exp = container_of(h, struct svc_export, h);
  319. char *pth;
  320. qword_add(bpp, blen, exp->ex_client->name);
  321. pth = d_path(&exp->ex_path, *bpp, *blen);
  322. if (IS_ERR(pth)) {
  323. /* is this correct? */
  324. (*bpp)[0] = '\n';
  325. return;
  326. }
  327. qword_add(bpp, blen, pth);
  328. (*bpp)[-1] = '\n';
  329. }
  330. static struct svc_export *svc_export_update(struct svc_export *new,
  331. struct svc_export *old);
  332. static struct svc_export *svc_export_lookup(struct svc_export *);
  333. static int check_export(struct path *path, int *flags, unsigned char *uuid)
  334. {
  335. struct inode *inode = d_inode(path->dentry);
  336. /*
  337. * We currently export only dirs, regular files, and (for v4
  338. * pseudoroot) symlinks.
  339. */
  340. if (!S_ISDIR(inode->i_mode) &&
  341. !S_ISLNK(inode->i_mode) &&
  342. !S_ISREG(inode->i_mode))
  343. return -ENOTDIR;
  344. /*
  345. * Mountd should never pass down a writeable V4ROOT export, but,
  346. * just to make sure:
  347. */
  348. if (*flags & NFSEXP_V4ROOT)
  349. *flags |= NFSEXP_READONLY;
  350. /* There are two requirements on a filesystem to be exportable.
  351. * 1: We must be able to identify the filesystem from a number.
  352. * either a device number (so FS_REQUIRES_DEV needed)
  353. * or an FSID number (so NFSEXP_FSID or ->uuid is needed).
  354. * 2: We must be able to find an inode from a filehandle.
  355. * This means that s_export_op must be set.
  356. * 3: We must not currently be on an idmapped mount.
  357. */
  358. if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
  359. !(*flags & NFSEXP_FSID) &&
  360. uuid == NULL) {
  361. dprintk("exp_export: export of non-dev fs without fsid\n");
  362. return -EINVAL;
  363. }
  364. if (!inode->i_sb->s_export_op ||
  365. !inode->i_sb->s_export_op->fh_to_dentry) {
  366. dprintk("exp_export: export of invalid fs type.\n");
  367. return -EINVAL;
  368. }
  369. if (is_idmapped_mnt(path->mnt)) {
  370. dprintk("exp_export: export of idmapped mounts not yet supported.\n");
  371. return -EINVAL;
  372. }
  373. if (inode->i_sb->s_export_op->flags & EXPORT_OP_NOSUBTREECHK &&
  374. !(*flags & NFSEXP_NOSUBTREECHECK)) {
  375. dprintk("%s: %s does not support subtree checking!\n",
  376. __func__, inode->i_sb->s_type->name);
  377. return -EINVAL;
  378. }
  379. return 0;
  380. }
  381. #ifdef CONFIG_NFSD_V4
  382. static int
  383. fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
  384. {
  385. int len;
  386. int migrated, i, err;
  387. /* more than one fsloc */
  388. if (fsloc->locations)
  389. return -EINVAL;
  390. /* listsize */
  391. err = get_uint(mesg, &fsloc->locations_count);
  392. if (err)
  393. return err;
  394. if (fsloc->locations_count > MAX_FS_LOCATIONS)
  395. return -EINVAL;
  396. if (fsloc->locations_count == 0)
  397. return 0;
  398. fsloc->locations = kcalloc(fsloc->locations_count,
  399. sizeof(struct nfsd4_fs_location),
  400. GFP_KERNEL);
  401. if (!fsloc->locations)
  402. return -ENOMEM;
  403. for (i=0; i < fsloc->locations_count; i++) {
  404. /* colon separated host list */
  405. err = -EINVAL;
  406. len = qword_get(mesg, buf, PAGE_SIZE);
  407. if (len <= 0)
  408. goto out_free_all;
  409. err = -ENOMEM;
  410. fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
  411. if (!fsloc->locations[i].hosts)
  412. goto out_free_all;
  413. err = -EINVAL;
  414. /* slash separated path component list */
  415. len = qword_get(mesg, buf, PAGE_SIZE);
  416. if (len <= 0)
  417. goto out_free_all;
  418. err = -ENOMEM;
  419. fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
  420. if (!fsloc->locations[i].path)
  421. goto out_free_all;
  422. }
  423. /* migrated */
  424. err = get_int(mesg, &migrated);
  425. if (err)
  426. goto out_free_all;
  427. err = -EINVAL;
  428. if (migrated < 0 || migrated > 1)
  429. goto out_free_all;
  430. fsloc->migrated = migrated;
  431. return 0;
  432. out_free_all:
  433. nfsd4_fslocs_free(fsloc);
  434. return err;
  435. }
  436. static int secinfo_parse(char **mesg, char *buf, struct svc_export *exp)
  437. {
  438. struct exp_flavor_info *f;
  439. u32 listsize;
  440. int err;
  441. /* more than one secinfo */
  442. if (exp->ex_nflavors)
  443. return -EINVAL;
  444. err = get_uint(mesg, &listsize);
  445. if (err)
  446. return err;
  447. if (listsize > MAX_SECINFO_LIST)
  448. return -EINVAL;
  449. for (f = exp->ex_flavors; f < exp->ex_flavors + listsize; f++) {
  450. err = get_uint(mesg, &f->pseudoflavor);
  451. if (err)
  452. return err;
  453. /*
  454. * XXX: It would be nice to also check whether this
  455. * pseudoflavor is supported, so we can discover the
  456. * problem at export time instead of when a client fails
  457. * to authenticate.
  458. */
  459. err = get_uint(mesg, &f->flags);
  460. if (err)
  461. return err;
  462. /* Only some flags are allowed to differ between flavors: */
  463. if (~NFSEXP_SECINFO_FLAGS & (f->flags ^ exp->ex_flags))
  464. return -EINVAL;
  465. }
  466. exp->ex_nflavors = listsize;
  467. return 0;
  468. }
  469. #else /* CONFIG_NFSD_V4 */
  470. static inline int
  471. fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc){return 0;}
  472. static inline int
  473. secinfo_parse(char **mesg, char *buf, struct svc_export *exp) { return 0; }
  474. #endif
  475. static inline int
  476. nfsd_uuid_parse(char **mesg, char *buf, unsigned char **puuid)
  477. {
  478. int len;
  479. /* more than one uuid */
  480. if (*puuid)
  481. return -EINVAL;
  482. /* expect a 16 byte uuid encoded as \xXXXX... */
  483. len = qword_get(mesg, buf, PAGE_SIZE);
  484. if (len != EX_UUID_LEN)
  485. return -EINVAL;
  486. *puuid = kmemdup(buf, EX_UUID_LEN, GFP_KERNEL);
  487. if (*puuid == NULL)
  488. return -ENOMEM;
  489. return 0;
  490. }
  491. static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
  492. {
  493. /* client path expiry [flags anonuid anongid fsid] */
  494. char *buf;
  495. int len;
  496. int err;
  497. struct auth_domain *dom = NULL;
  498. struct svc_export exp = {}, *expp;
  499. int an_int;
  500. if (mesg[mlen-1] != '\n')
  501. return -EINVAL;
  502. mesg[mlen-1] = 0;
  503. buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
  504. if (!buf)
  505. return -ENOMEM;
  506. /* client */
  507. err = -EINVAL;
  508. len = qword_get(&mesg, buf, PAGE_SIZE);
  509. if (len <= 0)
  510. goto out;
  511. err = -ENOENT;
  512. dom = auth_domain_find(buf);
  513. if (!dom)
  514. goto out;
  515. /* path */
  516. err = -EINVAL;
  517. if ((len = qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
  518. goto out1;
  519. err = kern_path(buf, 0, &exp.ex_path);
  520. if (err)
  521. goto out1;
  522. exp.ex_client = dom;
  523. exp.cd = cd;
  524. exp.ex_devid_map = NULL;
  525. /* expiry */
  526. err = -EINVAL;
  527. exp.h.expiry_time = get_expiry(&mesg);
  528. if (exp.h.expiry_time == 0)
  529. goto out3;
  530. /* flags */
  531. err = get_int(&mesg, &an_int);
  532. if (err == -ENOENT) {
  533. err = 0;
  534. set_bit(CACHE_NEGATIVE, &exp.h.flags);
  535. } else {
  536. if (err || an_int < 0)
  537. goto out3;
  538. exp.ex_flags= an_int;
  539. /* anon uid */
  540. err = get_int(&mesg, &an_int);
  541. if (err)
  542. goto out3;
  543. exp.ex_anon_uid= make_kuid(current_user_ns(), an_int);
  544. /* anon gid */
  545. err = get_int(&mesg, &an_int);
  546. if (err)
  547. goto out3;
  548. exp.ex_anon_gid= make_kgid(current_user_ns(), an_int);
  549. /* fsid */
  550. err = get_int(&mesg, &an_int);
  551. if (err)
  552. goto out3;
  553. exp.ex_fsid = an_int;
  554. while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
  555. if (strcmp(buf, "fsloc") == 0)
  556. err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
  557. else if (strcmp(buf, "uuid") == 0)
  558. err = nfsd_uuid_parse(&mesg, buf, &exp.ex_uuid);
  559. else if (strcmp(buf, "secinfo") == 0)
  560. err = secinfo_parse(&mesg, buf, &exp);
  561. else
  562. /* quietly ignore unknown words and anything
  563. * following. Newer user-space can try to set
  564. * new values, then see what the result was.
  565. */
  566. break;
  567. if (err)
  568. goto out4;
  569. }
  570. err = check_export(&exp.ex_path, &exp.ex_flags, exp.ex_uuid);
  571. if (err)
  572. goto out4;
  573. /*
  574. * No point caching this if it would immediately expire.
  575. * Also, this protects exportfs's dummy export from the
  576. * anon_uid/anon_gid checks:
  577. */
  578. if (exp.h.expiry_time < seconds_since_boot())
  579. goto out4;
  580. /*
  581. * For some reason exportfs has been passing down an
  582. * invalid (-1) uid & gid on the "dummy" export which it
  583. * uses to test export support. To make sure exportfs
  584. * sees errors from check_export we therefore need to
  585. * delay these checks till after check_export:
  586. */
  587. err = -EINVAL;
  588. if (!uid_valid(exp.ex_anon_uid))
  589. goto out4;
  590. if (!gid_valid(exp.ex_anon_gid))
  591. goto out4;
  592. err = 0;
  593. nfsd4_setup_layout_type(&exp);
  594. }
  595. expp = svc_export_lookup(&exp);
  596. if (!expp) {
  597. err = -ENOMEM;
  598. goto out4;
  599. }
  600. expp = svc_export_update(&exp, expp);
  601. if (expp) {
  602. trace_nfsd_export_update(expp);
  603. cache_flush();
  604. exp_put(expp);
  605. } else
  606. err = -ENOMEM;
  607. out4:
  608. nfsd4_fslocs_free(&exp.ex_fslocs);
  609. kfree(exp.ex_uuid);
  610. out3:
  611. path_put(&exp.ex_path);
  612. out1:
  613. auth_domain_put(dom);
  614. out:
  615. kfree(buf);
  616. return err;
  617. }
  618. static void exp_flags(struct seq_file *m, int flag, int fsid,
  619. kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);
  620. static void show_secinfo(struct seq_file *m, struct svc_export *exp);
  621. static int is_export_stats_file(struct seq_file *m)
  622. {
  623. /*
  624. * The export_stats file uses the same ops as the exports file.
  625. * We use the file's name to determine the reported info per export.
  626. * There is no rename in nsfdfs, so d_name.name is stable.
  627. */
  628. return !strcmp(m->file->f_path.dentry->d_name.name, "export_stats");
  629. }
  630. static int svc_export_show(struct seq_file *m,
  631. struct cache_detail *cd,
  632. struct cache_head *h)
  633. {
  634. struct svc_export *exp;
  635. bool export_stats = is_export_stats_file(m);
  636. if (h == NULL) {
  637. if (export_stats)
  638. seq_puts(m, "#path domain start-time\n#\tstats\n");
  639. else
  640. seq_puts(m, "#path domain(flags)\n");
  641. return 0;
  642. }
  643. exp = container_of(h, struct svc_export, h);
  644. seq_path(m, &exp->ex_path, " \t\n\\");
  645. seq_putc(m, '\t');
  646. seq_escape(m, exp->ex_client->name, " \t\n\\");
  647. if (export_stats) {
  648. seq_printf(m, "\t%lld\n", exp->ex_stats.start_time);
  649. seq_printf(m, "\tfh_stale: %lld\n",
  650. percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_FH_STALE]));
  651. seq_printf(m, "\tio_read: %lld\n",
  652. percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_READ]));
  653. seq_printf(m, "\tio_write: %lld\n",
  654. percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_WRITE]));
  655. seq_putc(m, '\n');
  656. return 0;
  657. }
  658. seq_putc(m, '(');
  659. if (test_bit(CACHE_VALID, &h->flags) &&
  660. !test_bit(CACHE_NEGATIVE, &h->flags)) {
  661. exp_flags(m, exp->ex_flags, exp->ex_fsid,
  662. exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
  663. if (exp->ex_uuid) {
  664. int i;
  665. seq_puts(m, ",uuid=");
  666. for (i = 0; i < EX_UUID_LEN; i++) {
  667. if ((i&3) == 0 && i)
  668. seq_putc(m, ':');
  669. seq_printf(m, "%02x", exp->ex_uuid[i]);
  670. }
  671. }
  672. show_secinfo(m, exp);
  673. }
  674. seq_puts(m, ")\n");
  675. return 0;
  676. }
  677. static int svc_export_match(struct cache_head *a, struct cache_head *b)
  678. {
  679. struct svc_export *orig = container_of(a, struct svc_export, h);
  680. struct svc_export *new = container_of(b, struct svc_export, h);
  681. return orig->ex_client == new->ex_client &&
  682. path_equal(&orig->ex_path, &new->ex_path);
  683. }
  684. static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
  685. {
  686. struct svc_export *new = container_of(cnew, struct svc_export, h);
  687. struct svc_export *item = container_of(citem, struct svc_export, h);
  688. kref_get(&item->ex_client->ref);
  689. new->ex_client = item->ex_client;
  690. new->ex_path = item->ex_path;
  691. path_get(&item->ex_path);
  692. new->ex_fslocs.locations = NULL;
  693. new->ex_fslocs.locations_count = 0;
  694. new->ex_fslocs.migrated = 0;
  695. new->ex_layout_types = 0;
  696. new->ex_uuid = NULL;
  697. new->cd = item->cd;
  698. export_stats_reset(&new->ex_stats);
  699. }
  700. static void export_update(struct cache_head *cnew, struct cache_head *citem)
  701. {
  702. struct svc_export *new = container_of(cnew, struct svc_export, h);
  703. struct svc_export *item = container_of(citem, struct svc_export, h);
  704. int i;
  705. new->ex_flags = item->ex_flags;
  706. new->ex_anon_uid = item->ex_anon_uid;
  707. new->ex_anon_gid = item->ex_anon_gid;
  708. new->ex_fsid = item->ex_fsid;
  709. new->ex_devid_map = item->ex_devid_map;
  710. item->ex_devid_map = NULL;
  711. new->ex_uuid = item->ex_uuid;
  712. item->ex_uuid = NULL;
  713. new->ex_fslocs.locations = item->ex_fslocs.locations;
  714. item->ex_fslocs.locations = NULL;
  715. new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
  716. item->ex_fslocs.locations_count = 0;
  717. new->ex_fslocs.migrated = item->ex_fslocs.migrated;
  718. item->ex_fslocs.migrated = 0;
  719. new->ex_layout_types = item->ex_layout_types;
  720. new->ex_nflavors = item->ex_nflavors;
  721. for (i = 0; i < MAX_SECINFO_LIST; i++) {
  722. new->ex_flavors[i] = item->ex_flavors[i];
  723. }
  724. }
  725. static struct cache_head *svc_export_alloc(void)
  726. {
  727. struct svc_export *i = kmalloc(sizeof(*i), GFP_KERNEL);
  728. if (!i)
  729. return NULL;
  730. if (export_stats_init(&i->ex_stats)) {
  731. kfree(i);
  732. return NULL;
  733. }
  734. return &i->h;
  735. }
  736. static const struct cache_detail svc_export_cache_template = {
  737. .owner = THIS_MODULE,
  738. .hash_size = EXPORT_HASHMAX,
  739. .name = "nfsd.export",
  740. .cache_put = svc_export_put,
  741. .cache_upcall = svc_export_upcall,
  742. .cache_request = svc_export_request,
  743. .cache_parse = svc_export_parse,
  744. .cache_show = svc_export_show,
  745. .match = svc_export_match,
  746. .init = svc_export_init,
  747. .update = export_update,
  748. .alloc = svc_export_alloc,
  749. };
  750. static int
  751. svc_export_hash(struct svc_export *exp)
  752. {
  753. int hash;
  754. hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
  755. hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS);
  756. hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS);
  757. return hash;
  758. }
  759. static struct svc_export *
  760. svc_export_lookup(struct svc_export *exp)
  761. {
  762. struct cache_head *ch;
  763. int hash = svc_export_hash(exp);
  764. ch = sunrpc_cache_lookup_rcu(exp->cd, &exp->h, hash);
  765. if (ch)
  766. return container_of(ch, struct svc_export, h);
  767. else
  768. return NULL;
  769. }
  770. static struct svc_export *
  771. svc_export_update(struct svc_export *new, struct svc_export *old)
  772. {
  773. struct cache_head *ch;
  774. int hash = svc_export_hash(old);
  775. ch = sunrpc_cache_update(old->cd, &new->h, &old->h, hash);
  776. if (ch)
  777. return container_of(ch, struct svc_export, h);
  778. else
  779. return NULL;
  780. }
  781. static struct svc_expkey *
  782. exp_find_key(struct cache_detail *cd, struct auth_domain *clp, int fsid_type,
  783. u32 *fsidv, struct cache_req *reqp)
  784. {
  785. struct svc_expkey key, *ek;
  786. int err;
  787. if (!clp)
  788. return ERR_PTR(-ENOENT);
  789. key.ek_client = clp;
  790. key.ek_fsidtype = fsid_type;
  791. memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
  792. ek = svc_expkey_lookup(cd, &key);
  793. if (ek == NULL)
  794. return ERR_PTR(-ENOMEM);
  795. err = cache_check(cd, &ek->h, reqp);
  796. if (err) {
  797. trace_nfsd_exp_find_key(&key, err);
  798. return ERR_PTR(err);
  799. }
  800. return ek;
  801. }
  802. static struct svc_export *
  803. exp_get_by_name(struct cache_detail *cd, struct auth_domain *clp,
  804. const struct path *path, struct cache_req *reqp)
  805. {
  806. struct svc_export *exp, key;
  807. int err;
  808. if (!clp)
  809. return ERR_PTR(-ENOENT);
  810. key.ex_client = clp;
  811. key.ex_path = *path;
  812. key.cd = cd;
  813. exp = svc_export_lookup(&key);
  814. if (exp == NULL)
  815. return ERR_PTR(-ENOMEM);
  816. err = cache_check(cd, &exp->h, reqp);
  817. if (err) {
  818. trace_nfsd_exp_get_by_name(&key, err);
  819. return ERR_PTR(err);
  820. }
  821. return exp;
  822. }
  823. /*
  824. * Find the export entry for a given dentry.
  825. */
  826. static struct svc_export *
  827. exp_parent(struct cache_detail *cd, struct auth_domain *clp, struct path *path)
  828. {
  829. struct dentry *saved = dget(path->dentry);
  830. struct svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
  831. while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
  832. struct dentry *parent = dget_parent(path->dentry);
  833. dput(path->dentry);
  834. path->dentry = parent;
  835. exp = exp_get_by_name(cd, clp, path, NULL);
  836. }
  837. dput(path->dentry);
  838. path->dentry = saved;
  839. return exp;
  840. }
  841. /*
  842. * Obtain the root fh on behalf of a client.
  843. * This could be done in user space, but I feel that it adds some safety
  844. * since its harder to fool a kernel module than a user space program.
  845. */
  846. int
  847. exp_rootfh(struct net *net, struct auth_domain *clp, char *name,
  848. struct knfsd_fh *f, int maxsize)
  849. {
  850. struct svc_export *exp;
  851. struct path path;
  852. struct inode *inode;
  853. struct svc_fh fh;
  854. int err;
  855. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  856. struct cache_detail *cd = nn->svc_export_cache;
  857. err = -EPERM;
  858. /* NB: we probably ought to check that it's NUL-terminated */
  859. if (kern_path(name, 0, &path)) {
  860. printk("nfsd: exp_rootfh path not found %s", name);
  861. return err;
  862. }
  863. inode = d_inode(path.dentry);
  864. dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
  865. name, path.dentry, clp->name,
  866. inode->i_sb->s_id, inode->i_ino);
  867. exp = exp_parent(cd, clp, &path);
  868. if (IS_ERR(exp)) {
  869. err = PTR_ERR(exp);
  870. goto out;
  871. }
  872. /*
  873. * fh must be initialized before calling fh_compose
  874. */
  875. fh_init(&fh, maxsize);
  876. if (fh_compose(&fh, exp, path.dentry, NULL))
  877. err = -EINVAL;
  878. else
  879. err = 0;
  880. memcpy(f, &fh.fh_handle, sizeof(struct knfsd_fh));
  881. fh_put(&fh);
  882. exp_put(exp);
  883. out:
  884. path_put(&path);
  885. return err;
  886. }
  887. static struct svc_export *exp_find(struct cache_detail *cd,
  888. struct auth_domain *clp, int fsid_type,
  889. u32 *fsidv, struct cache_req *reqp)
  890. {
  891. struct svc_export *exp;
  892. struct nfsd_net *nn = net_generic(cd->net, nfsd_net_id);
  893. struct svc_expkey *ek = exp_find_key(nn->svc_expkey_cache, clp, fsid_type, fsidv, reqp);
  894. if (IS_ERR(ek))
  895. return ERR_CAST(ek);
  896. exp = exp_get_by_name(cd, clp, &ek->ek_path, reqp);
  897. cache_put(&ek->h, nn->svc_expkey_cache);
  898. if (IS_ERR(exp))
  899. return ERR_CAST(exp);
  900. return exp;
  901. }
  902. __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
  903. {
  904. struct exp_flavor_info *f;
  905. struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
  906. /* legacy gss-only clients are always OK: */
  907. if (exp->ex_client == rqstp->rq_gssclient)
  908. return 0;
  909. /* ip-address based client; check sec= export option: */
  910. for (f = exp->ex_flavors; f < end; f++) {
  911. if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
  912. return 0;
  913. }
  914. /* defaults in absence of sec= options: */
  915. if (exp->ex_nflavors == 0) {
  916. if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
  917. rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)
  918. return 0;
  919. }
  920. /* If the compound op contains a spo_must_allowed op,
  921. * it will be sent with integrity/protection which
  922. * will have to be expressly allowed on mounts that
  923. * don't support it
  924. */
  925. if (nfsd4_spo_must_allow(rqstp))
  926. return 0;
  927. return rqstp->rq_vers < 4 ? nfserr_acces : nfserr_wrongsec;
  928. }
  929. /*
  930. * Uses rq_client and rq_gssclient to find an export; uses rq_client (an
  931. * auth_unix client) if it's available and has secinfo information;
  932. * otherwise, will try to use rq_gssclient.
  933. *
  934. * Called from functions that handle requests; functions that do work on
  935. * behalf of mountd are passed a single client name to use, and should
  936. * use exp_get_by_name() or exp_find().
  937. */
  938. struct svc_export *
  939. rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
  940. {
  941. struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
  942. struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
  943. struct cache_detail *cd = nn->svc_export_cache;
  944. if (rqstp->rq_client == NULL)
  945. goto gss;
  946. /* First try the auth_unix client: */
  947. exp = exp_get_by_name(cd, rqstp->rq_client, path, &rqstp->rq_chandle);
  948. if (PTR_ERR(exp) == -ENOENT)
  949. goto gss;
  950. if (IS_ERR(exp))
  951. return exp;
  952. /* If it has secinfo, assume there are no gss/... clients */
  953. if (exp->ex_nflavors > 0)
  954. return exp;
  955. gss:
  956. /* Otherwise, try falling back on gss client */
  957. if (rqstp->rq_gssclient == NULL)
  958. return exp;
  959. gssexp = exp_get_by_name(cd, rqstp->rq_gssclient, path, &rqstp->rq_chandle);
  960. if (PTR_ERR(gssexp) == -ENOENT)
  961. return exp;
  962. if (!IS_ERR(exp))
  963. exp_put(exp);
  964. return gssexp;
  965. }
  966. struct svc_export *
  967. rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
  968. {
  969. struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
  970. struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
  971. struct cache_detail *cd = nn->svc_export_cache;
  972. if (rqstp->rq_client == NULL)
  973. goto gss;
  974. /* First try the auth_unix client: */
  975. exp = exp_find(cd, rqstp->rq_client, fsid_type,
  976. fsidv, &rqstp->rq_chandle);
  977. if (PTR_ERR(exp) == -ENOENT)
  978. goto gss;
  979. if (IS_ERR(exp))
  980. return exp;
  981. /* If it has secinfo, assume there are no gss/... clients */
  982. if (exp->ex_nflavors > 0)
  983. return exp;
  984. gss:
  985. /* Otherwise, try falling back on gss client */
  986. if (rqstp->rq_gssclient == NULL)
  987. return exp;
  988. gssexp = exp_find(cd, rqstp->rq_gssclient, fsid_type, fsidv,
  989. &rqstp->rq_chandle);
  990. if (PTR_ERR(gssexp) == -ENOENT)
  991. return exp;
  992. if (!IS_ERR(exp))
  993. exp_put(exp);
  994. return gssexp;
  995. }
  996. struct svc_export *
  997. rqst_exp_parent(struct svc_rqst *rqstp, struct path *path)
  998. {
  999. struct dentry *saved = dget(path->dentry);
  1000. struct svc_export *exp = rqst_exp_get_by_name(rqstp, path);
  1001. while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
  1002. struct dentry *parent = dget_parent(path->dentry);
  1003. dput(path->dentry);
  1004. path->dentry = parent;
  1005. exp = rqst_exp_get_by_name(rqstp, path);
  1006. }
  1007. dput(path->dentry);
  1008. path->dentry = saved;
  1009. return exp;
  1010. }
  1011. struct svc_export *rqst_find_fsidzero_export(struct svc_rqst *rqstp)
  1012. {
  1013. u32 fsidv[2];
  1014. mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL);
  1015. return rqst_exp_find(rqstp, FSID_NUM, fsidv);
  1016. }
  1017. /*
  1018. * Called when we need the filehandle for the root of the pseudofs,
  1019. * for a given NFSv4 client. The root is defined to be the
  1020. * export point with fsid==0
  1021. */
  1022. __be32
  1023. exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
  1024. {
  1025. struct svc_export *exp;
  1026. __be32 rv;
  1027. exp = rqst_find_fsidzero_export(rqstp);
  1028. if (IS_ERR(exp))
  1029. return nfserrno(PTR_ERR(exp));
  1030. rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL);
  1031. exp_put(exp);
  1032. return rv;
  1033. }
  1034. static struct flags {
  1035. int flag;
  1036. char *name[2];
  1037. } expflags[] = {
  1038. { NFSEXP_READONLY, {"ro", "rw"}},
  1039. { NFSEXP_INSECURE_PORT, {"insecure", ""}},
  1040. { NFSEXP_ROOTSQUASH, {"root_squash", "no_root_squash"}},
  1041. { NFSEXP_ALLSQUASH, {"all_squash", ""}},
  1042. { NFSEXP_ASYNC, {"async", "sync"}},
  1043. { NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}},
  1044. { NFSEXP_NOREADDIRPLUS, {"nordirplus", ""}},
  1045. { NFSEXP_NOHIDE, {"nohide", ""}},
  1046. { NFSEXP_CROSSMOUNT, {"crossmnt", ""}},
  1047. { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
  1048. { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
  1049. { NFSEXP_V4ROOT, {"v4root", ""}},
  1050. { NFSEXP_PNFS, {"pnfs", ""}},
  1051. { NFSEXP_SECURITY_LABEL, {"security_label", ""}},
  1052. { 0, {"", ""}}
  1053. };
  1054. static void show_expflags(struct seq_file *m, int flags, int mask)
  1055. {
  1056. struct flags *flg;
  1057. int state, first = 0;
  1058. for (flg = expflags; flg->flag; flg++) {
  1059. if (flg->flag & ~mask)
  1060. continue;
  1061. state = (flg->flag & flags) ? 0 : 1;
  1062. if (*flg->name[state])
  1063. seq_printf(m, "%s%s", first++?",":"", flg->name[state]);
  1064. }
  1065. }
  1066. static void show_secinfo_flags(struct seq_file *m, int flags)
  1067. {
  1068. seq_printf(m, ",");
  1069. show_expflags(m, flags, NFSEXP_SECINFO_FLAGS);
  1070. }
  1071. static bool secinfo_flags_equal(int f, int g)
  1072. {
  1073. f &= NFSEXP_SECINFO_FLAGS;
  1074. g &= NFSEXP_SECINFO_FLAGS;
  1075. return f == g;
  1076. }
  1077. static int show_secinfo_run(struct seq_file *m, struct exp_flavor_info **fp, struct exp_flavor_info *end)
  1078. {
  1079. int flags;
  1080. flags = (*fp)->flags;
  1081. seq_printf(m, ",sec=%d", (*fp)->pseudoflavor);
  1082. (*fp)++;
  1083. while (*fp != end && secinfo_flags_equal(flags, (*fp)->flags)) {
  1084. seq_printf(m, ":%d", (*fp)->pseudoflavor);
  1085. (*fp)++;
  1086. }
  1087. return flags;
  1088. }
  1089. static void show_secinfo(struct seq_file *m, struct svc_export *exp)
  1090. {
  1091. struct exp_flavor_info *f;
  1092. struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
  1093. int flags;
  1094. if (exp->ex_nflavors == 0)
  1095. return;
  1096. f = exp->ex_flavors;
  1097. flags = show_secinfo_run(m, &f, end);
  1098. if (!secinfo_flags_equal(flags, exp->ex_flags))
  1099. show_secinfo_flags(m, flags);
  1100. while (f != end) {
  1101. flags = show_secinfo_run(m, &f, end);
  1102. show_secinfo_flags(m, flags);
  1103. }
  1104. }
  1105. static void exp_flags(struct seq_file *m, int flag, int fsid,
  1106. kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
  1107. {
  1108. struct user_namespace *userns = m->file->f_cred->user_ns;
  1109. show_expflags(m, flag, NFSEXP_ALLFLAGS);
  1110. if (flag & NFSEXP_FSID)
  1111. seq_printf(m, ",fsid=%d", fsid);
  1112. if (!uid_eq(anonu, make_kuid(userns, (uid_t)-2)) &&
  1113. !uid_eq(anonu, make_kuid(userns, 0x10000-2)))
  1114. seq_printf(m, ",anonuid=%u", from_kuid_munged(userns, anonu));
  1115. if (!gid_eq(anong, make_kgid(userns, (gid_t)-2)) &&
  1116. !gid_eq(anong, make_kgid(userns, 0x10000-2)))
  1117. seq_printf(m, ",anongid=%u", from_kgid_munged(userns, anong));
  1118. if (fsloc && fsloc->locations_count > 0) {
  1119. char *loctype = (fsloc->migrated) ? "refer" : "replicas";
  1120. int i;
  1121. seq_printf(m, ",%s=", loctype);
  1122. seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
  1123. seq_putc(m, '@');
  1124. seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
  1125. for (i = 1; i < fsloc->locations_count; i++) {
  1126. seq_putc(m, ';');
  1127. seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
  1128. seq_putc(m, '@');
  1129. seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
  1130. }
  1131. }
  1132. }
  1133. static int e_show(struct seq_file *m, void *p)
  1134. {
  1135. struct cache_head *cp = p;
  1136. struct svc_export *exp = container_of(cp, struct svc_export, h);
  1137. struct cache_detail *cd = m->private;
  1138. bool export_stats = is_export_stats_file(m);
  1139. if (p == SEQ_START_TOKEN) {
  1140. seq_puts(m, "# Version 1.1\n");
  1141. if (export_stats)
  1142. seq_puts(m, "# Path Client Start-time\n#\tStats\n");
  1143. else
  1144. seq_puts(m, "# Path Client(Flags) # IPs\n");
  1145. return 0;
  1146. }
  1147. exp_get(exp);
  1148. if (cache_check(cd, &exp->h, NULL))
  1149. return 0;
  1150. exp_put(exp);
  1151. return svc_export_show(m, cd, cp);
  1152. }
  1153. const struct seq_operations nfs_exports_op = {
  1154. .start = cache_seq_start_rcu,
  1155. .next = cache_seq_next_rcu,
  1156. .stop = cache_seq_stop_rcu,
  1157. .show = e_show,
  1158. };
  1159. /*
  1160. * Initialize the exports module.
  1161. */
  1162. int
  1163. nfsd_export_init(struct net *net)
  1164. {
  1165. int rv;
  1166. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  1167. dprintk("nfsd: initializing export module (net: %x).\n", net->ns.inum);
  1168. nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net);
  1169. if (IS_ERR(nn->svc_export_cache))
  1170. return PTR_ERR(nn->svc_export_cache);
  1171. rv = cache_register_net(nn->svc_export_cache, net);
  1172. if (rv)
  1173. goto destroy_export_cache;
  1174. nn->svc_expkey_cache = cache_create_net(&svc_expkey_cache_template, net);
  1175. if (IS_ERR(nn->svc_expkey_cache)) {
  1176. rv = PTR_ERR(nn->svc_expkey_cache);
  1177. goto unregister_export_cache;
  1178. }
  1179. rv = cache_register_net(nn->svc_expkey_cache, net);
  1180. if (rv)
  1181. goto destroy_expkey_cache;
  1182. return 0;
  1183. destroy_expkey_cache:
  1184. cache_destroy_net(nn->svc_expkey_cache, net);
  1185. unregister_export_cache:
  1186. cache_unregister_net(nn->svc_export_cache, net);
  1187. destroy_export_cache:
  1188. cache_destroy_net(nn->svc_export_cache, net);
  1189. return rv;
  1190. }
  1191. /*
  1192. * Flush exports table - called when last nfsd thread is killed
  1193. */
  1194. void
  1195. nfsd_export_flush(struct net *net)
  1196. {
  1197. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  1198. cache_purge(nn->svc_expkey_cache);
  1199. cache_purge(nn->svc_export_cache);
  1200. }
  1201. /*
  1202. * Shutdown the exports module.
  1203. */
  1204. void
  1205. nfsd_export_shutdown(struct net *net)
  1206. {
  1207. struct nfsd_net *nn = net_generic(net, nfsd_net_id);
  1208. dprintk("nfsd: shutting down export module (net: %x).\n", net->ns.inum);
  1209. cache_unregister_net(nn->svc_expkey_cache, net);
  1210. cache_unregister_net(nn->svc_export_cache, net);
  1211. cache_destroy_net(nn->svc_expkey_cache, net);
  1212. cache_destroy_net(nn->svc_export_cache, net);
  1213. svcauth_unix_purge(net);
  1214. dprintk("nfsd: export shutdown complete (net: %x).\n", net->ns.inum);
  1215. }