summaryrefslogtreecommitdiff
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2019-06-18 15:06:16 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-25 11:35:52 +0800
commit639e8c2f0910a57e9a29d9508ea6ed0960e8d4fe (patch)
tree295cbd1da39180542a80a3d109423840f2178f1f /fs/overlayfs
parentf1c5aa5eda08710c2ba619d93126380881fa1114 (diff)
ovl: don't fail with disconnected lower NFS
[ Upstream commit 9179c21dc6ed1c993caa5fe4da876a6765c26af7 ] NFS mounts can be disconnected from fs root. Don't fail the overlapping layer check because of this. The check is not authoritative anyway, since topology can change during or after the check. Reported-by: Antti Antinoja <antti@fennosys.fi> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Fixes: 146d62e5a586 ("ovl: detect overlapping layers") Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r--fs/overlayfs/super.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 4e268f981b4d..d6e60a7156a1 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1444,23 +1444,20 @@ out_err:
* Check if this layer root is a descendant of:
* - another layer of this overlayfs instance
* - upper/work dir of any overlayfs instance
- * - a disconnected dentry (detached root)
*/
static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
const char *name)
{
- struct dentry *next, *parent;
- bool is_root = false;
+ struct dentry *next = dentry, *parent;
int err = 0;
- if (!dentry || dentry == dentry->d_sb->s_root)
+ if (!dentry)
return 0;
- next = dget(dentry);
- /* Walk back ancestors to fs root (inclusive) looking for traps */
- do {
- parent = dget_parent(next);
- is_root = (parent == next);
+ parent = dget_parent(next);
+
+ /* Walk back ancestors to root (inclusive) looking for traps */
+ while (!err && parent != next) {
if (ovl_is_inuse(parent)) {
err = -EBUSY;
pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n",
@@ -1469,17 +1466,12 @@ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
err = -ELOOP;
pr_err("overlayfs: overlapping %s path\n", name);
}
- dput(next);
next = parent;
- } while (!err && !is_root);
-
- /* Did we really walk to fs root or found a detached root? */
- if (!err && next != dentry->d_sb->s_root) {
- err = -ESTALE;
- pr_err("overlayfs: disconnected %s path\n", name);
+ parent = dget_parent(next);
+ dput(next);
}
- dput(next);
+ dput(parent);
return err;
}