[v7,2/2] overlayfs: add mnt_id paths options

Submitted by Alexander Mikhalitsyn on June 3, 2020, 4:58 p.m.

Details

Message ID 20200603165813.13629-3-alexander.mikhalitsyn@virtuozzo.com
State New
Series "overlayfs: add dynamic path resolving in mount options"
Headers show

Commit Message

Alexander Mikhalitsyn June 3, 2020, 4:58 p.m.
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.

https://jira.sw.ru/browse/PSBM-58614

Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
---
 fs/overlayfs/Kconfig     | 26 ++++++++++++++++++++++++++
 fs/overlayfs/overlayfs.h |  3 +++
 fs/overlayfs/super.c     | 14 ++++++++++++++
 fs/overlayfs/util.c      | 21 +++++++++++++++++++++
 4 files changed, 64 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
index 27a3f05..2a76e28 100644
--- a/fs/overlayfs/Kconfig
+++ b/fs/overlayfs/Kconfig
@@ -133,4 +133,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 f508cd2..6440be5 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -256,6 +256,9 @@  int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
 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 138c6ac..be01553 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -61,6 +61,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;
@@ -390,6 +394,16 @@  static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
 		}
 	}
 
+	if (ovl_mnt_id_path_opts) {
+		print_mnt_ids_option(m, "lowerdir_mnt_id", ofs->lowerpaths, ofs->numlower);
+		/*
+		 * 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 bb670ee..0425c49 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -18,6 +18,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)
@@ -699,3 +700,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);
+	}
+}

Comments

Pavel Tikhomirov June 4, 2020, 8:19 a.m.
On 6/3/20 7:58 PM, Alexander Mikhalitsyn wrote:
> 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.
> 
> https://jira.sw.ru/browse/PSBM-58614
> 

Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

> Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com > ---
>   fs/overlayfs/Kconfig     | 26 ++++++++++++++++++++++++++
>   fs/overlayfs/overlayfs.h |  3 +++
>   fs/overlayfs/super.c     | 14 ++++++++++++++
>   fs/overlayfs/util.c      | 21 +++++++++++++++++++++
>   4 files changed, 64 insertions(+)
> 
> diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
> index 27a3f05..2a76e28 100644
> --- a/fs/overlayfs/Kconfig
> +++ b/fs/overlayfs/Kconfig
> @@ -133,4 +133,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 f508cd2..6440be5 100644
> --- a/fs/overlayfs/overlayfs.h
> +++ b/fs/overlayfs/overlayfs.h
> @@ -256,6 +256,9 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
>   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 138c6ac..be01553 100644
> --- a/fs/overlayfs/super.c
> +++ b/fs/overlayfs/super.c
> @@ -61,6 +61,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;
> @@ -390,6 +394,16 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
>   		}
>   	}
>   
> +	if (ovl_mnt_id_path_opts) {
> +		print_mnt_ids_option(m, "lowerdir_mnt_id", ofs->lowerpaths, ofs->numlower);
> +		/*
> +		 * 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 bb670ee..0425c49 100644
> --- a/fs/overlayfs/util.c
> +++ b/fs/overlayfs/util.c
> @@ -18,6 +18,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)
> @@ -699,3 +700,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);
> +	}
> +}
>