Commit | Line | Data |
---|---|---|
380065aa JA |
1 | #include <stdlib.h> |
2 | #include <assert.h> | |
3 | ||
4 | #include "fio.h" | |
5 | #include "list.h" | |
6 | #include "crc/crc16.h" | |
7 | ||
8 | #define HASH_BUCKETS 512 | |
9 | #define HASH_MASK (HASH_BUCKETS - 1) | |
10 | ||
11 | unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct list_head); | |
12 | ||
13 | static struct list_head *file_hash; | |
14 | static struct fio_mutex *hash_lock; | |
15 | ||
380065aa JA |
16 | static unsigned short hash(const char *name) |
17 | { | |
18 | return crc16((const unsigned char *) name, strlen(name)) & HASH_MASK; | |
19 | } | |
20 | ||
21 | void remove_file_hash(struct fio_file *f) | |
22 | { | |
23 | fio_mutex_down(hash_lock); | |
24 | ||
25 | if (f->flags & FIO_FILE_HASHED) { | |
26 | assert(!list_empty(&f->hash_list)); | |
27 | list_del_init(&f->hash_list); | |
28 | f->flags &= ~FIO_FILE_HASHED; | |
29 | } | |
30 | ||
31 | fio_mutex_up(hash_lock); | |
32 | } | |
33 | ||
34 | static struct fio_file *__lookup_file_hash(const char *name) | |
35 | { | |
36 | struct list_head *bucket = &file_hash[hash(name)]; | |
37 | struct list_head *n; | |
38 | ||
39 | list_for_each(n, bucket) { | |
40 | struct fio_file *f = list_entry(n, struct fio_file, hash_list); | |
41 | ||
42 | if (!strcmp(f->file_name, name)) { | |
43 | assert(f->fd != -1); | |
44 | return f; | |
45 | } | |
46 | } | |
47 | ||
380065aa JA |
48 | return NULL; |
49 | } | |
50 | ||
51 | struct fio_file *lookup_file_hash(const char *name) | |
52 | { | |
53 | struct fio_file *f; | |
54 | ||
55 | fio_mutex_down(hash_lock); | |
56 | f = __lookup_file_hash(name); | |
57 | fio_mutex_up(hash_lock); | |
58 | return f; | |
59 | } | |
60 | ||
61 | struct fio_file *add_file_hash(struct fio_file *f) | |
62 | { | |
63 | struct fio_file *alias; | |
64 | ||
65 | if (f->flags & FIO_FILE_HASHED) | |
66 | return NULL; | |
67 | ||
68 | INIT_LIST_HEAD(&f->hash_list); | |
69 | ||
70 | fio_mutex_down(hash_lock); | |
71 | ||
72 | alias = __lookup_file_hash(f->file_name); | |
73 | if (!alias) { | |
74 | f->flags |= FIO_FILE_HASHED; | |
75 | list_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); | |
76 | } | |
77 | ||
78 | fio_mutex_up(hash_lock); | |
79 | return alias; | |
80 | } | |
81 | ||
5e1d306e JA |
82 | void file_hash_exit(void) |
83 | { | |
84 | unsigned int i, has_entries = 0; | |
85 | ||
86 | fio_mutex_down(hash_lock); | |
87 | for (i = 0; i < HASH_BUCKETS; i++) | |
88 | has_entries += !list_empty(&file_hash[i]); | |
89 | fio_mutex_up(hash_lock); | |
90 | ||
91 | if (has_entries) | |
92 | log_err("fio: file hash not empty on exit\n"); | |
93 | ||
94 | file_hash = NULL; | |
95 | fio_mutex_remove(hash_lock); | |
96 | hash_lock = NULL; | |
97 | } | |
98 | ||
380065aa JA |
99 | void file_hash_init(void *ptr) |
100 | { | |
101 | unsigned int i; | |
102 | ||
103 | file_hash = ptr; | |
104 | for (i = 0; i < HASH_BUCKETS; i++) | |
105 | INIT_LIST_HEAD(&file_hash[i]); | |
106 | ||
107 | hash_lock = fio_mutex_init(1); | |
108 | } |