Skip to content

Commit 97242f9

Browse files
author
Al Viro
committed
link_path_walk(): be careful when failing with ENOTDIR
In RCU mode we might end up with dentry evicted just we check that it's a directory. In such case we should return ECHILD rather than ENOTDIR, so that pathwalk would be retries in non-RCU mode. Breakage had been introduced in commit b18825a - prior to that we were looking at nd->inode, which had been fetched before verifying that ->d_seq was still valid. That form of check would only be satisfied if at some point the pathname prefix would indeed have resolved to a non-directory. The fix consists of checking ->d_seq after we'd run into a non-directory dentry, and failing with ECHILD in case of mismatch. Note that all branches since 3.12 have that problem... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent cbfe8fa commit 97242f9

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

fs/namei.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1954,8 +1954,13 @@ static int link_path_walk(const char *name, struct nameidata *nd)
19541954
continue;
19551955
}
19561956
}
1957-
if (unlikely(!d_can_lookup(nd->path.dentry)))
1957+
if (unlikely(!d_can_lookup(nd->path.dentry))) {
1958+
if (nd->flags & LOOKUP_RCU) {
1959+
if (unlazy_walk(nd, NULL, 0))
1960+
return -ECHILD;
1961+
}
19581962
return -ENOTDIR;
1963+
}
19591964
}
19601965
}
19611966

0 commit comments

Comments
 (0)