[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:
parent
92476d7fc0
commit
3e7e241f8c
2 changed files with 29 additions and 16 deletions
44
fs/dcache.c
44
fs/dcache.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in a new issue