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