[PATCH] overlay: allow config override of metacopy/redirect defaults

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[Why]
Currently, if the redirect_dir option is set as a kernel or module
parameter, then even if metacopy is only enabled config, then both
metacopy and redirect_dir will be enabled when one creates a mount
point. This is not desirable because /sys/module/overlay/parameters will
still report that redirect_dir is not enabled, and there will be no
redirect_dir=on line in the mount options in /proc/mounts. The behavior
of setting redirect_dir globally for overlay is likely a common pattern
on docker workstations, as redirect_dir makes for slower building of
docker images.

[How]
This patch adds similar logic to that already in place for parsing mount
parameters. If the user explicitly sets redirect_dir via a kernel or
module parameter, then metacopy will become disabled, unless it was also
specified that way. Obviously, mount options still take precedence over
this process, so this logic only kicks in when neither redirect_dir or
metacopy were specified in the mount options.

[Related]
This undesirable logic was introduced by the commit that introduced the
mount option handling logic: d47748e5ae5af6572e520cc9767bbe70c22ea498
---
 fs/overlayfs/super.c | 48 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 0116735cc321..456d48f57700 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -30,10 +30,16 @@ struct ovl_dir_cache;
 #define OVL_MAX_STACK 500
 
 static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR);
-module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644);
-MODULE_PARM_DESC(ovl_redirect_dir_def,
+static bool ovl_redirect_dir_param = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR);
+module_param_named(redirect_dir, ovl_redirect_dir_param, bool, 0644);
+MODULE_PARM_DESC(ovl_redirect_dir_param,
 		 "Default to on or off for the redirect_dir feature");
 
+static inline bool ovl_redirect_dir_module_overrides_kernel(void)
+{
+	return (ovl_redirect_dir_def != ovl_redirect_dir_param);
+}
+
 static bool ovl_redirect_always_follow =
 	IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW);
 module_param_named(redirect_always_follow, ovl_redirect_always_follow,
@@ -65,10 +71,16 @@ static void ovl_entry_stack_free(struct ovl_entry *oe)
 }
 
 static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY);
-module_param_named(metacopy, ovl_metacopy_def, bool, 0644);
-MODULE_PARM_DESC(ovl_metacopy_def,
+static bool ovl_metacopy_param = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY);
+module_param_named(metacopy, ovl_metacopy_param, bool, 0644);
+MODULE_PARM_DESC(ovl_metacopy_param,
 		 "Default to on or off for the metadata only copy up feature");
 
+static inline bool ovl_metacopy_module_overrides_kernel(void)
+{
+	return (ovl_metacopy_def != ovl_metacopy_param);
+}
+
 static void ovl_dentry_release(struct dentry *dentry)
 {
 	struct ovl_entry *oe = dentry->d_fsdata;
@@ -312,7 +324,7 @@ static bool ovl_force_readonly(struct ovl_fs *ofs)
 
 static const char *ovl_redirect_mode_def(void)
 {
-	return ovl_redirect_dir_def ? "on" : "off";
+	return ovl_redirect_dir_param ? "on" : "off";
 }
 
 enum {
@@ -359,7 +371,7 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
 						"on" : "off");
 	if (ofs->config.xino != ovl_xino_def())
 		seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
-	if (ofs->config.metacopy != ovl_metacopy_def)
+	if (ofs->config.metacopy != ovl_metacopy_param)
 		seq_printf(m, ",metacopy=%s",
 			   ofs->config.metacopy ? "on" : "off");
 	return 0;
@@ -457,6 +469,7 @@ static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
 	} else if (strcmp(mode, "follow") == 0) {
 		config->redirect_follow = true;
 	} else if (strcmp(mode, "off") == 0) {
+		config->redirect_dir = false;
 		if (ovl_redirect_always_follow)
 			config->redirect_follow = true;
 	} else if (strcmp(mode, "nofollow") != 0) {
@@ -473,6 +486,8 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
 	char *p;
 	int err;
 	bool metacopy_opt = false, redirect_opt = false;
+	bool metacopy_override = ovl_metacopy_module_overrides_kernel();
+	bool redirect_override = ovl_redirect_dir_module_overrides_kernel();
 
 	config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
 	if (!config->redirect_mode)
@@ -598,8 +613,23 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
 				config->redirect_mode);
 			config->metacopy = false;
 		} else {
-			/* Automatically enable redirect otherwise. */
-			config->redirect_follow = config->redirect_dir = true;
+			if (metacopy_override && redirect_override) {
+				pr_err("overlayfs: conflicting module params: metacopy=on,redirect_dir=%s\n",
+					config->redirect_mode);
+				return -EINVAL;
+			}
+			if (redirect_override) {
+				/*
+				 * There was an explicit redirect_dir=... that resulted
+				 * in this conflict (module param)
+				 */
+				pr_info("overlayfs: disabling metacopy due to module param redirect_dir=%s\n",
+					config->redirect_mode);
+				config->metacopy = false;
+			} else {
+				/* Automatically enable redirect otherwise. */
+				config->redirect_follow = config->redirect_dir = true;
+			}
 		}
 	}
 
@@ -1439,7 +1469,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
 	ofs->config.index = ovl_index_def;
 	ofs->config.nfs_export = ovl_nfs_export_def;
 	ofs->config.xino = ovl_xino_def();
-	ofs->config.metacopy = ovl_metacopy_def;
+	ofs->config.metacopy = ovl_metacopy_param;
 	err = ovl_parse_opt((char *) data, &ofs->config);
 	if (err)
 		goto out_err;
-- 
2.21.0




[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux