* 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;
- 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) {
static int pre_read_file(struct thread_data *td, struct fio_file *f)
{
- int r, did_open = 0, old_runstate;
+ int ret = 0, r, did_open = 0, old_runstate;
unsigned long long left;
unsigned int bs;
char *b;
did_open = 1;
}
- old_runstate = td->runstate;
- td_set_runstate(td, TD_PRE_READING);
+ old_runstate = td_bump_runstate(td, TD_PRE_READING);
bs = td->o.max_bs[DDIR_READ];
b = malloc(bs);
memset(b, 0, bs);
- lseek(f->fd, f->file_offset, SEEK_SET);
+ if (lseek(f->fd, f->file_offset, SEEK_SET) < 0) {
+ td_verror(td, errno, "lseek");
+ log_err("fio: failed to lseek pre-read file\n");
+ ret = 1;
+ goto error;
+ }
+
left = f->io_size;
while (left && !td->terminate) {
}
}
- td_set_runstate(td, old_runstate);
+error:
+ td_restore_runstate(td, old_runstate);
if (did_open)
td->io_ops->close_file(td, f);
+
free(b);
- return 0;
+ return ret;
}
static unsigned long long get_rand_file_size(struct thread_data *td)
return ret;
}
-uint64_t get_start_offset(struct thread_data *td)
+uint64_t get_start_offset(struct thread_data *td, struct fio_file *f)
{
+ struct thread_options *o = &td->o;
+
+ if (o->file_append && f->filetype == FIO_TYPE_FILE)
+ return f->real_file_size;
+
return td->o.start_offset +
(td->thread_number - 1) * td->o.offset_increment;
}
dprint(FD_FILE, "setup files\n");
- old_state = td->runstate;
- td_set_runstate(td, TD_SETTING_UP);
+ old_state = td_bump_runstate(td, TD_SETTING_UP);
if (o->read_iolog_file)
goto done;
extend_size = total_size = 0;
need_extend = 0;
for_each_file(td, f, i) {
- f->file_offset = get_start_offset(td);
+ f->file_offset = get_start_offset(td, f);
if (!o->file_size_low) {
/*
if (o->create_only)
td->done = 1;
- td_set_runstate(td, old_state);
+ td_restore_runstate(td, old_state);
return 0;
err_offset:
log_err("%s: you need to specify valid offset=\n", o->name);
err_out:
- td_set_runstate(td, old_state);
+ td_restore_runstate(td, old_state);
return 1;
}
if (td->o.random_distribution == FIO_RAND_DIST_RANDOM)
return 0;
- state = td->runstate;
- td_set_runstate(td, TD_SETTING_UP);
+ state = td_bump_runstate(td, TD_SETTING_UP);
+
for_each_file(td, f, i)
__init_rand_distribution(td, f);
- td_set_runstate(td, state);
+
+ td_restore_runstate(td, state);
return 1;
}
seed = td->rand_seeds[FIO_RAND_BLOCK_OFF];
- if (!lfsr_init(&f->lfsr, blocks, seed, seed & 0xF))
+ if (!lfsr_init(&f->lfsr, blocks, seed, 0))
continue;
} else if (!td->o.norandommap) {
f->io_axmap = axmap_new(blocks);
dprint(FD_FILE, "close files\n");
for_each_file(td, f, i) {
- if (td->o.unlink && f->filetype == FIO_TYPE_FILE) {
- dprint(FD_FILE, "free unlink %s\n", f->file_name);
- unlink(f->file_name);
- }
-
if (fio_file_open(f))
td_io_close_file(td, f);
remove_file_hash(f);
+ if (td->o.unlink && f->filetype == FIO_TYPE_FILE) {
+ dprint(FD_FILE, "free unlink %s\n", f->file_name);
+ unlink(f->file_name);
+ }
+
sfree(f->file_name);
f->file_name = NULL;
axmap_free(f->io_axmap);
}
}
-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)
{
- 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() {
+
+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();
+}
+
+static struct fio_file *alloc_new_file(struct thread_data *td)
+{
+ struct fio_file *f;
+
+ f = smalloc(sizeof(*f));
+ if (!f) {
+ log_err("fio: smalloc OOM\n");
+ assert(0);
+ return NULL;
+ }
+
+ f->fd = -1;
+ f->shadow_fd = -1;
+ fio_file_reset(td, f);
+ return f;
}
int add_file(struct thread_data *td, const char *fname, int numjob, int inc)
if (numjob && is_already_allocated(file_name))
return 0;
- f = smalloc(sizeof(*f));
- if (!f) {
- log_err("fio: smalloc OOM\n");
- assert(0);
- }
-
- f->fd = -1;
- f->shadow_fd = -1;
- fio_file_reset(td, f);
+ f = alloc_new_file(td);
if (td->files_size <= td->files_index) {
unsigned int new_size = td->o.nr_files + 1;
for_each_file(org, f, i) {
struct fio_file *__f;
- __f = smalloc(sizeof(*__f));
- if (!__f) {
- log_err("fio: smalloc OOM\n");
- assert(0);
- }
- __f->fd = -1;
- fio_file_reset(td, __f);
+ __f = alloc_new_file(td);
if (f->file_name) {
__f->file_name = smalloc_strdup(f->file_name);
}
/* free memory used in initialization phase only */
-void filesetup_mem_free() {
+void filesetup_mem_free(void)
+{
free_already_allocated();
}