Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 1 | #include <stdlib.h> |
2 | #include <assert.h> | ||||
3 | |||||
4 | #include "fio.h" | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 5 | #include "flist.h" |
Jens Axboe | dadf66c | 2011-10-06 12:37:10 +0200 | [diff] [blame] | 6 | #include "hash.h" |
Jens Axboe | 10aa136 | 2014-04-01 21:10:36 -0600 | [diff] [blame] | 7 | #include "filehash.h" |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 8 | |
9 | #define HASH_BUCKETS 512 | ||||
10 | #define HASH_MASK (HASH_BUCKETS - 1) | ||||
11 | |||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 12 | unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct flist_head); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 13 | |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 14 | static struct flist_head *file_hash; |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 15 | static struct fio_mutex *hash_lock; |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 16 | |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 17 | static unsigned short hash(const char *name) |
18 | { | ||||
Jens Axboe | dadf66c | 2011-10-06 12:37:10 +0200 | [diff] [blame] | 19 | return jhash(name, strlen(name), 0) & HASH_MASK; |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 20 | } |
21 | |||||
Jens Axboe | 9042623 | 2014-04-01 12:28:47 -0600 | [diff] [blame] | 22 | void fio_file_hash_lock(void) |
23 | { | ||||
Jens Axboe | 45aeca7 | 2014-04-02 12:25:16 -0600 | [diff] [blame] | 24 | if (hash_lock) |
25 | fio_mutex_down(hash_lock); | ||||
Jens Axboe | 9042623 | 2014-04-01 12:28:47 -0600 | [diff] [blame] | 26 | } |
27 | |||||
28 | void fio_file_hash_unlock(void) | ||||
29 | { | ||||
Jens Axboe | 45aeca7 | 2014-04-02 12:25:16 -0600 | [diff] [blame] | 30 | if (hash_lock) |
31 | fio_mutex_up(hash_lock); | ||||
Jens Axboe | 9042623 | 2014-04-01 12:28:47 -0600 | [diff] [blame] | 32 | } |
33 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 34 | void remove_file_hash(struct fio_file *f) |
35 | { | ||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 36 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 37 | |
Jens Axboe | d6aed79 | 2009-06-03 08:41:15 +0200 | [diff] [blame] | 38 | if (fio_file_hashed(f)) { |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 39 | assert(!flist_empty(&f->hash_list)); |
40 | flist_del_init(&f->hash_list); | ||||
Jens Axboe | d6aed79 | 2009-06-03 08:41:15 +0200 | [diff] [blame] | 41 | fio_file_clear_hashed(f); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 42 | } |
43 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 44 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 45 | } |
46 | |||||
47 | static struct fio_file *__lookup_file_hash(const char *name) | ||||
48 | { | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 49 | struct flist_head *bucket = &file_hash[hash(name)]; |
50 | struct flist_head *n; | ||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 51 | |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 52 | flist_for_each(n, bucket) { |
53 | struct fio_file *f = flist_entry(n, struct fio_file, hash_list); | ||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 54 | |
Jens Axboe | 8954110 | 2008-09-10 09:07:55 +0200 | [diff] [blame] | 55 | if (!f->file_name) |
56 | continue; | ||||
57 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 58 | if (!strcmp(f->file_name, name)) { |
59 | assert(f->fd != -1); | ||||
60 | return f; | ||||
61 | } | ||||
62 | } | ||||
63 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 64 | return NULL; |
65 | } | ||||
66 | |||||
67 | struct fio_file *lookup_file_hash(const char *name) | ||||
68 | { | ||||
69 | struct fio_file *f; | ||||
70 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 71 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 72 | f = __lookup_file_hash(name); |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 73 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 74 | return f; |
75 | } | ||||
76 | |||||
77 | struct fio_file *add_file_hash(struct fio_file *f) | ||||
78 | { | ||||
79 | struct fio_file *alias; | ||||
80 | |||||
Jens Axboe | d6aed79 | 2009-06-03 08:41:15 +0200 | [diff] [blame] | 81 | if (fio_file_hashed(f)) |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 82 | return NULL; |
83 | |||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 84 | INIT_FLIST_HEAD(&f->hash_list); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 85 | |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 86 | fio_mutex_down(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 87 | |
88 | alias = __lookup_file_hash(f->file_name); | ||||
89 | if (!alias) { | ||||
Jens Axboe | d6aed79 | 2009-06-03 08:41:15 +0200 | [diff] [blame] | 90 | fio_file_set_hashed(f); |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 91 | flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 92 | } |
93 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 94 | fio_mutex_up(hash_lock); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 95 | return alias; |
96 | } | ||||
97 | |||||
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 98 | void file_hash_exit(void) |
99 | { | ||||
100 | unsigned int i, has_entries = 0; | ||||
101 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 102 | fio_mutex_down(hash_lock); |
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 103 | for (i = 0; i < HASH_BUCKETS; i++) |
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 104 | has_entries += !flist_empty(&file_hash[i]); |
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 105 | fio_mutex_up(hash_lock); |
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 106 | |
107 | if (has_entries) | ||||
108 | log_err("fio: file hash not empty on exit\n"); | ||||
109 | |||||
Jens Axboe | b950781 | 2008-06-13 08:38:25 +0200 | [diff] [blame] | 110 | file_hash = NULL; |
111 | fio_mutex_remove(hash_lock); | ||||
Jens Axboe | 5e1d306 | 2008-05-23 11:55:53 +0200 | [diff] [blame] | 112 | hash_lock = NULL; |
113 | } | ||||
114 | |||||
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 115 | void file_hash_init(void *ptr) |
116 | { | ||||
117 | unsigned int i; | ||||
118 | |||||
119 | file_hash = ptr; | ||||
120 | for (i = 0; i < HASH_BUCKETS; i++) | ||||
Jens Axboe | 01743ee | 2008-06-02 12:19:19 +0200 | [diff] [blame] | 121 | INIT_FLIST_HEAD(&file_hash[i]); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 122 | |
Jens Axboe | 521da52 | 2012-08-02 11:21:36 +0200 | [diff] [blame] | 123 | hash_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED); |
Jens Axboe | 380065a | 2008-03-01 18:56:24 +0100 | [diff] [blame] | 124 | } |