--- /dev/null
+From 708fa01597fa002599756bf56a96d0de1677375c Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Mon, 12 Apr 2021 12:00:37 +0200
+Subject: ovl: allow upperdir inside lowerdir
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 708fa01597fa002599756bf56a96d0de1677375c upstream.
+
+Commit 146d62e5a586 ("ovl: detect overlapping layers") made sure we don't
+have overlapping layers, but it also broke the arguably valid use case of
+
+ mount -olowerdir=/,upperdir=/subdir,..
+
+where upperdir overlaps lowerdir on the same filesystem. This has been
+causing regressions.
+
+Revert the check, but only for the specific case where upperdir and/or
+workdir are subdirectories of lowerdir. Any other overlap (e.g. lowerdir
+is subdirectory of upperdir, etc) case is crazy, so leave the check in
+place for those.
+
+Overlaps are detected at lookup time too, so reverting the mount time check
+should be safe.
+
+Fixes: 146d62e5a586 ("ovl: detect overlapping layers")
+Cc: <stable@vger.kernel.org> # v5.2
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/super.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1479,7 +1479,8 @@ out_err:
+ * - upper/work dir of any overlayfs instance
+ */
+ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
+- struct dentry *dentry, const char *name)
++ struct dentry *dentry, const char *name,
++ bool is_lower)
+ {
+ struct dentry *next = dentry, *parent;
+ int err = 0;
+@@ -1491,7 +1492,7 @@ static int ovl_check_layer(struct super_
+
+ /* Walk back ancestors to root (inclusive) looking for traps */
+ while (!err && parent != next) {
+- if (ovl_lookup_trap_inode(sb, parent)) {
++ if (is_lower && ovl_lookup_trap_inode(sb, parent)) {
+ err = -ELOOP;
+ pr_err("overlayfs: overlapping %s path\n", name);
+ } else if (ovl_is_inuse(parent)) {
+@@ -1517,7 +1518,7 @@ static int ovl_check_overlapping_layers(
+
+ if (ofs->upper_mnt) {
+ err = ovl_check_layer(sb, ofs, ofs->upper_mnt->mnt_root,
+- "upperdir");
++ "upperdir", false);
+ if (err)
+ return err;
+
+@@ -1528,7 +1529,8 @@ static int ovl_check_overlapping_layers(
+ * workbasedir. In that case, we already have their traps in
+ * inode cache and we will catch that case on lookup.
+ */
+- err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir");
++ err = ovl_check_layer(sb, ofs, ofs->workbasedir, "workdir",
++ false);
+ if (err)
+ return err;
+ }
+@@ -1536,7 +1538,7 @@ static int ovl_check_overlapping_layers(
+ for (i = 0; i < ofs->numlower; i++) {
+ err = ovl_check_layer(sb, ofs,
+ ofs->lower_layers[i].mnt->mnt_root,
+- "lowerdir");
++ "lowerdir", true);
+ if (err)
+ return err;
+ }