Properly protect already-allocated file list
authorJens Axboe <axboe@fb.com>
Tue, 1 Apr 2014 18:28:47 +0000 (12:28 -0600)
committerJens Axboe <axboe@fb.com>
Tue, 1 Apr 2014 18:28:47 +0000 (12:28 -0600)
We need proper locking around it for thread based setups.

Signed-off-by: Jens Axboe <axboe@fb.com>
filehash.c
filehash.h
filesetup.c

index 392464e..2d9659c 100644 (file)
@@ -18,6 +18,16 @@ static unsigned short hash(const char *name)
        return jhash(name, strlen(name), 0) & HASH_MASK;
 }
 
+void fio_file_hash_lock(void)
+{
+       fio_mutex_down(hash_lock);
+}
+
+void fio_file_hash_unlock(void)
+{
+       fio_mutex_up(hash_lock);
+}
+
 void remove_file_hash(struct fio_file *f)
 {
        fio_mutex_down(hash_lock);
index 993943a..f316b20 100644 (file)
@@ -8,5 +8,7 @@ extern void file_hash_exit(void);
 extern struct fio_file *lookup_file_hash(const char *);
 extern struct fio_file *add_file_hash(struct fio_file *);
 extern void remove_file_hash(struct fio_file *);
+extern void fio_file_hash_lock(void);
+extern void fio_file_hash_unlock(void);
 
 #endif
index fd55cc4..f17e20b 100644 (file)
@@ -1109,47 +1109,72 @@ static void get_file_type(struct fio_file *f)
        }
 }
 
-static void set_already_allocated(const char *fname)
+static int __is_already_allocated(const char *fname)
 {
-       struct file_name *fn;
+       struct flist_head *entry;
+       char *filename;
 
-       fn = malloc(sizeof(struct file_name));
-       fn->filename = strdup(fname);
-       flist_add_tail(&fn->list, &filename_list);
+       if (flist_empty(&filename_list))
+               return 0;
+
+       flist_for_each(entry, &filename_list) {
+               filename = flist_entry(entry, struct file_name, list)->filename;
+
+               if (strcmp(filename, fname) == 0)
+                       return 1;
+       }
+
+       return 0;
 }
 
 static int is_already_allocated(const char *fname)
 {
-       struct flist_head *entry;
-       char *filename;
+       int ret;
 
-       if (!flist_empty(&filename_list))
-       {
-               flist_for_each(entry, &filename_list) {
-                       filename = flist_entry(entry, struct file_name, list)->filename;
+       fio_file_hash_lock();
+       ret = __is_already_allocated(fname);
+       fio_file_hash_unlock();
+       return ret;
+}
 
-                       if (strcmp(filename, fname) == 0)
-                               return 1;
-               }
+static void set_already_allocated(const char *fname)
+{
+       struct file_name *fn;
+
+       fn = malloc(sizeof(struct file_name));
+       fn->filename = strdup(fname);
+
+       fio_file_hash_lock();
+       if (!__is_already_allocated(fname)) {
+               flist_add_tail(&fn->list, &filename_list);
+               fn = NULL;
        }
+       fio_file_hash_unlock();
 
-       return 0;
+       if (fn) {
+               free(fn->filename);
+               free(fn);
+       }
 }
 
+
 static void free_already_allocated(void)
 {
        struct flist_head *entry, *tmp;
        struct file_name *fn;
 
-       if (!flist_empty(&filename_list))
-       {
-               flist_for_each_safe(entry, tmp, &filename_list) {
-                       fn = flist_entry(entry, struct file_name, list);
-                       free(fn->filename);
-                       flist_del(&fn->list);
-                       free(fn);
-               }
+       if (flist_empty(&filename_list))
+               return;
+
+       fio_file_hash_lock();
+       flist_for_each_safe(entry, tmp, &filename_list) {
+               fn = flist_entry(entry, struct file_name, list);
+               free(fn->filename);
+               flist_del(&fn->list);
+               free(fn);
        }
+
+       fio_file_hash_unlock();
 }
 
 int add_file(struct thread_data *td, const char *fname, int numjob, int inc)