Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tomoyo: improve hash bucket dispersion

When examining the network device name hash, it was discovered that
the low order bits of full_name_hash() are not very well dispersed
across the possible values. When used by filesystem code, this is handled
by folding with the function hash_long().

The only other non-filesystem usage of full_name_hash() at this time
appears to be in TOMOYO. This patch should fix that.

I do not use TOMOYO at this time, so this patch is build tested only.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Acked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>

authored by

Stephen Hemminger and committed by
James Morris
024e1a49 d6ba4521

+9 -4
+9 -4
security/tomoyo/realpath.c
··· 13 13 #include <linux/mount.h> 14 14 #include <linux/mnt_namespace.h> 15 15 #include <linux/fs_struct.h> 16 + #include <linux/hash.h> 17 + 16 18 #include "common.h" 17 19 #include "realpath.h" 18 20 ··· 265 263 * table. Frequency of appending strings is very low. So we don't need 266 264 * large (e.g. 64k) hash size. 256 will be sufficient. 267 265 */ 268 - #define TOMOYO_MAX_HASH 256 266 + #define TOMOYO_HASH_BITS 8 267 + #define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) 269 268 270 269 /* 271 270 * tomoyo_name_entry is a structure which is used for linking ··· 318 315 struct tomoyo_free_memory_block_list *fmb; 319 316 int len; 320 317 char *cp; 318 + struct list_head *head; 321 319 322 320 if (!name) 323 321 return NULL; ··· 329 325 return NULL; 330 326 } 331 327 hash = full_name_hash((const unsigned char *) name, len - 1); 328 + head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 329 + 332 330 mutex_lock(&lock); 333 - list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 334 - list) { 331 + list_for_each_entry(ptr, head, list) { 335 332 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 336 333 goto out; 337 334 } ··· 370 365 tomoyo_fill_path_info(&ptr->entry); 371 366 fmb->ptr += len; 372 367 fmb->len -= len; 373 - list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]); 368 + list_add_tail(&ptr->list, head); 374 369 if (fmb->len == 0) { 375 370 list_del(&fmb->list); 376 371 kfree(fmb);