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