Properly protect already-allocated file list
[fio.git] / filesetup.c
index 9c03a626986722491c5ef18694e6f66ba7d841e2..f17e20bfb9ac94095e40e698b7ff45b036d189a7 100644 (file)
@@ -50,10 +50,11 @@ static int extend_file(struct thread_data *td, struct fio_file *f)
         * does that for operations involving reads, or for writes
         * where overwrite is set
         */
         * does that for operations involving reads, or for writes
         * where overwrite is set
         */
-       if (td_read(td) || (td_write(td) && td->o.overwrite) ||
+       if (td_read(td) ||
+          (td_write(td) && td->o.overwrite && !td->o.file_append) ||
            (td_write(td) && td->io_ops->flags & FIO_NOEXTEND))
                new_layout = 1;
            (td_write(td) && td->io_ops->flags & FIO_NOEXTEND))
                new_layout = 1;
-       if (td_write(td) && !td->o.overwrite)
+       if (td_write(td) && !td->o.overwrite && !td->o.file_append)
                unlink_file = 1;
 
        if (unlink_file || new_layout) {
                unlink_file = 1;
 
        if (unlink_file || new_layout) {
@@ -1108,45 +1109,72 @@ static void get_file_type(struct fio_file *f)
        }
 }
 
        }
 }
 
-static void set_already_allocated(const char *fname) {
-       struct file_name *fn;
+static int __is_already_allocated(const char *fname)
+{
+       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)
 {
 }
 
 static int is_already_allocated(const char *fname)
 {
-       struct flist_head *entry;
-       char *filename;
+       int ret;
+
+       fio_file_hash_lock();
+       ret = __is_already_allocated(fname);
+       fio_file_hash_unlock();
+       return ret;
+}
 
 
-       if (!flist_empty(&filename_list))
-       {
-               flist_for_each(entry, &filename_list) {
-                       filename = flist_entry(entry, struct file_name, list)->filename;
+static void set_already_allocated(const char *fname)
+{
+       struct file_name *fn;
 
 
-                       if (strcmp(filename, fname) == 0)
-                               return 1;
-               }
+       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() {
+
+static void free_already_allocated(void)
+{
        struct flist_head *entry, *tmp;
        struct file_name *fn;
 
        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)
 }
 
 int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
@@ -1418,6 +1446,7 @@ void dup_files(struct thread_data *td, struct thread_data *org)
                        assert(0);
                }
                __f->fd = -1;
                        assert(0);
                }
                __f->fd = -1;
+               __f->shadow_fd = -1;
                fio_file_reset(td, __f);
 
                if (f->file_name) {
                fio_file_reset(td, __f);
 
                if (f->file_name) {
@@ -1487,6 +1516,7 @@ int fio_files_done(struct thread_data *td)
 }
 
 /* free memory used in initialization phase only */
 }
 
 /* free memory used in initialization phase only */
-void filesetup_mem_free() {
+void filesetup_mem_free(void)
+{
        free_already_allocated();
 }
        free_already_allocated();
 }