提交 874d896f 编写于 作者: M Miklos Szeredi 提交者: Xie XiuQi

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: NAntti Antinoja <antti@fennosys.fi>
Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
Fixes: 146d62e5a586 ("ovl: detect overlapping layers")
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 f0796cdd
...@@ -1472,23 +1472,20 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb, ...@@ -1472,23 +1472,20 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
* Check if this layer root is a descendant of: * Check if this layer root is a descendant of:
* - another layer of this overlayfs instance * - another layer of this overlayfs instance
* - upper/work dir of any 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, static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
const char *name) const char *name)
{ {
struct dentry *next, *parent; struct dentry *next = dentry, *parent;
bool is_root = false;
int err = 0; int err = 0;
if (!dentry || dentry == dentry->d_sb->s_root) if (!dentry)
return 0; return 0;
next = dget(dentry); parent = dget_parent(next);
/* Walk back ancestors to fs root (inclusive) looking for traps */
do { /* Walk back ancestors to root (inclusive) looking for traps */
parent = dget_parent(next); while (!err && parent != next) {
is_root = (parent == next);
if (ovl_is_inuse(parent)) { if (ovl_is_inuse(parent)) {
err = -EBUSY; err = -EBUSY;
pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n", pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n",
...@@ -1497,17 +1494,12 @@ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry, ...@@ -1497,17 +1494,12 @@ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
err = -ELOOP; err = -ELOOP;
pr_err("overlayfs: overlapping %s path\n", name); pr_err("overlayfs: overlapping %s path\n", name);
} }
dput(next);
next = parent; next = parent;
} while (!err && !is_root); parent = dget_parent(next);
dput(next);
/* 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);
} }
dput(next); dput(parent);
return err; return err;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册