diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-03-31 05:31:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-31 15:19:00 -0500 |
commit | 3e7e241f8c5c87cc3685364feface081c9fa3648 (patch) | |
tree | 43ea46cfec4da31a505e93875feeac945bf906ce | |
parent | 92476d7fc0326a409ab1d3864a04093a6be9aca7 (diff) |
[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>
-rw-r--r-- | fs/dcache.c | 44 | ||||
-rw-r--r-- | include/linux/dcache.h | 1 |
2 files changed, 29 insertions, 16 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 21dffeec755b..940d188e5d14 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1101,6 +1101,32 @@ next: | |||
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | /** | 1103 | /** |
1104 | * d_hash_and_lookup - hash the qstr then search for a dentry | ||
1105 | * @dir: Directory to search in | ||
1106 | * @name: qstr of name we wish to find | ||
1107 | * | ||
1108 | * On hash failure or on lookup failure NULL is returned. | ||
1109 | */ | ||
1110 | struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) | ||
1111 | { | ||
1112 | struct dentry *dentry = NULL; | ||
1113 | |||
1114 | /* | ||
1115 | * Check for a fs-specific hash function. Note that we must | ||
1116 | * calculate the standard hash first, as the d_op->d_hash() | ||
1117 | * routine may choose to leave the hash value unchanged. | ||
1118 | */ | ||
1119 | name->hash = full_name_hash(name->name, name->len); | ||
1120 | if (dir->d_op && dir->d_op->d_hash) { | ||
1121 | if (dir->d_op->d_hash(dir, name) < 0) | ||
1122 | goto out; | ||
1123 | } | ||
1124 | dentry = d_lookup(dir, name); | ||
1125 | out: | ||
1126 | return dentry; | ||
1127 | } | ||
1128 | |||
1129 | /** | ||
1104 | * d_validate - verify dentry provided from insecure source | 1130 | * d_validate - verify dentry provided from insecure source |
1105 | * @dentry: The dentry alleged to be valid child of @dparent | 1131 | * @dentry: The dentry alleged to be valid child of @dparent |
1106 | * @dparent: The parent dentry (known to be valid) | 1132 | * @dparent: The parent dentry (known to be valid) |
@@ -1616,26 +1642,12 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name) | |||
1616 | struct dentry * dentry; | 1642 | struct dentry * dentry; |
1617 | ino_t ino = 0; | 1643 | ino_t ino = 0; |
1618 | 1644 | ||
1619 | /* | 1645 | dentry = d_hash_and_lookup(dir, name); |
1620 | * Check for a fs-specific hash function. Note that we must | 1646 | if (dentry) { |
1621 | * calculate the standard hash first, as the d_op->d_hash() | ||
1622 | * routine may choose to leave the hash value unchanged. | ||
1623 | */ | ||
1624 | name->hash = full_name_hash(name->name, name->len); | ||
1625 | if (dir->d_op && dir->d_op->d_hash) | ||
1626 | { | ||
1627 | if (dir->d_op->d_hash(dir, name) != 0) | ||
1628 | goto out; | ||
1629 | } | ||
1630 | |||
1631 | dentry = d_lookup(dir, name); | ||
1632 | if (dentry) | ||
1633 | { | ||
1634 | if (dentry->d_inode) | 1647 | if (dentry->d_inode) |
1635 | ino = dentry->d_inode->i_ino; | 1648 | ino = dentry->d_inode->i_ino; |
1636 | dput(dentry); | 1649 | dput(dentry); |
1637 | } | 1650 | } |
1638 | out: | ||
1639 | return ino; | 1651 | return ino; |
1640 | } | 1652 | } |
1641 | 1653 | ||
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index d10bd30c337e..836325ee0931 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -275,6 +275,7 @@ extern void d_move(struct dentry *, struct dentry *); | |||
275 | /* appendix may either be NULL or be used for transname suffixes */ | 275 | /* appendix may either be NULL or be used for transname suffixes */ |
276 | extern struct dentry * d_lookup(struct dentry *, struct qstr *); | 276 | extern struct dentry * d_lookup(struct dentry *, struct qstr *); |
277 | extern struct dentry * __d_lookup(struct dentry *, struct qstr *); | 277 | extern struct dentry * __d_lookup(struct dentry *, struct qstr *); |
278 | extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *); | ||
278 | 279 | ||
279 | /* validate "insecure" dentry pointer */ | 280 | /* validate "insecure" dentry pointer */ |
280 | extern int d_validate(struct dentry *, struct dentry *); | 281 | extern int d_validate(struct dentry *, struct dentry *); |