Lines Matching +full:static +full:- +full:config
1 // SPDX-License-Identifier: GPL-2.0-only
14 static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR);
19 static bool ovl_redirect_always_follow =
26 static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO);
31 static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX);
36 static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT);
41 static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY);
64 static const struct constant_table ovl_parameter_bool[] = {
70 static const struct constant_table ovl_parameter_uuid[] = {
78 static const char *ovl_uuid_mode(struct ovl_config *config) in ovl_uuid_mode() argument
80 return ovl_parameter_uuid[config->uuid].name; in ovl_uuid_mode()
83 static int ovl_uuid_def(void) in ovl_uuid_def()
88 static const struct constant_table ovl_parameter_xino[] = {
95 const char *ovl_xino_mode(struct ovl_config *config) in ovl_xino_mode() argument
97 return ovl_parameter_xino[config->xino].name; in ovl_xino_mode()
100 static int ovl_xino_def(void) in ovl_xino_def()
113 static const char *ovl_redirect_mode(struct ovl_config *config) in ovl_redirect_mode() argument
115 return ovl_parameter_redirect_dir[config->redirect_mode].name; in ovl_redirect_mode()
118 static int ovl_redirect_mode_def(void) in ovl_redirect_mode_def()
125 static const struct constant_table ovl_parameter_verity[] = {
132 static const char *ovl_verity_mode(struct ovl_config *config) in ovl_verity_mode() argument
134 return ovl_parameter_verity[config->verity_mode].name; in ovl_verity_mode()
137 static int ovl_verity_mode_def(void) in ovl_verity_mode_def()
161 static char *ovl_next_opt(char **s) in ovl_next_opt()
184 static int ovl_parse_monolithic(struct fs_context *fc, void *data) in ovl_parse_monolithic()
189 static ssize_t ovl_parse_param_split_lowerdirs(char *str) in ovl_parse_param_split_lowerdirs()
204 return -EINVAL; in ovl_parse_param_split_lowerdirs()
219 return -EINVAL; in ovl_parse_param_split_lowerdirs()
229 static int ovl_mount_dir_noesc(const char *name, struct path *path) in ovl_mount_dir_noesc()
231 int err = -EINVAL; in ovl_mount_dir_noesc()
248 static void ovl_unescape(char *s) in ovl_unescape()
261 static int ovl_mount_dir(const char *name, struct path *path) in ovl_mount_dir()
263 int err = -ENOMEM; in ovl_mount_dir()
274 static int ovl_mount_dir_check(struct fs_context *fc, const struct path *path, in ovl_mount_dir_check()
277 struct ovl_fs_context *ctx = fc->fs_private; in ovl_mount_dir_check()
279 if (!d_is_dir(path->dentry)) in ovl_mount_dir_check()
283 * Root dentries of case-insensitive capable filesystems might in ovl_mount_dir_check()
285 * with overlayfs. Check explicitly to prevent post-mount in ovl_mount_dir_check()
288 if (sb_has_encoding(path->mnt->mnt_sb)) in ovl_mount_dir_check()
289 return invalfc(fc, "case-insensitive capable filesystem on %s not supported", name); in ovl_mount_dir_check()
291 if (ovl_dentry_weird(path->dentry)) in ovl_mount_dir_check()
295 * Check whether upper path is read-only here to report failures in ovl_mount_dir_check()
300 if (path->dentry->d_flags & DCACHE_OP_REAL) in ovl_mount_dir_check()
302 if (__mnt_is_readonly(path->mnt)) in ovl_mount_dir_check()
303 return invalfc(fc, "filesystem on %s is read-only", name); in ovl_mount_dir_check()
305 if (ctx->lowerdir_all && layer != Opt_lowerdir) in ovl_mount_dir_check()
307 if (ctx->nr_data && layer == Opt_lowerdir_add) in ovl_mount_dir_check()
309 if (ctx->nr == OVL_MAX_STACK) in ovl_mount_dir_check()
316 static int ovl_ctx_realloc_lower(struct fs_context *fc) in ovl_ctx_realloc_lower()
318 struct ovl_fs_context *ctx = fc->fs_private; in ovl_ctx_realloc_lower()
322 if (ctx->nr < ctx->capacity) in ovl_ctx_realloc_lower()
325 nr = min_t(size_t, max(4096 / sizeof(*l), ctx->capacity * 2), in ovl_ctx_realloc_lower()
327 l = krealloc_array(ctx->lower, nr, sizeof(*l), GFP_KERNEL_ACCOUNT); in ovl_ctx_realloc_lower()
329 return -ENOMEM; in ovl_ctx_realloc_lower()
331 ctx->lower = l; in ovl_ctx_realloc_lower()
332 ctx->capacity = nr; in ovl_ctx_realloc_lower()
336 static void ovl_add_layer(struct fs_context *fc, enum ovl_opt layer, in ovl_add_layer()
339 struct ovl_fs *ofs = fc->s_fs_info; in ovl_add_layer()
340 struct ovl_config *config = &ofs->config; in ovl_add_layer() local
341 struct ovl_fs_context *ctx = fc->fs_private; in ovl_add_layer()
346 swap(config->workdir, *pname); in ovl_add_layer()
347 swap(ctx->work, *path); in ovl_add_layer()
350 swap(config->upperdir, *pname); in ovl_add_layer()
351 swap(ctx->upper, *path); in ovl_add_layer()
354 ctx->nr_data++; in ovl_add_layer()
359 WARN_ON(ctx->nr >= ctx->capacity); in ovl_add_layer()
360 l = &ctx->lower[ctx->nr++]; in ovl_add_layer()
362 swap(l->name, *pname); in ovl_add_layer()
363 swap(l->path, *path); in ovl_add_layer()
370 static inline bool is_upper_layer(enum ovl_opt layer) in is_upper_layer()
375 /* Handle non-file descriptor-based layer options that require path lookup. */
376 static inline int ovl_kern_path(const char *layer_name, struct path *layer_path, in ovl_kern_path()
396 err = -EINVAL; in ovl_kern_path()
402 static int ovl_do_parse_layer(struct fs_context *fc, const char *layer_name, in ovl_do_parse_layer()
410 return -ENOMEM; in ovl_do_parse_layer()
428 static int ovl_parse_layer(struct fs_context *fc, struct fs_parameter *param, in ovl_parse_layer()
434 switch (param->type) { in ovl_parse_layer()
436 err = ovl_kern_path(param->string, &layer_path, layer); in ovl_parse_layer()
439 err = ovl_do_parse_layer(fc, param->string, &layer_path, layer); in ovl_parse_layer()
447 return -ENOMEM; in ovl_parse_layer()
449 layer_path = param->file->f_path; in ovl_parse_layer()
461 err = -EINVAL; in ovl_parse_layer()
467 static void ovl_reset_lowerdirs(struct ovl_fs_context *ctx) in ovl_reset_lowerdirs()
469 struct ovl_fs_context_layer *l = ctx->lower; in ovl_reset_lowerdirs()
472 kfree(ctx->lowerdir_all); in ovl_reset_lowerdirs()
473 ctx->lowerdir_all = NULL; in ovl_reset_lowerdirs()
475 for (size_t nr = 0; nr < ctx->nr; nr++, l++) { in ovl_reset_lowerdirs()
476 path_put(&l->path); in ovl_reset_lowerdirs()
477 kfree(l->name); in ovl_reset_lowerdirs()
478 l->name = NULL; in ovl_reset_lowerdirs()
480 ctx->nr = 0; in ovl_reset_lowerdirs()
481 ctx->nr_data = 0; in ovl_reset_lowerdirs()
492 static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc) in ovl_parse_param_lowerdir()
495 struct ovl_fs_context *ctx = fc->fs_private; in ovl_parse_param_lowerdir()
513 return -EINVAL; in ovl_parse_param_lowerdir()
517 ctx->lowerdir_all = kstrdup(name, GFP_KERNEL); in ovl_parse_param_lowerdir()
518 if (!ctx->lowerdir_all) in ovl_parse_param_lowerdir()
519 return -ENOMEM; in ovl_parse_param_lowerdir()
523 return -ENOMEM; in ovl_parse_param_lowerdir()
525 err = -EINVAL; in ovl_parse_param_lowerdir()
548 ctx->nr_data++; in ovl_parse_param_lowerdir()
551 if (ctx->nr == nr_lower) in ovl_parse_param_lowerdir()
554 err = -EINVAL; in ovl_parse_param_lowerdir()
561 if (ctx->nr_data > 0) { in ovl_parse_param_lowerdir()
584 static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param) in ovl_parse_param()
588 struct ovl_fs *ofs = fc->s_fs_info; in ovl_parse_param()
589 struct ovl_config *config = &ofs->config; in ovl_parse_param() local
590 struct ovl_fs_context *ctx = fc->fs_private; in ovl_parse_param()
593 if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { in ovl_parse_param()
599 if (fc->oldapi) in ovl_parse_param()
618 err = ovl_parse_param_lowerdir(param->string, fc); in ovl_parse_param()
627 config->default_permissions = true; in ovl_parse_param()
630 config->redirect_mode = result.uint_32; in ovl_parse_param()
631 if (config->redirect_mode == OVL_REDIRECT_OFF) { in ovl_parse_param()
632 config->redirect_mode = ovl_redirect_always_follow ? in ovl_parse_param()
636 ctx->set.redirect = true; in ovl_parse_param()
639 config->index = result.uint_32; in ovl_parse_param()
640 ctx->set.index = true; in ovl_parse_param()
643 config->uuid = result.uint_32; in ovl_parse_param()
646 config->nfs_export = result.uint_32; in ovl_parse_param()
647 ctx->set.nfs_export = true; in ovl_parse_param()
650 config->xino = result.uint_32; in ovl_parse_param()
653 config->metacopy = result.uint_32; in ovl_parse_param()
654 ctx->set.metacopy = true; in ovl_parse_param()
657 config->verity_mode = result.uint_32; in ovl_parse_param()
660 config->ovl_volatile = true; in ovl_parse_param()
663 config->userxattr = true; in ovl_parse_param()
667 param->key); in ovl_parse_param()
668 return -EINVAL; in ovl_parse_param()
674 static int ovl_get_tree(struct fs_context *fc) in ovl_get_tree()
679 static inline void ovl_fs_context_free(struct ovl_fs_context *ctx) in ovl_fs_context_free()
682 path_put(&ctx->upper); in ovl_fs_context_free()
683 path_put(&ctx->work); in ovl_fs_context_free()
684 kfree(ctx->lower); in ovl_fs_context_free()
688 static void ovl_free(struct fs_context *fc) in ovl_free()
690 struct ovl_fs *ofs = fc->s_fs_info; in ovl_free()
691 struct ovl_fs_context *ctx = fc->fs_private; in ovl_free()
706 static int ovl_reconfigure(struct fs_context *fc) in ovl_reconfigure()
708 struct super_block *sb = fc->root->d_sb; in ovl_reconfigure()
713 if (!(fc->sb_flags & SB_RDONLY) && ovl_force_readonly(ofs)) in ovl_reconfigure()
714 return -EROFS; in ovl_reconfigure()
716 if (fc->sb_flags & SB_RDONLY && !sb_rdonly(sb)) { in ovl_reconfigure()
717 upper_sb = ovl_upper_mnt(ofs)->mnt_sb; in ovl_reconfigure()
719 down_read(&upper_sb->s_umount); in ovl_reconfigure()
721 up_read(&upper_sb->s_umount); in ovl_reconfigure()
728 static const struct fs_context_operations ovl_context_ops = {
738 * the caller in fc->user_ns since we've raised FS_USERNS_MOUNT. We'll
750 return -ENOMEM; in ovl_init_fs_context()
756 ctx->lower = kmalloc_array(3, sizeof(*ctx->lower), GFP_KERNEL_ACCOUNT); in ovl_init_fs_context()
757 if (!ctx->lower) in ovl_init_fs_context()
759 ctx->capacity = 3; in ovl_init_fs_context()
765 ofs->config.redirect_mode = ovl_redirect_mode_def(); in ovl_init_fs_context()
766 ofs->config.index = ovl_index_def; in ovl_init_fs_context()
767 ofs->config.uuid = ovl_uuid_def(); in ovl_init_fs_context()
768 ofs->config.nfs_export = ovl_nfs_export_def; in ovl_init_fs_context()
769 ofs->config.xino = ovl_xino_def(); in ovl_init_fs_context()
770 ofs->config.metacopy = ovl_metacopy_def; in ovl_init_fs_context()
772 fc->s_fs_info = ofs; in ovl_init_fs_context()
773 fc->fs_private = ctx; in ovl_init_fs_context()
774 fc->ops = &ovl_context_ops; in ovl_init_fs_context()
779 return -ENOMEM; in ovl_init_fs_context()
788 iput(ofs->workbasedir_trap); in ovl_free_fs()
789 iput(ofs->workdir_trap); in ovl_free_fs()
790 dput(ofs->whiteout); in ovl_free_fs()
791 dput(ofs->workdir); in ovl_free_fs()
792 if (ofs->workdir_locked) in ovl_free_fs()
793 ovl_inuse_unlock(ofs->workbasedir); in ovl_free_fs()
794 dput(ofs->workbasedir); in ovl_free_fs()
795 if (ofs->upperdir_locked) in ovl_free_fs()
796 ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); in ovl_free_fs()
798 /* Reuse ofs->config.lowerdirs as a vfsmount array before freeing it */ in ovl_free_fs()
799 mounts = (struct vfsmount **) ofs->config.lowerdirs; in ovl_free_fs()
800 for (i = 0; i < ofs->numlayer; i++) { in ovl_free_fs()
801 iput(ofs->layers[i].trap); in ovl_free_fs()
802 kfree(ofs->config.lowerdirs[i]); in ovl_free_fs()
803 mounts[i] = ofs->layers[i].mnt; in ovl_free_fs()
805 kern_unmount_array(mounts, ofs->numlayer); in ovl_free_fs()
806 kfree(ofs->layers); in ovl_free_fs()
807 for (i = 0; i < ofs->numfs; i++) in ovl_free_fs()
808 free_anon_bdev(ofs->fs[i].pseudo_dev); in ovl_free_fs()
809 kfree(ofs->fs); in ovl_free_fs()
811 kfree(ofs->config.lowerdirs); in ovl_free_fs()
812 kfree(ofs->config.upperdir); in ovl_free_fs()
813 kfree(ofs->config.workdir); in ovl_free_fs()
814 if (ofs->creator_cred) in ovl_free_fs()
815 put_cred(ofs->creator_cred); in ovl_free_fs()
820 struct ovl_config *config) in ovl_fs_params_verify() argument
822 struct ovl_opt_set set = ctx->set; in ovl_fs_params_verify()
824 /* Workdir/index are useless in non-upper mount */ in ovl_fs_params_verify()
825 if (!config->upperdir) { in ovl_fs_params_verify()
826 if (config->workdir) { in ovl_fs_params_verify()
827 pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n", in ovl_fs_params_verify()
828 config->workdir); in ovl_fs_params_verify()
829 kfree(config->workdir); in ovl_fs_params_verify()
830 config->workdir = NULL; in ovl_fs_params_verify()
832 if (config->index && set.index) { in ovl_fs_params_verify()
833 pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n"); in ovl_fs_params_verify()
836 config->index = false; in ovl_fs_params_verify()
839 if (!config->upperdir && config->ovl_volatile) { in ovl_fs_params_verify()
840 pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n"); in ovl_fs_params_verify()
841 config->ovl_volatile = false; in ovl_fs_params_verify()
844 if (!config->upperdir && config->uuid == OVL_UUID_ON) { in ovl_fs_params_verify()
846 config->uuid = OVL_UUID_NULL; in ovl_fs_params_verify()
849 /* Resolve verity -> metacopy dependency */ in ovl_fs_params_verify()
850 if (config->verity_mode && !config->metacopy) { in ovl_fs_params_verify()
854 ovl_verity_mode(config)); in ovl_fs_params_verify()
855 return -EINVAL; in ovl_fs_params_verify()
858 config->metacopy = true; in ovl_fs_params_verify()
865 if (!config->upperdir && config->redirect_mode == OVL_REDIRECT_FOLLOW) in ovl_fs_params_verify()
866 config->redirect_mode = OVL_REDIRECT_ON; in ovl_fs_params_verify()
868 /* Resolve verity -> metacopy -> redirect_dir dependency */ in ovl_fs_params_verify()
869 if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) { in ovl_fs_params_verify()
872 ovl_redirect_mode(config)); in ovl_fs_params_verify()
873 return -EINVAL; in ovl_fs_params_verify()
875 if (config->verity_mode && set.redirect) { in ovl_fs_params_verify()
877 ovl_verity_mode(config), ovl_redirect_mode(config)); in ovl_fs_params_verify()
878 return -EINVAL; in ovl_fs_params_verify()
886 ovl_redirect_mode(config)); in ovl_fs_params_verify()
887 config->metacopy = false; in ovl_fs_params_verify()
890 config->redirect_mode = OVL_REDIRECT_ON; in ovl_fs_params_verify()
894 /* Resolve nfs_export -> index dependency */ in ovl_fs_params_verify()
895 if (config->nfs_export && !config->index) { in ovl_fs_params_verify()
896 if (!config->upperdir && in ovl_fs_params_verify()
897 config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { in ovl_fs_params_verify()
898 …pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_exp… in ovl_fs_params_verify()
899 config->nfs_export = false; in ovl_fs_params_verify()
902 return -EINVAL; in ovl_fs_params_verify()
909 config->nfs_export = false; in ovl_fs_params_verify()
912 config->index = true; in ovl_fs_params_verify()
916 /* Resolve nfs_export -> !metacopy && !verity dependency */ in ovl_fs_params_verify()
917 if (config->nfs_export && config->metacopy) { in ovl_fs_params_verify()
920 return -EINVAL; in ovl_fs_params_verify()
928 config->nfs_export = false; in ovl_fs_params_verify()
929 } else if (config->verity_mode) { in ovl_fs_params_verify()
935 ovl_verity_mode(config)); in ovl_fs_params_verify()
936 config->nfs_export = false; in ovl_fs_params_verify()
943 config->metacopy = false; in ovl_fs_params_verify()
948 /* Resolve userxattr -> !redirect && !metacopy && !verity dependency */ in ovl_fs_params_verify()
949 if (config->userxattr) { in ovl_fs_params_verify()
951 config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { in ovl_fs_params_verify()
953 ovl_redirect_mode(config)); in ovl_fs_params_verify()
954 return -EINVAL; in ovl_fs_params_verify()
956 if (config->metacopy && set.metacopy) { in ovl_fs_params_verify()
958 return -EINVAL; in ovl_fs_params_verify()
960 if (config->verity_mode) { in ovl_fs_params_verify()
962 ovl_verity_mode(config)); in ovl_fs_params_verify()
963 return -EINVAL; in ovl_fs_params_verify()
971 config->redirect_mode = OVL_REDIRECT_NOFOLLOW; in ovl_fs_params_verify()
972 config->metacopy = false; in ovl_fs_params_verify()
979 if (!config->userxattr && !capable(CAP_SYS_ADMIN)) { in ovl_fs_params_verify()
981 config->redirect_mode != OVL_REDIRECT_NOFOLLOW) { in ovl_fs_params_verify()
983 return -EPERM; in ovl_fs_params_verify()
985 if (config->metacopy && set.metacopy) { in ovl_fs_params_verify()
987 return -EPERM; in ovl_fs_params_verify()
989 if (config->verity_mode) { in ovl_fs_params_verify()
991 return -EPERM; in ovl_fs_params_verify()
993 if (ctx->nr_data > 0) { in ovl_fs_params_verify()
994 pr_err("lower data-only dirs require permission to access trusted xattrs\n"); in ovl_fs_params_verify()
995 return -EPERM; in ovl_fs_params_verify()
998 * Other xattr-dependent features should be disabled without in ovl_fs_params_verify()
1003 if (ctx->nr_data > 0 && !config->metacopy) { in ovl_fs_params_verify()
1004 pr_err("lower data-only dirs require metacopy support.\n"); in ovl_fs_params_verify()
1005 return -EINVAL; in ovl_fs_params_verify()
1021 struct super_block *sb = dentry->d_sb; in ovl_show_options()
1024 char **lowerdirs = ofs->config.lowerdirs; in ovl_show_options()
1037 nr_lower = ofs->numlayer; in ovl_show_options()
1038 nr_merged_lower = nr_lower - ofs->numdatalayer; in ovl_show_options()
1046 if (ofs->config.upperdir) { in ovl_show_options()
1047 seq_show_option(m, "upperdir", ofs->config.upperdir); in ovl_show_options()
1048 seq_show_option(m, "workdir", ofs->config.workdir); in ovl_show_options()
1050 if (ofs->config.default_permissions) in ovl_show_options()
1052 if (ofs->config.redirect_mode != ovl_redirect_mode_def()) in ovl_show_options()
1054 ovl_redirect_mode(&ofs->config)); in ovl_show_options()
1055 if (ofs->config.index != ovl_index_def) in ovl_show_options()
1056 seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off"); in ovl_show_options()
1057 if (ofs->config.uuid != ovl_uuid_def()) in ovl_show_options()
1058 seq_printf(m, ",uuid=%s", ovl_uuid_mode(&ofs->config)); in ovl_show_options()
1059 if (ofs->config.nfs_export != ovl_nfs_export_def) in ovl_show_options()
1060 seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ? in ovl_show_options()
1062 if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(ofs)) in ovl_show_options()
1063 seq_printf(m, ",xino=%s", ovl_xino_mode(&ofs->config)); in ovl_show_options()
1064 if (ofs->config.metacopy != ovl_metacopy_def) in ovl_show_options()
1066 ofs->config.metacopy ? "on" : "off"); in ovl_show_options()
1067 if (ofs->config.ovl_volatile) in ovl_show_options()
1069 if (ofs->config.userxattr) in ovl_show_options()
1071 if (ofs->config.verity_mode != ovl_verity_mode_def()) in ovl_show_options()
1073 ovl_verity_mode(&ofs->config)); in ovl_show_options()