No. This is why:
lookup_dentry() uses this code to calculate the hash value:
hash = init_name_hash();
do {
name++;
hash = partial_name_hash(c, hash);
c = *(const unsigned char *)name;
} while (c && (c != '/'));
this.len = name - (const char *) this.name;
this.hash = end_name_hash(hash);
Later on, it uses this.hash to call cached_lookup():
/* This does the actual lookups.. */
dentry = reserved_lookup(base, &this);
if (!dentry) {
dentry = cached_lookup(base, &this);
if (!dentry) {
dentry = real_lookup(base, &this);
if (IS_ERR(dentry))
break;
}
}
cached_lookup() uses d_lookup() to lookup a dentry in the cache:
static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
{
struct dentry * dentry = d_lookup(parent, name);
if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
if (!dentry->d_op->d_revalidate(dentry) && !d_invalidate(dentry)) {
dput(dentry);
dentry = NULL;
}
}
return dentry;
}
d_lookup() uses d_hash() to get the list_head of the external linking
of the hash table:
struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
{
unsigned int len = name->len;
unsigned int hash = name->hash;
const unsigned char *str = name->name;
struct list_head *head = d_hash(parent,hash);
struct list_head *tmp = head->next;
d_hash() uses the hash value to get a pointer into the dentry_hashtable:
static inline struct list_head * d_hash(struct dentry * parent, unsigned long ha
sh)
{
hash += (unsigned long) parent;
hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
return dentry_hashtable + (hash & D_HASHMASK);
}
If the hash value is different from that produced by full_name_hash(),
it will get the wrong link chain, and it will never find the entry
that was put there by using full_name_hash().
/Magnus
map@stacken.kth.se
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/