aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2018-11-01 16:31:39 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2018-11-01 16:31:39 -0400
commitd47748e5ae5af6572e520cc9767bbe70c22ea498 (patch)
treeae33bdfffaaa6c1e9297d33f39dff2ddee4ddb24
parent5e1275808630ea3b2c97c776f40e475017535f72 (diff)
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: d5791044d2e5 ("ovl: Provide a mount option metacopy=on/off...") Cc: <stable@vger.kernel.org> # v4.19 Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--Documentation/filesystems/overlayfs.txt6
-rw-r--r--fs/overlayfs/super.c36
2 files changed, 35 insertions, 7 deletions
diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt
index 51c136c821bf..eef7d9d259e8 100644
--- a/Documentation/filesystems/overlayfs.txt
+++ b/Documentation/filesystems/overlayfs.txt
@@ -286,6 +286,12 @@ pointed by REDIRECT. This should not be possible on local system as setting
286"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible 286"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
287for untrusted layers like from a pen drive. 287for untrusted layers like from a pen drive.
288 288
289Note: redirect_dir={off|nofollow|follow(*)} conflicts with metacopy=on, and
290results in an error.
291
292(*) redirect_dir=follow only conflicts with metacopy=on if upperdir=... is
293given.
294
289Sharing and copying layers 295Sharing and copying layers
290-------------------------- 296--------------------------
291 297
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 22ffb23ea44d..0116735cc321 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -472,6 +472,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
472{ 472{
473 char *p; 473 char *p;
474 int err; 474 int err;
475 bool metacopy_opt = false, redirect_opt = false;
475 476
476 config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL); 477 config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
477 if (!config->redirect_mode) 478 if (!config->redirect_mode)
@@ -516,6 +517,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
516 config->redirect_mode = match_strdup(&args[0]); 517 config->redirect_mode = match_strdup(&args[0]);
517 if (!config->redirect_mode) 518 if (!config->redirect_mode)
518 return -ENOMEM; 519 return -ENOMEM;
520 redirect_opt = true;
519 break; 521 break;
520 522
521 case OPT_INDEX_ON: 523 case OPT_INDEX_ON:
@@ -548,6 +550,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
548 550
549 case OPT_METACOPY_ON: 551 case OPT_METACOPY_ON:
550 config->metacopy = true; 552 config->metacopy = true;
553 metacopy_opt = true;
551 break; 554 break;
552 555
553 case OPT_METACOPY_OFF: 556 case OPT_METACOPY_OFF:
@@ -572,13 +575,32 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
572 if (err) 575 if (err)
573 return err; 576 return err;
574 577
575 /* metacopy feature with upper requires redirect_dir=on */ 578 /*
576 if (config->upperdir && config->metacopy && !config->redirect_dir) { 579 * This is to make the logic below simpler. It doesn't make any other
577 pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=on\", falling back to metacopy=off.\n"); 580 * difference, since config->redirect_dir is only used for upper.
578 config->metacopy = false; 581 */
579 } else if (config->metacopy && !config->redirect_follow) { 582 if (!config->upperdir && config->redirect_follow)
580 pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=follow\" on non-upper mount, falling back to metacopy=off.\n"); 583 config->redirect_dir = true;
581 config->metacopy = false; 584
585 /* Resolve metacopy -> redirect_dir dependency */
586 if (config->metacopy && !config->redirect_dir) {
587 if (metacopy_opt && redirect_opt) {
588 pr_err("overlayfs: conflicting options: metacopy=on,redirect_dir=%s\n",
589 config->redirect_mode);
590 return -EINVAL;
591 }
592 if (redirect_opt) {
593 /*
594 * There was an explicit redirect_dir=... that resulted
595 * in this conflict.
596 */
597 pr_info("overlayfs: disabling metacopy due to redirect_dir=%s\n",
598 config->redirect_mode);
599 config->metacopy = false;
600 } else {
601 /* Automatically enable redirect otherwise. */
602 config->redirect_follow = config->redirect_dir = true;
603 }
582 } 604 }
583 605
584 return 0; 606 return 0;