aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 746ea36f3171..9b18e0f9016a 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1471,23 +1471,20 @@ out_err:
1471 * Check if this layer root is a descendant of: 1471 * Check if this layer root is a descendant of:
1472 * - another layer of this overlayfs instance 1472 * - another layer of this overlayfs instance
1473 * - upper/work dir of any overlayfs instance 1473 * - upper/work dir of any overlayfs instance
1474 * - a disconnected dentry (detached root)
1475 */ 1474 */
1476static int ovl_check_layer(struct super_block *sb, struct dentry *dentry, 1475static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
1477 const char *name) 1476 const char *name)
1478{ 1477{
1479 struct dentry *next, *parent; 1478 struct dentry *next = dentry, *parent;
1480 bool is_root = false;
1481 int err = 0; 1479 int err = 0;
1482 1480
1483 if (!dentry || dentry == dentry->d_sb->s_root) 1481 if (!dentry)
1484 return 0; 1482 return 0;
1485 1483
1486 next = dget(dentry); 1484 parent = dget_parent(next);
1487 /* Walk back ancestors to fs root (inclusive) looking for traps */ 1485
1488 do { 1486 /* Walk back ancestors to root (inclusive) looking for traps */
1489 parent = dget_parent(next); 1487 while (!err && parent != next) {
1490 is_root = (parent == next);
1491 if (ovl_is_inuse(parent)) { 1488 if (ovl_is_inuse(parent)) {
1492 err = -EBUSY; 1489 err = -EBUSY;
1493 pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n", 1490 pr_err("overlayfs: %s path overlapping in-use upperdir/workdir\n",
@@ -1496,17 +1493,12 @@ static int ovl_check_layer(struct super_block *sb, struct dentry *dentry,
1496 err = -ELOOP; 1493 err = -ELOOP;
1497 pr_err("overlayfs: overlapping %s path\n", name); 1494 pr_err("overlayfs: overlapping %s path\n", name);
1498 } 1495 }
1499 dput(next);
1500 next = parent; 1496 next = parent;
1501 } while (!err && !is_root); 1497 parent = dget_parent(next);
1502 1498 dput(next);
1503 /* Did we really walk to fs root or found a detached root? */
1504 if (!err && next != dentry->d_sb->s_root) {
1505 err = -ESTALE;
1506 pr_err("overlayfs: disconnected %s path\n", name);
1507 } 1499 }
1508 1500
1509 dput(next); 1501 dput(parent);
1510 1502
1511 return err; 1503 return err;
1512} 1504}