summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-06-16 10:38:35 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-06-19 12:35:57 -0700
commit631e1a710c0489e083d4f1276f6de787a5cf08fb (patch)
tree5d6b9ba7c68308d94a5e9e7e0e65822169aa63f0 /fs/namei.c
parent7d286849a8de41c1aee2957e224c5802d3488c8d (diff)
downloadlinux-631e1a710c0489e083d4f1276f6de787a5cf08fb.tar.gz
linux-631e1a710c0489e083d4f1276f6de787a5cf08fb.tar.bz2
linux-631e1a710c0489e083d4f1276f6de787a5cf08fb.zip
vfs: link_path_walk: clarify and improve name hashing interface
Now that we clearly only care about the length of the name we just parsed, we can simplify and clarify the interface to "name_hash()", and move the actual nd->last field setting in there. That makes everything simpler, and this way don't mix the hash and the length together only to then immediately unmix them again. We still eventually want the combined mixed "hashlen" for when we look things up in the dentry cache, but inside link_path_walk() it's simpler and clearer to just deal with the path component length. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/namei.c b/fs/namei.c
index f3c91d8ae140..40929d3cdf76 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2165,9 +2165,9 @@ EXPORT_SYMBOL(hashlen_string);
* Calculate the length and hash of the path component, and
* return the "hash_len" as the result.
*/
-static inline u64 hash_name(const void *salt, const char *name)
+static inline unsigned long hash_name(struct nameidata *nd, const char *name)
{
- unsigned long a = 0, b, x = 0, y = (unsigned long)salt;
+ unsigned long a = 0, b, x = 0, y = (unsigned long)nd->path.dentry;
unsigned long adata, bdata, mask, len;
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
@@ -2186,8 +2186,11 @@ inside:
bdata = prep_zero_mask(b, bdata, &constants);
mask = create_zero_mask(adata | bdata);
x ^= a & zero_bytemask(mask);
+ len += find_zero(mask);
- return hashlen_create(fold_hash(x, y), len + find_zero(mask));
+ nd->last.hash = fold_hash(x, y);
+ nd->last.len = len;
+ return len;
}
#else /* !CONFIG_DCACHE_WORD_ACCESS: Slow, byte-at-a-time version */
@@ -2222,9 +2225,9 @@ EXPORT_SYMBOL(hashlen_string);
* We know there's a real path component here of at least
* one character.
*/
-static inline u64 hash_name(const void *salt, const char *name)
+static inline unsigned long hash_name(struct nameidata *nd, const char *name)
{
- unsigned long hash = init_name_hash(salt);
+ unsigned long hash = init_name_hash(nd->path.dentry);
unsigned long len = 0, c;
c = (unsigned char)*name;
@@ -2233,7 +2236,9 @@ static inline u64 hash_name(const void *salt, const char *name)
hash = partial_name_hash(c, hash);
c = (unsigned char)name[len];
} while (c && c != '/');
- return hashlen_create(end_name_hash(hash), len);
+ nd->last.hash = end_name_hash(hash);
+ nd->last.len = len;
+ return len;
}
#endif
@@ -2275,8 +2280,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
return err;
nd->last.name = name;
- nd->last.hash_len = hash_name(nd->path.dentry, name);
- len = hashlen_len(nd->last.hash_len);
+ len = hash_name(nd, name);
name += len;
type = LAST_NORM;