ovl: automatically enable redirect_dir on metacopy=on
Current behavior is to automatically disable metacopy if redirect_dir is
not enabled and proceed with the mount.
If "metacopy=on" mount option was given, then this behavior can confuse the
user: no mount failure, yet metacopy is disabled.
This patch makes metacopy=on imply redirect_dir=on.
The converse is also true: turning off full redirect with redirect_dir=
{off|follow|nofollow} will disable metacopy.
If both metacopy=on and redirect_dir={off|follow|nofollow} is specified,
then mount will fail, since there's no way to correctly resolve the
conflict.
Reported-by: Daniel Walsh <dwalsh@redhat.com>
Fixes: d5791044d2
("ovl: Provide a mount option metacopy=on/off...")
Cc: <stable@vger.kernel.org> # v4.19
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
5e12758086
commit
d47748e5ae
2 changed files with 35 additions and 7 deletions
|
@ -286,6 +286,12 @@ pointed by REDIRECT. This should not be possible on local system as setting
|
||||||
"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
|
"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
|
||||||
for untrusted layers like from a pen drive.
|
for untrusted layers like from a pen drive.
|
||||||
|
|
||||||
|
Note: redirect_dir={off|nofollow|follow(*)} conflicts with metacopy=on, and
|
||||||
|
results in an error.
|
||||||
|
|
||||||
|
(*) redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
|
||||||
|
given.
|
||||||
|
|
||||||
Sharing and copying layers
|
Sharing and copying layers
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
|
|
@ -472,6 +472,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int err;
|
int err;
|
||||||
|
bool metacopy_opt = false, redirect_opt = false;
|
||||||
|
|
||||||
config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
|
config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
|
||||||
if (!config->redirect_mode)
|
if (!config->redirect_mode)
|
||||||
|
@ -516,6 +517,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
|
||||||
config->redirect_mode = match_strdup(&args[0]);
|
config->redirect_mode = match_strdup(&args[0]);
|
||||||
if (!config->redirect_mode)
|
if (!config->redirect_mode)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
redirect_opt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_INDEX_ON:
|
case OPT_INDEX_ON:
|
||||||
|
@ -548,6 +550,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
|
||||||
|
|
||||||
case OPT_METACOPY_ON:
|
case OPT_METACOPY_ON:
|
||||||
config->metacopy = true;
|
config->metacopy = true;
|
||||||
|
metacopy_opt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_METACOPY_OFF:
|
case OPT_METACOPY_OFF:
|
||||||
|
@ -572,13 +575,32 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* metacopy feature with upper requires redirect_dir=on */
|
/*
|
||||||
if (config->upperdir && config->metacopy && !config->redirect_dir) {
|
* This is to make the logic below simpler. It doesn't make any other
|
||||||
pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=on\", falling back to metacopy=off.\n");
|
* difference, since config->redirect_dir is only used for upper.
|
||||||
config->metacopy = false;
|
*/
|
||||||
} else if (config->metacopy && !config->redirect_follow) {
|
if (!config->upperdir && config->redirect_follow)
|
||||||
pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=follow\" on non-upper mount, falling back to metacopy=off.\n");
|
config->redirect_dir = true;
|
||||||
config->metacopy = false;
|
|
||||||
|
/* Resolve metacopy -> redirect_dir dependency */
|
||||||
|
if (config->metacopy && !config->redirect_dir) {
|
||||||
|
if (metacopy_opt && redirect_opt) {
|
||||||
|
pr_err("overlayfs: conflicting options: metacopy=on,redirect_dir=%s\n",
|
||||||
|
config->redirect_mode);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (redirect_opt) {
|
||||||
|
/*
|
||||||
|
* There was an explicit redirect_dir=... that resulted
|
||||||
|
* in this conflict.
|
||||||
|
*/
|
||||||
|
pr_info("overlayfs: disabling metacopy due to redirect_dir=%s\n",
|
||||||
|
config->redirect_mode);
|
||||||
|
config->metacopy = false;
|
||||||
|
} else {
|
||||||
|
/* Automatically enable redirect otherwise. */
|
||||||
|
config->redirect_follow = config->redirect_dir = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue