Skip to content

Commit 165200d

Browse files
author
Al Viro
committed
follow_dotdot(): be lazy about changing nd->path
Change nd->path only after the loop is done and only in case we hadn't ended up finding ourselves in root. Same for NO_XDEV check. That separates the "check how far back do we need to go through the mount stack" logics from the rest of .. traversal. NOTE: path_get/path_put introduced here are temporary. They will go away later in the series. Signed-off-by: Al Viro <[email protected]>
1 parent efe772d commit 165200d

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

fs/namei.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,16 +1748,24 @@ static struct dentry *follow_dotdot(struct nameidata *nd,
17481748
if (path_equal(&nd->path, &nd->root))
17491749
goto in_root;
17501750
if (unlikely(nd->path.dentry == nd->path.mnt->mnt_root)) {
1751+
struct path path = nd->path;
1752+
path_get(&path);
17511753
while (1) {
1752-
if (!follow_up(&nd->path))
1754+
if (!follow_up(&path)) {
1755+
path_put(&path);
17531756
goto in_root;
1754-
if (unlikely(nd->flags & LOOKUP_NO_XDEV))
1755-
return ERR_PTR(-EXDEV);
1756-
if (path_equal(&nd->path, &nd->root))
1757+
}
1758+
if (path_equal(&path, &nd->root)) {
1759+
path_put(&path);
17571760
goto in_root;
1758-
if (nd->path.dentry != nd->path.mnt->mnt_root)
1761+
}
1762+
if (path.dentry != nd->path.mnt->mnt_root)
17591763
break;
17601764
}
1765+
path_put(&nd->path);
1766+
nd->path = path;
1767+
if (unlikely(nd->flags & LOOKUP_NO_XDEV))
1768+
return ERR_PTR(-EXDEV);
17611769
}
17621770
/* rare case of legitimate dget_parent()... */
17631771
parent = dget_parent(nd->path.dentry);

0 commit comments

Comments
 (0)