Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ovl-update-6.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs

Pull more overlayfs updates from Amir Goldstein:
"This is a small 'move code around' followup by Christian to his work
on porting overlayfs to the new mount api for 6.5. It makes things a
bit cleaner and simpler for the next development cycle when I hand
overlayfs back over to Miklos"

* tag 'ovl-update-6.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/overlayfs/vfs:
ovl: move all parameter handling into params.{c,h}

+581 -564
+9 -32
fs/overlayfs/overlayfs.h
··· 70 70 OVL_XINO_ON, 71 71 }; 72 72 73 - /* The set of options that user requested explicitly via mount options */ 74 - struct ovl_opt_set { 75 - bool metacopy; 76 - bool redirect; 77 - bool nfs_export; 78 - bool index; 79 - }; 80 - 81 73 /* 82 74 * The tuple (fh,uuid) is a universal unique identifier for a copy up origin, 83 75 * where: ··· 359 367 360 368 return ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC)); 361 369 } 362 - 363 - 364 - /* params.c */ 365 - #define OVL_MAX_STACK 500 366 - 367 - struct ovl_fs_context_layer { 368 - char *name; 369 - struct path path; 370 - }; 371 - 372 - struct ovl_fs_context { 373 - struct path upper; 374 - struct path work; 375 - size_t capacity; 376 - size_t nr; /* includes nr_data */ 377 - size_t nr_data; 378 - struct ovl_opt_set set; 379 - struct ovl_fs_context_layer *lower; 380 - }; 381 - 382 - int ovl_parse_param_upperdir(const char *name, struct fs_context *fc, 383 - bool workdir); 384 - int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc); 385 - void ovl_parse_param_drop_lowerdir(struct ovl_fs_context *ctx); 386 370 387 371 /* util.c */ 388 372 int ovl_want_write(struct dentry *dentry); ··· 759 791 760 792 /* export.c */ 761 793 extern const struct export_operations ovl_export_operations; 794 + 795 + /* super.c */ 796 + int ovl_fill_super(struct super_block *sb, struct fs_context *fc); 797 + 798 + /* Will this overlay be forced to mount/remount ro? */ 799 + static inline bool ovl_force_readonly(struct ovl_fs *ofs) 800 + { 801 + return (!ovl_upper_mnt(ofs) || !ofs->workdir); 802 + }
+528 -4
fs/overlayfs/params.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 #include <linux/fs.h> 4 + #include <linux/module.h> 4 5 #include <linux/namei.h> 5 6 #include <linux/fs_context.h> 6 7 #include <linux/fs_parser.h> 7 8 #include <linux/posix_acl_xattr.h> 9 + #include <linux/seq_file.h> 8 10 #include <linux/xattr.h> 9 11 #include "overlayfs.h" 12 + #include "params.h" 13 + 14 + static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR); 15 + module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644); 16 + MODULE_PARM_DESC(redirect_dir, 17 + "Default to on or off for the redirect_dir feature"); 18 + 19 + static bool ovl_redirect_always_follow = 20 + IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW); 21 + module_param_named(redirect_always_follow, ovl_redirect_always_follow, 22 + bool, 0644); 23 + MODULE_PARM_DESC(redirect_always_follow, 24 + "Follow redirects even if redirect_dir feature is turned off"); 25 + 26 + static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO); 27 + module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644); 28 + MODULE_PARM_DESC(xino_auto, 29 + "Auto enable xino feature"); 30 + 31 + static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX); 32 + module_param_named(index, ovl_index_def, bool, 0644); 33 + MODULE_PARM_DESC(index, 34 + "Default to on or off for the inodes index feature"); 35 + 36 + static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT); 37 + module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644); 38 + MODULE_PARM_DESC(nfs_export, 39 + "Default to on or off for the NFS export feature"); 40 + 41 + static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY); 42 + module_param_named(metacopy, ovl_metacopy_def, bool, 0644); 43 + MODULE_PARM_DESC(metacopy, 44 + "Default to on or off for the metadata only copy up feature"); 45 + 46 + enum { 47 + Opt_lowerdir, 48 + Opt_upperdir, 49 + Opt_workdir, 50 + Opt_default_permissions, 51 + Opt_redirect_dir, 52 + Opt_index, 53 + Opt_uuid, 54 + Opt_nfs_export, 55 + Opt_userxattr, 56 + Opt_xino, 57 + Opt_metacopy, 58 + Opt_volatile, 59 + }; 60 + 61 + static const struct constant_table ovl_parameter_bool[] = { 62 + { "on", true }, 63 + { "off", false }, 64 + {} 65 + }; 66 + 67 + static const struct constant_table ovl_parameter_xino[] = { 68 + { "off", OVL_XINO_OFF }, 69 + { "auto", OVL_XINO_AUTO }, 70 + { "on", OVL_XINO_ON }, 71 + {} 72 + }; 73 + 74 + const char *ovl_xino_mode(struct ovl_config *config) 75 + { 76 + return ovl_parameter_xino[config->xino].name; 77 + } 78 + 79 + static int ovl_xino_def(void) 80 + { 81 + return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF; 82 + } 83 + 84 + const struct constant_table ovl_parameter_redirect_dir[] = { 85 + { "off", OVL_REDIRECT_OFF }, 86 + { "follow", OVL_REDIRECT_FOLLOW }, 87 + { "nofollow", OVL_REDIRECT_NOFOLLOW }, 88 + { "on", OVL_REDIRECT_ON }, 89 + {} 90 + }; 91 + 92 + static const char *ovl_redirect_mode(struct ovl_config *config) 93 + { 94 + return ovl_parameter_redirect_dir[config->redirect_mode].name; 95 + } 96 + 97 + static int ovl_redirect_mode_def(void) 98 + { 99 + return ovl_redirect_dir_def ? OVL_REDIRECT_ON : 100 + ovl_redirect_always_follow ? OVL_REDIRECT_FOLLOW : 101 + OVL_REDIRECT_NOFOLLOW; 102 + } 103 + 104 + #define fsparam_string_empty(NAME, OPT) \ 105 + __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL) 106 + 107 + const struct fs_parameter_spec ovl_parameter_spec[] = { 108 + fsparam_string_empty("lowerdir", Opt_lowerdir), 109 + fsparam_string("upperdir", Opt_upperdir), 110 + fsparam_string("workdir", Opt_workdir), 111 + fsparam_flag("default_permissions", Opt_default_permissions), 112 + fsparam_enum("redirect_dir", Opt_redirect_dir, ovl_parameter_redirect_dir), 113 + fsparam_enum("index", Opt_index, ovl_parameter_bool), 114 + fsparam_enum("uuid", Opt_uuid, ovl_parameter_bool), 115 + fsparam_enum("nfs_export", Opt_nfs_export, ovl_parameter_bool), 116 + fsparam_flag("userxattr", Opt_userxattr), 117 + fsparam_enum("xino", Opt_xino, ovl_parameter_xino), 118 + fsparam_enum("metacopy", Opt_metacopy, ovl_parameter_bool), 119 + fsparam_flag("volatile", Opt_volatile), 120 + {} 121 + }; 10 122 11 123 static ssize_t ovl_parse_param_split_lowerdirs(char *str) 12 124 { ··· 222 110 return err; 223 111 } 224 112 225 - int ovl_parse_param_upperdir(const char *name, struct fs_context *fc, 226 - bool workdir) 113 + static int ovl_parse_param_upperdir(const char *name, struct fs_context *fc, 114 + bool workdir) 227 115 { 228 116 int err; 229 117 struct ovl_fs *ofs = fc->s_fs_info; ··· 266 154 return 0; 267 155 } 268 156 269 - void ovl_parse_param_drop_lowerdir(struct ovl_fs_context *ctx) 157 + static void ovl_parse_param_drop_lowerdir(struct ovl_fs_context *ctx) 270 158 { 271 159 for (size_t nr = 0; nr < ctx->nr; nr++) { 272 160 path_put(&ctx->lower[nr].path); ··· 291 179 * Append data "/lower5" as data lower layer. This requires that 292 180 * there's at least one regular lower layer present. 293 181 */ 294 - int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc) 182 + static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc) 295 183 { 296 184 int err; 297 185 struct ovl_fs_context *ctx = fc->fs_private; ··· 498 386 499 387 /* Intentionally don't realloc to a smaller size. */ 500 388 return err; 389 + } 390 + 391 + static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param) 392 + { 393 + int err = 0; 394 + struct fs_parse_result result; 395 + struct ovl_fs *ofs = fc->s_fs_info; 396 + struct ovl_config *config = &ofs->config; 397 + struct ovl_fs_context *ctx = fc->fs_private; 398 + int opt; 399 + 400 + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { 401 + /* 402 + * On remount overlayfs has always ignored all mount 403 + * options no matter if malformed or not so for 404 + * backwards compatibility we do the same here. 405 + */ 406 + if (fc->oldapi) 407 + return 0; 408 + 409 + /* 410 + * Give us the freedom to allow changing mount options 411 + * with the new mount api in the future. So instead of 412 + * silently ignoring everything we report a proper 413 + * error. This is only visible for users of the new 414 + * mount api. 415 + */ 416 + return invalfc(fc, "No changes allowed in reconfigure"); 417 + } 418 + 419 + opt = fs_parse(fc, ovl_parameter_spec, param, &result); 420 + if (opt < 0) 421 + return opt; 422 + 423 + switch (opt) { 424 + case Opt_lowerdir: 425 + err = ovl_parse_param_lowerdir(param->string, fc); 426 + break; 427 + case Opt_upperdir: 428 + fallthrough; 429 + case Opt_workdir: 430 + err = ovl_parse_param_upperdir(param->string, fc, 431 + (Opt_workdir == opt)); 432 + break; 433 + case Opt_default_permissions: 434 + config->default_permissions = true; 435 + break; 436 + case Opt_redirect_dir: 437 + config->redirect_mode = result.uint_32; 438 + if (config->redirect_mode == OVL_REDIRECT_OFF) { 439 + config->redirect_mode = ovl_redirect_always_follow ? 440 + OVL_REDIRECT_FOLLOW : 441 + OVL_REDIRECT_NOFOLLOW; 442 + } 443 + ctx->set.redirect = true; 444 + break; 445 + case Opt_index: 446 + config->index = result.uint_32; 447 + ctx->set.index = true; 448 + break; 449 + case Opt_uuid: 450 + config->uuid = result.uint_32; 451 + break; 452 + case Opt_nfs_export: 453 + config->nfs_export = result.uint_32; 454 + ctx->set.nfs_export = true; 455 + break; 456 + case Opt_xino: 457 + config->xino = result.uint_32; 458 + break; 459 + case Opt_metacopy: 460 + config->metacopy = result.uint_32; 461 + ctx->set.metacopy = true; 462 + break; 463 + case Opt_volatile: 464 + config->ovl_volatile = true; 465 + break; 466 + case Opt_userxattr: 467 + config->userxattr = true; 468 + break; 469 + default: 470 + pr_err("unrecognized mount option \"%s\" or missing value\n", 471 + param->key); 472 + return -EINVAL; 473 + } 474 + 475 + return err; 476 + } 477 + 478 + static int ovl_get_tree(struct fs_context *fc) 479 + { 480 + return get_tree_nodev(fc, ovl_fill_super); 481 + } 482 + 483 + static inline void ovl_fs_context_free(struct ovl_fs_context *ctx) 484 + { 485 + ovl_parse_param_drop_lowerdir(ctx); 486 + path_put(&ctx->upper); 487 + path_put(&ctx->work); 488 + kfree(ctx->lower); 489 + kfree(ctx); 490 + } 491 + 492 + static void ovl_free(struct fs_context *fc) 493 + { 494 + struct ovl_fs *ofs = fc->s_fs_info; 495 + struct ovl_fs_context *ctx = fc->fs_private; 496 + 497 + /* 498 + * ofs is stored in the fs_context when it is initialized. 499 + * ofs is transferred to the superblock on a successful mount, 500 + * but if an error occurs before the transfer we have to free 501 + * it here. 502 + */ 503 + if (ofs) 504 + ovl_free_fs(ofs); 505 + 506 + if (ctx) 507 + ovl_fs_context_free(ctx); 508 + } 509 + 510 + static int ovl_reconfigure(struct fs_context *fc) 511 + { 512 + struct super_block *sb = fc->root->d_sb; 513 + struct ovl_fs *ofs = sb->s_fs_info; 514 + struct super_block *upper_sb; 515 + int ret = 0; 516 + 517 + if (!(fc->sb_flags & SB_RDONLY) && ovl_force_readonly(ofs)) 518 + return -EROFS; 519 + 520 + if (fc->sb_flags & SB_RDONLY && !sb_rdonly(sb)) { 521 + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; 522 + if (ovl_should_sync(ofs)) { 523 + down_read(&upper_sb->s_umount); 524 + ret = sync_filesystem(upper_sb); 525 + up_read(&upper_sb->s_umount); 526 + } 527 + } 528 + 529 + return ret; 530 + } 531 + 532 + static const struct fs_context_operations ovl_context_ops = { 533 + .parse_param = ovl_parse_param, 534 + .get_tree = ovl_get_tree, 535 + .reconfigure = ovl_reconfigure, 536 + .free = ovl_free, 537 + }; 538 + 539 + /* 540 + * This is called during fsopen() and will record the user namespace of 541 + * the caller in fc->user_ns since we've raised FS_USERNS_MOUNT. We'll 542 + * need it when we actually create the superblock to verify that the 543 + * process creating the superblock is in the same user namespace as 544 + * process that called fsopen(). 545 + */ 546 + int ovl_init_fs_context(struct fs_context *fc) 547 + { 548 + struct ovl_fs_context *ctx; 549 + struct ovl_fs *ofs; 550 + 551 + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); 552 + if (!ctx) 553 + return -ENOMEM; 554 + 555 + /* 556 + * By default we allocate for three lower layers. It's likely 557 + * that it'll cover most users. 558 + */ 559 + ctx->lower = kmalloc_array(3, sizeof(*ctx->lower), GFP_KERNEL_ACCOUNT); 560 + if (!ctx->lower) 561 + goto out_err; 562 + ctx->capacity = 3; 563 + 564 + ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); 565 + if (!ofs) 566 + goto out_err; 567 + 568 + ofs->config.redirect_mode = ovl_redirect_mode_def(); 569 + ofs->config.index = ovl_index_def; 570 + ofs->config.uuid = true; 571 + ofs->config.nfs_export = ovl_nfs_export_def; 572 + ofs->config.xino = ovl_xino_def(); 573 + ofs->config.metacopy = ovl_metacopy_def; 574 + 575 + fc->s_fs_info = ofs; 576 + fc->fs_private = ctx; 577 + fc->ops = &ovl_context_ops; 578 + return 0; 579 + 580 + out_err: 581 + ovl_fs_context_free(ctx); 582 + return -ENOMEM; 583 + 584 + } 585 + 586 + void ovl_free_fs(struct ovl_fs *ofs) 587 + { 588 + struct vfsmount **mounts; 589 + unsigned i; 590 + 591 + iput(ofs->workbasedir_trap); 592 + iput(ofs->indexdir_trap); 593 + iput(ofs->workdir_trap); 594 + dput(ofs->whiteout); 595 + dput(ofs->indexdir); 596 + dput(ofs->workdir); 597 + if (ofs->workdir_locked) 598 + ovl_inuse_unlock(ofs->workbasedir); 599 + dput(ofs->workbasedir); 600 + if (ofs->upperdir_locked) 601 + ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); 602 + 603 + /* Hack! Reuse ofs->layers as a vfsmount array before freeing it */ 604 + mounts = (struct vfsmount **) ofs->layers; 605 + for (i = 0; i < ofs->numlayer; i++) { 606 + iput(ofs->layers[i].trap); 607 + mounts[i] = ofs->layers[i].mnt; 608 + kfree(ofs->layers[i].name); 609 + } 610 + kern_unmount_array(mounts, ofs->numlayer); 611 + kfree(ofs->layers); 612 + for (i = 0; i < ofs->numfs; i++) 613 + free_anon_bdev(ofs->fs[i].pseudo_dev); 614 + kfree(ofs->fs); 615 + 616 + kfree(ofs->config.upperdir); 617 + kfree(ofs->config.workdir); 618 + if (ofs->creator_cred) 619 + put_cred(ofs->creator_cred); 620 + kfree(ofs); 621 + } 622 + 623 + int ovl_fs_params_verify(const struct ovl_fs_context *ctx, 624 + struct ovl_config *config) 625 + { 626 + struct ovl_opt_set set = ctx->set; 627 + 628 + if (ctx->nr_data > 0 && !config->metacopy) { 629 + pr_err("lower data-only dirs require metacopy support.\n"); 630 + return -EINVAL; 631 + } 632 + 633 + /* Workdir/index are useless in non-upper mount */ 634 + if (!config->upperdir) { 635 + if (config->workdir) { 636 + pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n", 637 + config->workdir); 638 + kfree(config->workdir); 639 + config->workdir = NULL; 640 + } 641 + if (config->index && set.index) { 642 + pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n"); 643 + set.index = false; 644 + } 645 + config->index = false; 646 + } 647 + 648 + if (!config->upperdir && config->ovl_volatile) { 649 + pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n"); 650 + config->ovl_volatile = false; 651 + } 652 + 653 + /* 654 + * This is to make the logic below simpler. It doesn't make any other 655 + * difference, since redirect_dir=on is only used for upper. 656 + */ 657 + if (!config->upperdir && config->redirect_mode == OVL_REDIRECT_FOLLOW) 658 + config->redirect_mode = OVL_REDIRECT_ON; 659 + 660 + /* Resolve metacopy -> redirect_dir dependency */ 661 + if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) { 662 + if (set.metacopy && set.redirect) { 663 + pr_err("conflicting options: metacopy=on,redirect_dir=%s\n", 664 + ovl_redirect_mode(config)); 665 + return -EINVAL; 666 + } 667 + if (set.redirect) { 668 + /* 669 + * There was an explicit redirect_dir=... that resulted 670 + * in this conflict. 671 + */ 672 + pr_info("disabling metacopy due to redirect_dir=%s\n", 673 + ovl_redirect_mode(config)); 674 + config->metacopy = false; 675 + } else { 676 + /* Automatically enable redirect otherwise. */ 677 + config->redirect_mode = OVL_REDIRECT_ON; 678 + } 679 + } 680 + 681 + /* Resolve nfs_export -> index dependency */ 682 + if (config->nfs_export && !config->index) { 683 + if (!config->upperdir && 684 + config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { 685 + pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n"); 686 + config->nfs_export = false; 687 + } else if (set.nfs_export && set.index) { 688 + pr_err("conflicting options: nfs_export=on,index=off\n"); 689 + return -EINVAL; 690 + } else if (set.index) { 691 + /* 692 + * There was an explicit index=off that resulted 693 + * in this conflict. 694 + */ 695 + pr_info("disabling nfs_export due to index=off\n"); 696 + config->nfs_export = false; 697 + } else { 698 + /* Automatically enable index otherwise. */ 699 + config->index = true; 700 + } 701 + } 702 + 703 + /* Resolve nfs_export -> !metacopy dependency */ 704 + if (config->nfs_export && config->metacopy) { 705 + if (set.nfs_export && set.metacopy) { 706 + pr_err("conflicting options: nfs_export=on,metacopy=on\n"); 707 + return -EINVAL; 708 + } 709 + if (set.metacopy) { 710 + /* 711 + * There was an explicit metacopy=on that resulted 712 + * in this conflict. 713 + */ 714 + pr_info("disabling nfs_export due to metacopy=on\n"); 715 + config->nfs_export = false; 716 + } else { 717 + /* 718 + * There was an explicit nfs_export=on that resulted 719 + * in this conflict. 720 + */ 721 + pr_info("disabling metacopy due to nfs_export=on\n"); 722 + config->metacopy = false; 723 + } 724 + } 725 + 726 + 727 + /* Resolve userxattr -> !redirect && !metacopy dependency */ 728 + if (config->userxattr) { 729 + if (set.redirect && 730 + config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { 731 + pr_err("conflicting options: userxattr,redirect_dir=%s\n", 732 + ovl_redirect_mode(config)); 733 + return -EINVAL; 734 + } 735 + if (config->metacopy && set.metacopy) { 736 + pr_err("conflicting options: userxattr,metacopy=on\n"); 737 + return -EINVAL; 738 + } 739 + /* 740 + * Silently disable default setting of redirect and metacopy. 741 + * This shall be the default in the future as well: these 742 + * options must be explicitly enabled if used together with 743 + * userxattr. 744 + */ 745 + config->redirect_mode = OVL_REDIRECT_NOFOLLOW; 746 + config->metacopy = false; 747 + } 748 + 749 + return 0; 750 + } 751 + 752 + /** 753 + * ovl_show_options 754 + * @m: the seq_file handle 755 + * @dentry: The dentry to query 756 + * 757 + * Prints the mount options for a given superblock. 758 + * Returns zero; does not fail. 759 + */ 760 + int ovl_show_options(struct seq_file *m, struct dentry *dentry) 761 + { 762 + struct super_block *sb = dentry->d_sb; 763 + struct ovl_fs *ofs = sb->s_fs_info; 764 + size_t nr, nr_merged_lower = ofs->numlayer - ofs->numdatalayer; 765 + const struct ovl_layer *data_layers = &ofs->layers[nr_merged_lower]; 766 + 767 + /* ofs->layers[0] is the upper layer */ 768 + seq_printf(m, ",lowerdir=%s", ofs->layers[1].name); 769 + /* dump regular lower layers */ 770 + for (nr = 2; nr < nr_merged_lower; nr++) 771 + seq_printf(m, ":%s", ofs->layers[nr].name); 772 + /* dump data lower layers */ 773 + for (nr = 0; nr < ofs->numdatalayer; nr++) 774 + seq_printf(m, "::%s", data_layers[nr].name); 775 + if (ofs->config.upperdir) { 776 + seq_show_option(m, "upperdir", ofs->config.upperdir); 777 + seq_show_option(m, "workdir", ofs->config.workdir); 778 + } 779 + if (ofs->config.default_permissions) 780 + seq_puts(m, ",default_permissions"); 781 + if (ofs->config.redirect_mode != ovl_redirect_mode_def()) 782 + seq_printf(m, ",redirect_dir=%s", 783 + ovl_redirect_mode(&ofs->config)); 784 + if (ofs->config.index != ovl_index_def) 785 + seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off"); 786 + if (!ofs->config.uuid) 787 + seq_puts(m, ",uuid=off"); 788 + if (ofs->config.nfs_export != ovl_nfs_export_def) 789 + seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ? 790 + "on" : "off"); 791 + if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(ofs)) 792 + seq_printf(m, ",xino=%s", ovl_xino_mode(&ofs->config)); 793 + if (ofs->config.metacopy != ovl_metacopy_def) 794 + seq_printf(m, ",metacopy=%s", 795 + ofs->config.metacopy ? "on" : "off"); 796 + if (ofs->config.ovl_volatile) 797 + seq_puts(m, ",volatile"); 798 + if (ofs->config.userxattr) 799 + seq_puts(m, ",userxattr"); 800 + return 0; 501 801 }
+42
fs/overlayfs/params.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #include <linux/fs_context.h> 4 + #include <linux/fs_parser.h> 5 + 6 + struct ovl_fs; 7 + struct ovl_config; 8 + 9 + extern const struct fs_parameter_spec ovl_parameter_spec[]; 10 + extern const struct constant_table ovl_parameter_redirect_dir[]; 11 + 12 + /* The set of options that user requested explicitly via mount options */ 13 + struct ovl_opt_set { 14 + bool metacopy; 15 + bool redirect; 16 + bool nfs_export; 17 + bool index; 18 + }; 19 + 20 + #define OVL_MAX_STACK 500 21 + 22 + struct ovl_fs_context_layer { 23 + char *name; 24 + struct path path; 25 + }; 26 + 27 + struct ovl_fs_context { 28 + struct path upper; 29 + struct path work; 30 + size_t capacity; 31 + size_t nr; /* includes nr_data */ 32 + size_t nr_data; 33 + struct ovl_opt_set set; 34 + struct ovl_fs_context_layer *lower; 35 + }; 36 + 37 + int ovl_init_fs_context(struct fs_context *fc); 38 + void ovl_free_fs(struct ovl_fs *ofs); 39 + int ovl_fs_params_verify(const struct ovl_fs_context *ctx, 40 + struct ovl_config *config); 41 + int ovl_show_options(struct seq_file *m, struct dentry *dentry); 42 + const char *ovl_xino_mode(struct ovl_config *config);
+2 -528
fs/overlayfs/super.c
··· 19 19 #include <linux/fs_context.h> 20 20 #include <linux/fs_parser.h> 21 21 #include "overlayfs.h" 22 + #include "params.h" 22 23 23 24 MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); 24 25 MODULE_DESCRIPTION("Overlay filesystem"); ··· 27 26 28 27 29 28 struct ovl_dir_cache; 30 - 31 - static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR); 32 - module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644); 33 - MODULE_PARM_DESC(redirect_dir, 34 - "Default to on or off for the redirect_dir feature"); 35 - 36 - static bool ovl_redirect_always_follow = 37 - IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW); 38 - module_param_named(redirect_always_follow, ovl_redirect_always_follow, 39 - bool, 0644); 40 - MODULE_PARM_DESC(redirect_always_follow, 41 - "Follow redirects even if redirect_dir feature is turned off"); 42 - 43 - static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX); 44 - module_param_named(index, ovl_index_def, bool, 0644); 45 - MODULE_PARM_DESC(index, 46 - "Default to on or off for the inodes index feature"); 47 - 48 - static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT); 49 - module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644); 50 - MODULE_PARM_DESC(nfs_export, 51 - "Default to on or off for the NFS export feature"); 52 - 53 - static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO); 54 - module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644); 55 - MODULE_PARM_DESC(xino_auto, 56 - "Auto enable xino feature"); 57 - 58 - static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY); 59 - module_param_named(metacopy, ovl_metacopy_def, bool, 0644); 60 - MODULE_PARM_DESC(metacopy, 61 - "Default to on or off for the metadata only copy up feature"); 62 29 63 30 static struct dentry *ovl_d_real(struct dentry *dentry, 64 31 const struct inode *inode) ··· 180 211 kfree(oi->lowerdata_redirect); 181 212 } 182 213 183 - static void ovl_free_fs(struct ovl_fs *ofs) 184 - { 185 - struct vfsmount **mounts; 186 - unsigned i; 187 - 188 - iput(ofs->workbasedir_trap); 189 - iput(ofs->indexdir_trap); 190 - iput(ofs->workdir_trap); 191 - dput(ofs->whiteout); 192 - dput(ofs->indexdir); 193 - dput(ofs->workdir); 194 - if (ofs->workdir_locked) 195 - ovl_inuse_unlock(ofs->workbasedir); 196 - dput(ofs->workbasedir); 197 - if (ofs->upperdir_locked) 198 - ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); 199 - 200 - /* Hack! Reuse ofs->layers as a vfsmount array before freeing it */ 201 - mounts = (struct vfsmount **) ofs->layers; 202 - for (i = 0; i < ofs->numlayer; i++) { 203 - iput(ofs->layers[i].trap); 204 - mounts[i] = ofs->layers[i].mnt; 205 - kfree(ofs->layers[i].name); 206 - } 207 - kern_unmount_array(mounts, ofs->numlayer); 208 - kfree(ofs->layers); 209 - for (i = 0; i < ofs->numfs; i++) 210 - free_anon_bdev(ofs->fs[i].pseudo_dev); 211 - kfree(ofs->fs); 212 - 213 - kfree(ofs->config.upperdir); 214 - kfree(ofs->config.workdir); 215 - if (ofs->creator_cred) 216 - put_cred(ofs->creator_cred); 217 - kfree(ofs); 218 - } 219 - 220 214 static void ovl_put_super(struct super_block *sb) 221 215 { 222 216 struct ovl_fs *ofs = sb->s_fs_info; ··· 255 323 return err; 256 324 } 257 325 258 - /* Will this overlay be forced to mount/remount ro? */ 259 - static bool ovl_force_readonly(struct ovl_fs *ofs) 260 - { 261 - return (!ovl_upper_mnt(ofs) || !ofs->workdir); 262 - } 263 - 264 - static const struct constant_table ovl_parameter_redirect_dir[] = { 265 - { "off", OVL_REDIRECT_OFF }, 266 - { "follow", OVL_REDIRECT_FOLLOW }, 267 - { "nofollow", OVL_REDIRECT_NOFOLLOW }, 268 - { "on", OVL_REDIRECT_ON }, 269 - {} 270 - }; 271 - 272 - static const char *ovl_redirect_mode(struct ovl_config *config) 273 - { 274 - return ovl_parameter_redirect_dir[config->redirect_mode].name; 275 - } 276 - 277 - static int ovl_redirect_mode_def(void) 278 - { 279 - return ovl_redirect_dir_def ? OVL_REDIRECT_ON : 280 - ovl_redirect_always_follow ? OVL_REDIRECT_FOLLOW : 281 - OVL_REDIRECT_NOFOLLOW; 282 - } 283 - 284 - static const struct constant_table ovl_parameter_xino[] = { 285 - { "off", OVL_XINO_OFF }, 286 - { "auto", OVL_XINO_AUTO }, 287 - { "on", OVL_XINO_ON }, 288 - {} 289 - }; 290 - 291 - static const char *ovl_xino_mode(struct ovl_config *config) 292 - { 293 - return ovl_parameter_xino[config->xino].name; 294 - } 295 - 296 - static inline int ovl_xino_def(void) 297 - { 298 - return ovl_xino_auto_def ? OVL_XINO_AUTO : OVL_XINO_OFF; 299 - } 300 - 301 - /** 302 - * ovl_show_options 303 - * @m: the seq_file handle 304 - * @dentry: The dentry to query 305 - * 306 - * Prints the mount options for a given superblock. 307 - * Returns zero; does not fail. 308 - */ 309 - static int ovl_show_options(struct seq_file *m, struct dentry *dentry) 310 - { 311 - struct super_block *sb = dentry->d_sb; 312 - struct ovl_fs *ofs = sb->s_fs_info; 313 - size_t nr, nr_merged_lower = ofs->numlayer - ofs->numdatalayer; 314 - const struct ovl_layer *data_layers = &ofs->layers[nr_merged_lower]; 315 - 316 - /* ofs->layers[0] is the upper layer */ 317 - seq_printf(m, ",lowerdir=%s", ofs->layers[1].name); 318 - /* dump regular lower layers */ 319 - for (nr = 2; nr < nr_merged_lower; nr++) 320 - seq_printf(m, ":%s", ofs->layers[nr].name); 321 - /* dump data lower layers */ 322 - for (nr = 0; nr < ofs->numdatalayer; nr++) 323 - seq_printf(m, "::%s", data_layers[nr].name); 324 - if (ofs->config.upperdir) { 325 - seq_show_option(m, "upperdir", ofs->config.upperdir); 326 - seq_show_option(m, "workdir", ofs->config.workdir); 327 - } 328 - if (ofs->config.default_permissions) 329 - seq_puts(m, ",default_permissions"); 330 - if (ofs->config.redirect_mode != ovl_redirect_mode_def()) 331 - seq_printf(m, ",redirect_dir=%s", 332 - ovl_redirect_mode(&ofs->config)); 333 - if (ofs->config.index != ovl_index_def) 334 - seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off"); 335 - if (!ofs->config.uuid) 336 - seq_puts(m, ",uuid=off"); 337 - if (ofs->config.nfs_export != ovl_nfs_export_def) 338 - seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ? 339 - "on" : "off"); 340 - if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(ofs)) 341 - seq_printf(m, ",xino=%s", ovl_xino_mode(&ofs->config)); 342 - if (ofs->config.metacopy != ovl_metacopy_def) 343 - seq_printf(m, ",metacopy=%s", 344 - ofs->config.metacopy ? "on" : "off"); 345 - if (ofs->config.ovl_volatile) 346 - seq_puts(m, ",volatile"); 347 - if (ofs->config.userxattr) 348 - seq_puts(m, ",userxattr"); 349 - return 0; 350 - } 351 - 352 - static int ovl_reconfigure(struct fs_context *fc) 353 - { 354 - struct super_block *sb = fc->root->d_sb; 355 - struct ovl_fs *ofs = sb->s_fs_info; 356 - struct super_block *upper_sb; 357 - int ret = 0; 358 - 359 - if (!(fc->sb_flags & SB_RDONLY) && ovl_force_readonly(ofs)) 360 - return -EROFS; 361 - 362 - if (fc->sb_flags & SB_RDONLY && !sb_rdonly(sb)) { 363 - upper_sb = ovl_upper_mnt(ofs)->mnt_sb; 364 - if (ovl_should_sync(ofs)) { 365 - down_read(&upper_sb->s_umount); 366 - ret = sync_filesystem(upper_sb); 367 - up_read(&upper_sb->s_umount); 368 - } 369 - } 370 - 371 - return ret; 372 - } 373 - 374 326 static const struct super_operations ovl_super_operations = { 375 327 .alloc_inode = ovl_alloc_inode, 376 328 .free_inode = ovl_free_inode, ··· 265 449 .statfs = ovl_statfs, 266 450 .show_options = ovl_show_options, 267 451 }; 268 - 269 - enum { 270 - Opt_lowerdir, 271 - Opt_upperdir, 272 - Opt_workdir, 273 - Opt_default_permissions, 274 - Opt_redirect_dir, 275 - Opt_index, 276 - Opt_uuid, 277 - Opt_nfs_export, 278 - Opt_userxattr, 279 - Opt_xino, 280 - Opt_metacopy, 281 - Opt_volatile, 282 - }; 283 - 284 - static const struct constant_table ovl_parameter_bool[] = { 285 - { "on", true }, 286 - { "off", false }, 287 - {} 288 - }; 289 - 290 - #define fsparam_string_empty(NAME, OPT) \ 291 - __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL) 292 - 293 - static const struct fs_parameter_spec ovl_parameter_spec[] = { 294 - fsparam_string_empty("lowerdir", Opt_lowerdir), 295 - fsparam_string("upperdir", Opt_upperdir), 296 - fsparam_string("workdir", Opt_workdir), 297 - fsparam_flag("default_permissions", Opt_default_permissions), 298 - fsparam_enum("redirect_dir", Opt_redirect_dir, ovl_parameter_redirect_dir), 299 - fsparam_enum("index", Opt_index, ovl_parameter_bool), 300 - fsparam_enum("uuid", Opt_uuid, ovl_parameter_bool), 301 - fsparam_enum("nfs_export", Opt_nfs_export, ovl_parameter_bool), 302 - fsparam_flag("userxattr", Opt_userxattr), 303 - fsparam_enum("xino", Opt_xino, ovl_parameter_xino), 304 - fsparam_enum("metacopy", Opt_metacopy, ovl_parameter_bool), 305 - fsparam_flag("volatile", Opt_volatile), 306 - {} 307 - }; 308 - 309 - static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param) 310 - { 311 - int err = 0; 312 - struct fs_parse_result result; 313 - struct ovl_fs *ofs = fc->s_fs_info; 314 - struct ovl_config *config = &ofs->config; 315 - struct ovl_fs_context *ctx = fc->fs_private; 316 - int opt; 317 - 318 - if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { 319 - /* 320 - * On remount overlayfs has always ignored all mount 321 - * options no matter if malformed or not so for 322 - * backwards compatibility we do the same here. 323 - */ 324 - if (fc->oldapi) 325 - return 0; 326 - 327 - /* 328 - * Give us the freedom to allow changing mount options 329 - * with the new mount api in the future. So instead of 330 - * silently ignoring everything we report a proper 331 - * error. This is only visible for users of the new 332 - * mount api. 333 - */ 334 - return invalfc(fc, "No changes allowed in reconfigure"); 335 - } 336 - 337 - opt = fs_parse(fc, ovl_parameter_spec, param, &result); 338 - if (opt < 0) 339 - return opt; 340 - 341 - switch (opt) { 342 - case Opt_lowerdir: 343 - err = ovl_parse_param_lowerdir(param->string, fc); 344 - break; 345 - case Opt_upperdir: 346 - fallthrough; 347 - case Opt_workdir: 348 - err = ovl_parse_param_upperdir(param->string, fc, 349 - (Opt_workdir == opt)); 350 - break; 351 - case Opt_default_permissions: 352 - config->default_permissions = true; 353 - break; 354 - case Opt_redirect_dir: 355 - config->redirect_mode = result.uint_32; 356 - if (config->redirect_mode == OVL_REDIRECT_OFF) { 357 - config->redirect_mode = ovl_redirect_always_follow ? 358 - OVL_REDIRECT_FOLLOW : 359 - OVL_REDIRECT_NOFOLLOW; 360 - } 361 - ctx->set.redirect = true; 362 - break; 363 - case Opt_index: 364 - config->index = result.uint_32; 365 - ctx->set.index = true; 366 - break; 367 - case Opt_uuid: 368 - config->uuid = result.uint_32; 369 - break; 370 - case Opt_nfs_export: 371 - config->nfs_export = result.uint_32; 372 - ctx->set.nfs_export = true; 373 - break; 374 - case Opt_xino: 375 - config->xino = result.uint_32; 376 - break; 377 - case Opt_metacopy: 378 - config->metacopy = result.uint_32; 379 - ctx->set.metacopy = true; 380 - break; 381 - case Opt_volatile: 382 - config->ovl_volatile = true; 383 - break; 384 - case Opt_userxattr: 385 - config->userxattr = true; 386 - break; 387 - default: 388 - pr_err("unrecognized mount option \"%s\" or missing value\n", 389 - param->key); 390 - return -EINVAL; 391 - } 392 - 393 - return err; 394 - } 395 - 396 - static int ovl_fs_params_verify(const struct ovl_fs_context *ctx, 397 - struct ovl_config *config) 398 - { 399 - struct ovl_opt_set set = ctx->set; 400 - 401 - if (ctx->nr_data > 0 && !config->metacopy) { 402 - pr_err("lower data-only dirs require metacopy support.\n"); 403 - return -EINVAL; 404 - } 405 - 406 - /* Workdir/index are useless in non-upper mount */ 407 - if (!config->upperdir) { 408 - if (config->workdir) { 409 - pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n", 410 - config->workdir); 411 - kfree(config->workdir); 412 - config->workdir = NULL; 413 - } 414 - if (config->index && set.index) { 415 - pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n"); 416 - set.index = false; 417 - } 418 - config->index = false; 419 - } 420 - 421 - if (!config->upperdir && config->ovl_volatile) { 422 - pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n"); 423 - config->ovl_volatile = false; 424 - } 425 - 426 - /* 427 - * This is to make the logic below simpler. It doesn't make any other 428 - * difference, since redirect_dir=on is only used for upper. 429 - */ 430 - if (!config->upperdir && config->redirect_mode == OVL_REDIRECT_FOLLOW) 431 - config->redirect_mode = OVL_REDIRECT_ON; 432 - 433 - /* Resolve metacopy -> redirect_dir dependency */ 434 - if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) { 435 - if (set.metacopy && set.redirect) { 436 - pr_err("conflicting options: metacopy=on,redirect_dir=%s\n", 437 - ovl_redirect_mode(config)); 438 - return -EINVAL; 439 - } 440 - if (set.redirect) { 441 - /* 442 - * There was an explicit redirect_dir=... that resulted 443 - * in this conflict. 444 - */ 445 - pr_info("disabling metacopy due to redirect_dir=%s\n", 446 - ovl_redirect_mode(config)); 447 - config->metacopy = false; 448 - } else { 449 - /* Automatically enable redirect otherwise. */ 450 - config->redirect_mode = OVL_REDIRECT_ON; 451 - } 452 - } 453 - 454 - /* Resolve nfs_export -> index dependency */ 455 - if (config->nfs_export && !config->index) { 456 - if (!config->upperdir && 457 - config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { 458 - pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n"); 459 - config->nfs_export = false; 460 - } else if (set.nfs_export && set.index) { 461 - pr_err("conflicting options: nfs_export=on,index=off\n"); 462 - return -EINVAL; 463 - } else if (set.index) { 464 - /* 465 - * There was an explicit index=off that resulted 466 - * in this conflict. 467 - */ 468 - pr_info("disabling nfs_export due to index=off\n"); 469 - config->nfs_export = false; 470 - } else { 471 - /* Automatically enable index otherwise. */ 472 - config->index = true; 473 - } 474 - } 475 - 476 - /* Resolve nfs_export -> !metacopy dependency */ 477 - if (config->nfs_export && config->metacopy) { 478 - if (set.nfs_export && set.metacopy) { 479 - pr_err("conflicting options: nfs_export=on,metacopy=on\n"); 480 - return -EINVAL; 481 - } 482 - if (set.metacopy) { 483 - /* 484 - * There was an explicit metacopy=on that resulted 485 - * in this conflict. 486 - */ 487 - pr_info("disabling nfs_export due to metacopy=on\n"); 488 - config->nfs_export = false; 489 - } else { 490 - /* 491 - * There was an explicit nfs_export=on that resulted 492 - * in this conflict. 493 - */ 494 - pr_info("disabling metacopy due to nfs_export=on\n"); 495 - config->metacopy = false; 496 - } 497 - } 498 - 499 - 500 - /* Resolve userxattr -> !redirect && !metacopy dependency */ 501 - if (config->userxattr) { 502 - if (set.redirect && 503 - config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { 504 - pr_err("conflicting options: userxattr,redirect_dir=%s\n", 505 - ovl_redirect_mode(config)); 506 - return -EINVAL; 507 - } 508 - if (config->metacopy && set.metacopy) { 509 - pr_err("conflicting options: userxattr,metacopy=on\n"); 510 - return -EINVAL; 511 - } 512 - /* 513 - * Silently disable default setting of redirect and metacopy. 514 - * This shall be the default in the future as well: these 515 - * options must be explicitly enabled if used together with 516 - * userxattr. 517 - */ 518 - config->redirect_mode = OVL_REDIRECT_NOFOLLOW; 519 - config->metacopy = false; 520 - } 521 - 522 - return 0; 523 - } 524 452 525 453 #define OVL_WORKDIR_NAME "work" 526 454 #define OVL_INDEXDIR_NAME "index" ··· 1318 1758 return root; 1319 1759 } 1320 1760 1321 - static int ovl_fill_super(struct super_block *sb, struct fs_context *fc) 1761 + int ovl_fill_super(struct super_block *sb, struct fs_context *fc) 1322 1762 { 1323 1763 struct ovl_fs *ofs = sb->s_fs_info; 1324 1764 struct ovl_fs_context *ctx = fc->fs_private; ··· 1477 1917 ovl_free_fs(ofs); 1478 1918 sb->s_fs_info = NULL; 1479 1919 return err; 1480 - } 1481 - 1482 - static int ovl_get_tree(struct fs_context *fc) 1483 - { 1484 - return get_tree_nodev(fc, ovl_fill_super); 1485 - } 1486 - 1487 - static inline void ovl_fs_context_free(struct ovl_fs_context *ctx) 1488 - { 1489 - ovl_parse_param_drop_lowerdir(ctx); 1490 - path_put(&ctx->upper); 1491 - path_put(&ctx->work); 1492 - kfree(ctx->lower); 1493 - kfree(ctx); 1494 - } 1495 - 1496 - static void ovl_free(struct fs_context *fc) 1497 - { 1498 - struct ovl_fs *ofs = fc->s_fs_info; 1499 - struct ovl_fs_context *ctx = fc->fs_private; 1500 - 1501 - /* 1502 - * ofs is stored in the fs_context when it is initialized. 1503 - * ofs is transferred to the superblock on a successful mount, 1504 - * but if an error occurs before the transfer we have to free 1505 - * it here. 1506 - */ 1507 - if (ofs) 1508 - ovl_free_fs(ofs); 1509 - 1510 - if (ctx) 1511 - ovl_fs_context_free(ctx); 1512 - } 1513 - 1514 - static const struct fs_context_operations ovl_context_ops = { 1515 - .parse_param = ovl_parse_param, 1516 - .get_tree = ovl_get_tree, 1517 - .reconfigure = ovl_reconfigure, 1518 - .free = ovl_free, 1519 - }; 1520 - 1521 - /* 1522 - * This is called during fsopen() and will record the user namespace of 1523 - * the caller in fc->user_ns since we've raised FS_USERNS_MOUNT. We'll 1524 - * need it when we actually create the superblock to verify that the 1525 - * process creating the superblock is in the same user namespace as 1526 - * process that called fsopen(). 1527 - */ 1528 - static int ovl_init_fs_context(struct fs_context *fc) 1529 - { 1530 - struct ovl_fs_context *ctx; 1531 - struct ovl_fs *ofs; 1532 - 1533 - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); 1534 - if (!ctx) 1535 - return -ENOMEM; 1536 - 1537 - /* 1538 - * By default we allocate for three lower layers. It's likely 1539 - * that it'll cover most users. 1540 - */ 1541 - ctx->lower = kmalloc_array(3, sizeof(*ctx->lower), GFP_KERNEL_ACCOUNT); 1542 - if (!ctx->lower) 1543 - goto out_err; 1544 - ctx->capacity = 3; 1545 - 1546 - ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); 1547 - if (!ofs) 1548 - goto out_err; 1549 - 1550 - ofs->config.redirect_mode = ovl_redirect_mode_def(); 1551 - ofs->config.index = ovl_index_def; 1552 - ofs->config.uuid = true; 1553 - ofs->config.nfs_export = ovl_nfs_export_def; 1554 - ofs->config.xino = ovl_xino_def(); 1555 - ofs->config.metacopy = ovl_metacopy_def; 1556 - 1557 - fc->s_fs_info = ofs; 1558 - fc->fs_private = ctx; 1559 - fc->ops = &ovl_context_ops; 1560 - return 0; 1561 - 1562 - out_err: 1563 - ovl_fs_context_free(ctx); 1564 - return -ENOMEM; 1565 - 1566 1920 } 1567 1921 1568 1922 static struct file_system_type ovl_fs_type = {