[PATCH] dcache: Add helper d_hash_and_lookup

It is very common to hash a dentry and then to call lookup.  If we take fs
specific hash functions into account the full hash logic can get ugly.
Further full_name_hash as an inline function is almost 100 bytes on x86 so
having a non-inline choice in some cases can measurably decrease code size.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Eric W. Biederman 2006-03-31 02:31:43 -08:00 committed by Linus Torvalds
parent 92476d7fc0
commit 3e7e241f8c
2 changed files with 29 additions and 16 deletions

View file

@ -1100,6 +1100,32 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
return found; return found;
} }
/**
* d_hash_and_lookup - hash the qstr then search for a dentry
* @dir: Directory to search in
* @name: qstr of name we wish to find
*
* On hash failure or on lookup failure NULL is returned.
*/
struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
{
struct dentry *dentry = NULL;
/*
* Check for a fs-specific hash function. Note that we must
* calculate the standard hash first, as the d_op->d_hash()
* routine may choose to leave the hash value unchanged.
*/
name->hash = full_name_hash(name->name, name->len);
if (dir->d_op && dir->d_op->d_hash) {
if (dir->d_op->d_hash(dir, name) < 0)
goto out;
}
dentry = d_lookup(dir, name);
out:
return dentry;
}
/** /**
* d_validate - verify dentry provided from insecure source * d_validate - verify dentry provided from insecure source
* @dentry: The dentry alleged to be valid child of @dparent * @dentry: The dentry alleged to be valid child of @dparent
@ -1616,26 +1642,12 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
struct dentry * dentry; struct dentry * dentry;
ino_t ino = 0; ino_t ino = 0;
/* dentry = d_hash_and_lookup(dir, name);
* Check for a fs-specific hash function. Note that we must if (dentry) {
* calculate the standard hash first, as the d_op->d_hash()
* routine may choose to leave the hash value unchanged.
*/
name->hash = full_name_hash(name->name, name->len);
if (dir->d_op && dir->d_op->d_hash)
{
if (dir->d_op->d_hash(dir, name) != 0)
goto out;
}
dentry = d_lookup(dir, name);
if (dentry)
{
if (dentry->d_inode) if (dentry->d_inode)
ino = dentry->d_inode->i_ino; ino = dentry->d_inode->i_ino;
dput(dentry); dput(dentry);
} }
out:
return ino; return ino;
} }

View file

@ -275,6 +275,7 @@ extern void d_move(struct dentry *, struct dentry *);
/* appendix may either be NULL or be used for transname suffixes */ /* appendix may either be NULL or be used for transname suffixes */
extern struct dentry * d_lookup(struct dentry *, struct qstr *); extern struct dentry * d_lookup(struct dentry *, struct qstr *);
extern struct dentry * __d_lookup(struct dentry *, struct qstr *); extern struct dentry * __d_lookup(struct dentry *, struct qstr *);
extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *);
/* validate "insecure" dentry pointer */ /* validate "insecure" dentry pointer */
extern int d_validate(struct dentry *, struct dentry *); extern int d_validate(struct dentry *, struct dentry *);