1243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe/*
2243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe * Really simple exclusive file locking based on filename.
3243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe * No hash indexing, just a list, so only works well for < 100 files or
4243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe * so. But that's more than what fio needs, so should be fine.
5243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe */
6243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include <inttypes.h>
7243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include <string.h>
8c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe#include <unistd.h>
9243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include <assert.h>
10243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
11243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "flist.h"
12243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "filelock.h"
13243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "smalloc.h"
14243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "mutex.h"
15243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "hash.h"
16243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe#include "log.h"
17243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
18243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboestruct fio_filelock {
19243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	uint32_t hash;
20243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct fio_mutex lock;
21243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct flist_head list;
22243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	unsigned int references;
23243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe};
24c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
25c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe#define MAX_FILELOCKS	128
26243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
27c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic struct filelock_data {
28c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct flist_head list;
29c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct fio_mutex lock;
30c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
31c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct flist_head free_list;
32c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct fio_filelock ffs[MAX_FILELOCKS];
33c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe} *fld;
34c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
35c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic void put_filelock(struct fio_filelock *ff)
36c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe{
37c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	flist_add(&ff->list, &fld->free_list);
38c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe}
39c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
40c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic struct fio_filelock *__get_filelock(void)
41c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe{
42c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct fio_filelock *ff;
43c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
44c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (flist_empty(&fld->free_list))
45c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		return NULL;
46c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
47c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	ff = flist_first_entry(&fld->free_list, struct fio_filelock, list);
48c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	flist_del_init(&ff->list);
49c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	return ff;
50c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe}
51c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
52c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic struct fio_filelock *get_filelock(int trylock, int *retry)
53c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe{
54c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	struct fio_filelock *ff;
55c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
56c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	do {
57c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		ff = __get_filelock();
58c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		if (ff || trylock)
59c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			break;
60c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
61c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		fio_mutex_up(&fld->lock);
62c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		usleep(1000);
63c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		fio_mutex_down(&fld->lock);
64c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		*retry = 1;
65c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	} while (1);
66c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
67c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	return ff;
68c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe}
69243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
70243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboeint fio_filelock_init(void)
71243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
72c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	int i;
73243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
74c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fld = smalloc(sizeof(*fld));
75c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (!fld)
76243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		return 1;
77c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
78c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	INIT_FLIST_HEAD(&fld->list);
79c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	INIT_FLIST_HEAD(&fld->free_list);
80c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
81c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (__fio_mutex_init(&fld->lock, FIO_MUTEX_UNLOCKED))
82c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		goto err;
83c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
84c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	for (i = 0; i < MAX_FILELOCKS; i++) {
85c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		struct fio_filelock *ff = &fld->ffs[i];
86c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
87c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		if (__fio_mutex_init(&ff->lock, FIO_MUTEX_UNLOCKED))
88c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			goto err;
89c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		flist_add_tail(&ff->list, &fld->free_list);
90243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	}
91243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
92243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	return 0;
93c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboeerr:
94c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_filelock_exit();
95c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	return 1;
96243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
97243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
98243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboevoid fio_filelock_exit(void)
99243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
100c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (!fld)
101243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		return;
102243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
103c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	assert(flist_empty(&fld->list));
1043b9719fdce75714101d47b409d81681c6d671d65Jens Axboe	__fio_mutex_remove(&fld->lock);
105c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
106c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	while (!flist_empty(&fld->free_list)) {
107c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		struct fio_filelock *ff;
108c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
109c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		ff = flist_first_entry(&fld->free_list, struct fio_filelock, list);
110c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
111c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		flist_del_init(&ff->list);
1123b9719fdce75714101d47b409d81681c6d671d65Jens Axboe		__fio_mutex_remove(&ff->lock);
113c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	}
114c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
115c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	sfree(fld);
116c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fld = NULL;
117243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
118243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
119243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboestatic struct fio_filelock *fio_hash_find(uint32_t hash)
120243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
121243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct flist_head *entry;
122243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct fio_filelock *ff;
123243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
124c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	flist_for_each(entry, &fld->list) {
125243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		ff = flist_entry(entry, struct fio_filelock, list);
126243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		if (ff->hash == hash)
127243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe			return ff;
128243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	}
129243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
130243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	return NULL;
131243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
132243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
133c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic struct fio_filelock *fio_hash_get(uint32_t hash, int trylock)
134243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
135243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct fio_filelock *ff;
136243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
137243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	ff = fio_hash_find(hash);
138243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	if (!ff) {
139c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		int retry = 0;
140c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
141c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		ff = get_filelock(trylock, &retry);
142c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		if (!ff)
143c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			return NULL;
144c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
145c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		/*
146c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		 * If we dropped the main lock, re-lookup the hash in case
147c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		 * someone else added it meanwhile. If it's now there,
148c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		 * just return that.
149c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		 */
150c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		if (retry) {
151c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			struct fio_filelock *__ff;
152c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
153c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			__ff = fio_hash_find(hash);
154c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			if (__ff) {
155c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe				put_filelock(ff);
156c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe				return __ff;
157c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			}
158c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		}
159c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
160243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		ff->hash = hash;
161243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		ff->references = 0;
162c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		flist_add(&ff->list, &fld->list);
163243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	}
164243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
165243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	return ff;
166243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
167243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
168c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboestatic int __fio_lock_file(const char *fname, int trylock)
169243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
170243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct fio_filelock *ff;
171243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	uint32_t hash;
172243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
173243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	hash = jhash(fname, strlen(fname), 0);
174243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
175c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_down(&fld->lock);
176c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	ff = fio_hash_get(hash, trylock);
177c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (ff)
178c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		ff->references++;
179c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_up(&fld->lock);
180c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
181c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (!ff) {
182c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		assert(!trylock);
183c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		return 1;
184c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	}
185c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe
186c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	if (!trylock) {
187c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		fio_mutex_down(&ff->lock);
188c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe		return 0;
189c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	}
190243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
191243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	if (!fio_mutex_down_trylock(&ff->lock))
192243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		return 0;
193243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
194c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_down(&fld->lock);
195243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
196243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	/*
197243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	 * If we raced and the only reference to the lock is us, we can
198243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	 * grab it
199243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	 */
200243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	if (ff->references != 1) {
201243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		ff->references--;
202243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		ff = NULL;
203243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	}
204243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
205c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_up(&fld->lock);
206243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
207243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	if (ff) {
208243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		fio_mutex_down(&ff->lock);
209243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		return 0;
210243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	}
211243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
212243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	return 1;
213243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
214243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
215c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboeint fio_trylock_file(const char *fname)
216243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
217c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	return __fio_lock_file(fname, 1);
218c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe}
219243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
220c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboevoid fio_lock_file(const char *fname)
221c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe{
222c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	__fio_lock_file(fname, 0);
223243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
224243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
225243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboevoid fio_unlock_file(const char *fname)
226243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe{
227243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	struct fio_filelock *ff;
228243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	uint32_t hash;
229243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
230243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	hash = jhash(fname, strlen(fname), 0);
231243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
232c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_down(&fld->lock);
233243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
234243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	ff = fio_hash_find(hash);
235243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	if (ff) {
236c180342e1293259ca8d23ed0298aa6c32815fee5Jens Axboe		int refs = --ff->references;
237243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		fio_mutex_up(&ff->lock);
238c180342e1293259ca8d23ed0298aa6c32815fee5Jens Axboe		if (!refs) {
239c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			flist_del_init(&ff->list);
240c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe			put_filelock(ff);
241243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		}
242243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe	} else
243243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe		log_err("fio: file not found for unlocking\n");
244243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe
245c2e99542fdc504ef4c95d2c20655ff4d8d5c2e3fJens Axboe	fio_mutex_up(&fld->lock);
246243bfe190245a10e9d0981bf2a7c722edc4c43d4Jens Axboe}
247