Skip to content

Commit

Permalink
link_path_walk(): be careful when failing with ENOTDIR
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Al Viro committed Aug 2, 2015
1 parent cbfe8fa commit 97242f9
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,8 +1954,13 @@ static int link_path_walk(const char *name, struct nameidata *nd)
continue;
}
}
if (unlikely(!d_can_lookup(nd->path.dentry)))
if (unlikely(!d_can_lookup(nd->path.dentry))) {
if (nd->flags & LOOKUP_RCU) {
if (unlazy_walk(nd, NULL, 0))
return -ECHILD;
}
return -ENOTDIR;
}
}
}

Expand Down

0 comments on commit 97242f9

Please sign in to comment.