Skip to content

Commit 631e1a7

Browse files
committed
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 <[email protected]>
1 parent 7d28684 commit 631e1a7

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

fs/namei.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,9 +2165,9 @@ EXPORT_SYMBOL(hashlen_string);
21652165
* Calculate the length and hash of the path component, and
21662166
* return the "hash_len" as the result.
21672167
*/
2168-
static inline u64 hash_name(const void *salt, const char *name)
2168+
static inline unsigned long hash_name(struct nameidata *nd, const char *name)
21692169
{
2170-
unsigned long a = 0, b, x = 0, y = (unsigned long)salt;
2170+
unsigned long a = 0, b, x = 0, y = (unsigned long)nd->path.dentry;
21712171
unsigned long adata, bdata, mask, len;
21722172
const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
21732173

@@ -2186,8 +2186,11 @@ static inline u64 hash_name(const void *salt, const char *name)
21862186
bdata = prep_zero_mask(b, bdata, &constants);
21872187
mask = create_zero_mask(adata | bdata);
21882188
x ^= a & zero_bytemask(mask);
2189+
len += find_zero(mask);
21892190

2190-
return hashlen_create(fold_hash(x, y), len + find_zero(mask));
2191+
nd->last.hash = fold_hash(x, y);
2192+
nd->last.len = len;
2193+
return len;
21912194
}
21922195

21932196
#else /* !CONFIG_DCACHE_WORD_ACCESS: Slow, byte-at-a-time version */
@@ -2222,9 +2225,9 @@ EXPORT_SYMBOL(hashlen_string);
22222225
* We know there's a real path component here of at least
22232226
* one character.
22242227
*/
2225-
static inline u64 hash_name(const void *salt, const char *name)
2228+
static inline unsigned long hash_name(struct nameidata *nd, const char *name)
22262229
{
2227-
unsigned long hash = init_name_hash(salt);
2230+
unsigned long hash = init_name_hash(nd->path.dentry);
22282231
unsigned long len = 0, c;
22292232

22302233
c = (unsigned char)*name;
@@ -2233,7 +2236,9 @@ static inline u64 hash_name(const void *salt, const char *name)
22332236
hash = partial_name_hash(c, hash);
22342237
c = (unsigned char)name[len];
22352238
} while (c && c != '/');
2236-
return hashlen_create(end_name_hash(hash), len);
2239+
nd->last.hash = end_name_hash(hash);
2240+
nd->last.len = len;
2241+
return len;
22372242
}
22382243

22392244
#endif
@@ -2275,8 +2280,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
22752280
return err;
22762281

22772282
nd->last.name = name;
2278-
nd->last.hash_len = hash_name(nd->path.dentry, name);
2279-
len = hashlen_len(nd->last.hash_len);
2283+
len = hash_name(nd, name);
22802284
name += len;
22812285

22822286
type = LAST_NORM;

0 commit comments

Comments
 (0)