diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-06-16 10:38:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-06-19 12:35:57 -0700 |
commit | 631e1a710c0489e083d4f1276f6de787a5cf08fb (patch) | |
tree | 5d6b9ba7c68308d94a5e9e7e0e65822169aa63f0 /fs/namei.c | |
parent | 7d286849a8de41c1aee2957e224c5802d3488c8d (diff) | |
download | linux-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.c | 20 |
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; |