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