]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Set d_bucket correctly for anonymous dentries
authorAndrew Morton <akpm@osdl.org>
Thu, 27 May 2004 00:35:31 +0000 (17:35 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 27 May 2004 00:35:31 +0000 (17:35 -0700)
From: Neil Brown <neilb@cse.unsw.edu.au>

In researching the oopses reported in bug #2761, Neil came up with:

I have found one problem, but it isn't particularly new and I cannot
 see how it would be related.

When d_alloc_anon creates an anonymous dentry, it is put on a special hash
chain for anonymous dentries (sb->s_anon), but d_bucket is set to

   d_hash(parent, name_hash)

If, when it is eventually moved to a proper name, that hash value is the same
as the final hash value, it will not be moved to the right bucket, and so it
not be accessible by name.  This patch should fix it.

anonymous dentries have their own private hash "bucket" (sb->s_anon) and so
d_bucket should be set to a unique (impossible) address, else d_move will
get confused.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
fs/dcache.c

index 62925977d29923ec4cdb3432c5db31beeca6fbbe..c308ad76aa7b856c031eb768ec8fe6fa5a7a3ecc 100644 (file)
@@ -846,7 +846,12 @@ struct dentry * d_alloc_anon(struct inode *inode)
                        res->d_sb = inode->i_sb;
                        res->d_parent = res;
                        res->d_inode = inode;
-                       res->d_bucket = d_hash(res, res->d_name.hash);
+
+                       /*
+                        * Set d_bucket to an "impossible" bucket address so
+                        * that d_move() doesn't get a false positive
+                        */
+                       res->d_bucket = dentry_hashtable + D_HASHMASK + 1;
                        res->d_flags |= DCACHE_DISCONNECTED;
                        res->d_flags &= ~DCACHE_UNHASHED;
                        list_add(&res->d_alias, &inode->i_dentry);