d_same_name() used to only check if the name exists in any of the directory's children. In order to fix lookup of /, the function was changed to also compare the name against the parent. This is obviously wrong, when the parent and child have the same name: Resolution of the child would always return the parent dentry triggering unexpected behavior. Fix this by effectively reverting the functional change in commit 3a478ff3e1e6 ("fs: support opening /"). This breaks opening /, but that currently only affects dirfd usage and will be fixed separately. Fixes: 3a478ff3e1e6 ("fs: support opening /") Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- fs/fs.c | 3 --- test/self/dirfd.c | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/fs.c b/fs/fs.c index 57bd781025f9..235fb8f8e9ef 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -1536,9 +1536,6 @@ static struct dentry *d_lookup(struct dentry *parent, const struct qstr *name) { struct dentry *dentry; - if (d_same_name(parent, name)) - return dget(parent); - list_for_each_entry(dentry, &parent->d_subdirs, d_child) { if (d_same_name(dentry, name)) return dget(dentry); diff --git a/test/self/dirfd.c b/test/self/dirfd.c index 20b54258715a..644ff214fb37 100644 --- a/test/self/dirfd.c +++ b/test/self/dirfd.c @@ -100,8 +100,13 @@ static void test_dirfd(void) int fd; fd = open("/", O_PATH); - if (expect(fd < 0, false, "open(/, O_PATH) = %d", fd)) + if (expect(fd < 0, false, "open(/, O_PATH) = %d", fd)) { close(fd); + } else { + pr_info("\tIgnoring expected failure\n"); + failed_tests--; + skipped_tests++; + } #define B(dot, dotdot, zero, dev) 0b##dev##zero##dotdot##dot /* We do fiften tests for every configuration -- 2.39.5