This patch adds config OVERLAY_FS_PATH_OPTIONS_MNT_ID compile-time option, and "mnt_id_path_opts" runtime module option. If enabled, user may see mnt_ids for lowerdir, upperdir paths in mountinfo in separate lowerdir_mnt_id/upperdir_mnt_id options. This patch is very helpful to checkpoint/restore functionality of overlayfs mounts in case when we have overmounts on lowerdir, workdir, upperdir paths. Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@xxxxxxxxxxxxx> --- fs/overlayfs/Kconfig | 26 ++++++++++++++++++++++++++ fs/overlayfs/overlayfs.h | 2 ++ fs/overlayfs/super.c | 15 +++++++++++++++ fs/overlayfs/util.c | 21 +++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig index c24988527ef3..2797869c8d16 100644 --- a/fs/overlayfs/Kconfig +++ b/fs/overlayfs/Kconfig @@ -154,4 +154,30 @@ config OVERLAY_FS_DYNAMIC_RESOLVE_PATH_OPTIONS For more information, see Documentation/filesystems/overlayfs.txt + If unsure, say N. + +config OVERLAY_FS_PATH_OPTIONS_MNT_ID + bool "Overlayfs: show mnt_id for all mount paths options" + default y + depends on OVERLAY_FS + help + This option helps checkpoint/restore of overlayfs mounts. + If N selected, old behavior is saved. + + If this config option is enabled then in overlay filesystems mount + options you will be able to see additional parameters lowerdir_mnt_id/ + upperdir_mnt_id with corresponding mnt_ids. + + It's also possible to change this behavior on overlayfs module loading or + through sysfs (mnt_id_path_opts parameter). + + Disable this to get a backward compatible with previous kernels configuration, + but in this case checkpoint/restore functionality for overlayfs mounts + may not fully work. + + If backward compatibility is not an issue, then it is safe and + recommended to say Y here. + + For more information, see Documentation/filesystems/overlayfs.txt + If unsure, say N. \ No newline at end of file diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 8722ed556e11..980fe06d15b5 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -305,6 +305,8 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value, void print_path_option(struct seq_file *m, const char *name, struct path *path); void print_paths_option(struct seq_file *m, const char *name, struct path *paths, unsigned int num); +void print_mnt_id_option(struct seq_file *m, const char *name, struct path *path); +void print_mnt_ids_option(struct seq_file *m, const char *name, struct path *paths, unsigned int num); static inline bool ovl_is_impuredir(struct dentry *dentry) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index a449b6bb4b20..ee2ed125341c 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -57,6 +57,10 @@ static bool ovl_dyn_path_opts = IS_ENABLED(CONFIG_OVERLAY_FS_DYNAMIC_RESOLVE_PAT module_param_named(dyn_path_opts, ovl_dyn_path_opts, bool, 0644); MODULE_PARM_DESC(dyn_path_opts, "dyn_path_opts feature enabled"); +static bool ovl_mnt_id_path_opts = IS_ENABLED(OVERLAY_FS_PATH_OPTIONS_MNT_ID); +module_param_named(mnt_id_path_opts, ovl_mnt_id_path_opts, bool, 0644); +MODULE_PARM_DESC(mnt_id_path_opts, "mnt_id_path_opts feature enabled"); + static void ovl_entry_stack_free(struct ovl_entry *oe) { unsigned int i; @@ -362,6 +366,17 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry) seq_show_option(m, "workdir", ofs->config.workdir); } } + + if (ovl_mnt_id_path_opts) { + print_mnt_ids_option(m, "lowerdir_mnt_id", ofs->lowerpaths, ofs->numlayer); + /* + * We don't need to show mnt_id for workdir because it + * on the same mount as upperdir. + */ + if (ofs->config.upperdir) + print_mnt_id_option(m, "upperdir_mnt_id", &ofs->upperpath); + } + if (ofs->config.default_permissions) seq_puts(m, ",default_permissions"); if (strcmp(ofs->config.redirect_mode, ovl_redirect_mode_def()) != 0) diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 36bb98c14d35..85106b2ed00a 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -14,6 +14,7 @@ #include <linux/namei.h> #include <linux/ratelimit.h> #include <linux/seq_file.h> +#include "../mount.h" #include "overlayfs.h" int ovl_want_write(struct dentry *dentry) @@ -941,3 +942,23 @@ void print_paths_option(struct seq_file *m, const char *name, seq_path(m, &paths[i], ", \t\n\\"); } } + +void print_mnt_id_option(struct seq_file *m, const char *name, struct path *path) +{ + seq_show_option(m, name, ""); + seq_printf(m, "%i", real_mount(path->mnt)->mnt_id); +} + +void print_mnt_ids_option(struct seq_file *m, const char *name, + struct path *paths, unsigned int num) +{ + int i; + + seq_show_option(m, name, ""); + + for (i = 0; i < num; i++) { + if (i) + seq_putc(m, ':'); + seq_printf(m, "%i", real_mount(paths[i].mnt)->mnt_id); + } +} -- 2.17.1