X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=e9976eb17a879ee3c98f51f45dc3b0746f23f3f5;hp=75136ff32fcc7e4409746a981d09f12b79313aef;hb=6acbee37b570fc1323f9cede201589babfafa274;hpb=942a851a366a04c36233c9a64500ede32bac8031 diff --git a/filesetup.c b/filesetup.c index 75136ff3..e9976eb1 100644 --- a/filesetup.c +++ b/filesetup.c @@ -52,14 +52,18 @@ static int extend_file(struct thread_data *td, struct fio_file *f) */ if (td_read(td) || (td_write(td) && td->o.overwrite && !td->o.file_append) || - (td_write(td) && td->io_ops->flags & FIO_NOEXTEND)) + (td_write(td) && td_ioengine_flagged(td, FIO_NOEXTEND))) new_layout = 1; if (td_write(td) && !td->o.overwrite && !td->o.file_append) unlink_file = 1; if (unlink_file || new_layout) { + int ret; + dprint(FD_FILE, "layout unlink %s\n", f->file_name); - if ((td_io_unlink_file(td, f) < 0) && (errno != ENOENT)) { + + ret = td_io_unlink_file(td, f); + if (ret != 0 && ret != ENOENT) { td_verror(td, errno, "unlink"); return 1; } @@ -213,7 +217,7 @@ static int pre_read_file(struct thread_data *td, struct fio_file *f) unsigned int bs; char *b; - if (td->io_ops->flags & FIO_PIPEIO) + if (td_ioengine_flagged(td, FIO_PIPEIO)) return 0; if (!fio_file_open(f)) { @@ -264,7 +268,7 @@ error: return ret; } -static unsigned long long get_rand_file_size(struct thread_data *td) +unsigned long long get_rand_file_size(struct thread_data *td) { unsigned long long ret, sized; uint64_t frand_max; @@ -329,7 +333,7 @@ static int char_size(struct thread_data *td, struct fio_file *f) int r; if (td->io_ops->open_file(td, f)) { - log_err("fio: failed opening blockdev %s for size check\n", + log_err("fio: failed opening chardev %s for size check\n", f->file_name); return 1; } @@ -366,15 +370,17 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) if (f->filetype == FIO_TYPE_FILE) ret = file_size(td, f); - else if (f->filetype == FIO_TYPE_BD) + else if (f->filetype == FIO_TYPE_BLOCK) ret = bdev_size(td, f); else if (f->filetype == FIO_TYPE_CHAR) ret = char_size(td, f); else - f->real_file_size = -1; + f->real_file_size = -1ULL; - if (ret) + if (ret) { + f->real_file_size = -1ULL; return ret; + } if (f->file_offset > f->real_file_size) { log_err("%s: offset extends end (%llu > %llu)\n", td->o.name, @@ -414,9 +420,9 @@ static int __file_invalidate_cache(struct thread_data *td, struct fio_file *f, errval = ret; } else if (f->filetype == FIO_TYPE_FILE) { ret = posix_fadvise(f->fd, off, len, POSIX_FADV_DONTNEED); - if (ret < 0) + if (ret) errval = ret; - } else if (f->filetype == FIO_TYPE_BD) { + } else if (f->filetype == FIO_TYPE_BLOCK) { int retry_count = 0; ret = blockdev_invalidate_cache(f); @@ -494,9 +500,6 @@ int file_lookup_open(struct fio_file *f, int flags) __f = lookup_file_hash(f->file_name); if (__f) { dprint(FD_FILE, "found file in hash %s\n", f->file_name); - /* - * racy, need the __f->lock locked - */ f->lock = __f->lock; from_hash = 1; } else { @@ -705,7 +708,7 @@ static unsigned long long get_fs_free_counts(struct thread_data *td) struct stat sb; char buf[256]; - if (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_CHAR) { + if (f->filetype == FIO_TYPE_BLOCK || f->filetype == FIO_TYPE_CHAR) { if (f->real_file_size != -1ULL) ret += f->real_file_size; continue; @@ -809,6 +812,7 @@ int setup_files(struct thread_data *td) */ total_size = 0; for_each_file(td, f, i) { + f->fileno = i; if (f->real_file_size == -1ULL) total_size = -1ULL; else @@ -822,7 +826,7 @@ int setup_files(struct thread_data *td) * device/file sizes are zero and no size given, punt */ if ((!total_size || total_size == -1ULL) && !o->size && - !(td->io_ops->flags & FIO_NOIO) && !o->fill_device && + !td_ioengine_flagged(td, FIO_NOIO) && !o->fill_device && !(o->nr_files && (o->file_size_low || o->file_size_high))) { log_err("%s: you need to specify size=\n", o->name); td_verror(td, EINVAL, "total_file_size"); @@ -889,14 +893,16 @@ int setup_files(struct thread_data *td) if (f->io_size == -1ULL) total_size = -1ULL; else { - if (o->size_percent) - f->io_size = (f->io_size * o->size_percent) / 100; + if (o->size_percent) { + f->io_size = (f->io_size * o->size_percent) / 100; + f->io_size -= (f->io_size % td_min_bs(td)); + } total_size += f->io_size; } if (f->filetype == FIO_TYPE_FILE && (f->io_size + f->file_offset) > f->real_file_size && - !(td->io_ops->flags & FIO_DISKLESSIO)) { + !td_ioengine_flagged(td, FIO_DISKLESSIO)) { if (!o->create_on_open) { need_extend++; extend_size += (f->io_size + f->file_offset); @@ -941,9 +947,8 @@ int setup_files(struct thread_data *td) if (need_extend) { temp_stall_ts = 1; if (output_format & FIO_OUTPUT_NORMAL) - log_info("%s: Laying out IO file(s) (%u file(s) /" - " %lluMB)\n", o->name, need_extend, - extend_size >> 20); + log_info("%s: Laying out IO file(s) (%u file(s) / %lluMiB)\n", + o->name, need_extend, extend_size >> 20); for_each_file(td, f, i) { unsigned long long old_len = -1ULL, extend_len = -1ULL; @@ -1091,7 +1096,7 @@ static int check_rand_gen_limits(struct thread_data *td, struct fio_file *f, if (!fio_option_is_set(&td->o, random_generator)) { log_info("fio: Switching to tausworthe64. Use the " "random_generator= option to get rid of this " - " warning.\n"); + "warning.\n"); td->o.random_generator = FIO_RAND_GEN_TAUSWORTHE64; return 0; } @@ -1218,14 +1223,16 @@ static void get_file_type(struct fio_file *f) else f->filetype = FIO_TYPE_FILE; +#ifdef WIN32 /* \\.\ is the device namespace in Windows, where every file is * a block device */ if (strncmp(f->file_name, "\\\\.\\", 4) == 0) - f->filetype = FIO_TYPE_BD; + f->filetype = FIO_TYPE_BLOCK; +#endif if (!stat(f->file_name, &sb)) { if (S_ISBLK(sb.st_mode)) - f->filetype = FIO_TYPE_BD; + f->filetype = FIO_TYPE_BLOCK; else if (S_ISCHR(sb.st_mode)) f->filetype = FIO_TYPE_CHAR; else if (S_ISFIFO(sb.st_mode)) @@ -1233,31 +1240,35 @@ static void get_file_type(struct fio_file *f) } } -static int __is_already_allocated(const char *fname) +static bool __is_already_allocated(const char *fname, bool set) { struct flist_head *entry; - char *filename; + bool ret; - if (flist_empty(&filename_list)) - return 0; + ret = file_bloom_exists(fname, set); + if (!ret) + return ret; flist_for_each(entry, &filename_list) { - filename = flist_entry(entry, struct file_name, list)->filename; + struct file_name *fn; - if (strcmp(filename, fname) == 0) - return 1; + fn = flist_entry(entry, struct file_name, list); + + if (!strcmp(fn->filename, fname)) + return true; } - return 0; + return false; } -static int is_already_allocated(const char *fname) +static bool is_already_allocated(const char *fname) { - int ret; + bool ret; fio_file_hash_lock(); - ret = __is_already_allocated(fname); + ret = __is_already_allocated(fname, false); fio_file_hash_unlock(); + return ret; } @@ -1269,7 +1280,7 @@ static void set_already_allocated(const char *fname) fn->filename = strdup(fname); fio_file_hash_lock(); - if (!__is_already_allocated(fname)) { + if (!__is_already_allocated(fname, true)) { flist_add_tail(&fn->list, &filename_list); fn = NULL; } @@ -1281,7 +1292,6 @@ static void set_already_allocated(const char *fname) } } - static void free_already_allocated(void) { struct flist_head *entry, *tmp; @@ -1307,7 +1317,6 @@ static struct fio_file *alloc_new_file(struct thread_data *td) f = smalloc(sizeof(*f)); if (!f) { - log_err("fio: smalloc OOM\n"); assert(0); return NULL; } @@ -1318,6 +1327,26 @@ static struct fio_file *alloc_new_file(struct thread_data *td) return f; } +bool exists_and_not_regfile(const char *filename) +{ + struct stat sb; + + if (lstat(filename, &sb) == -1) + return false; + +#ifndef WIN32 /* NOT Windows */ + if (S_ISREG(sb.st_mode)) + return false; +#else + /* \\.\ is the device namespace in Windows, where every file + * is a device node */ + if (S_ISREG(sb.st_mode) && strncmp(filename, "\\\\.\\", 4) != 0) + return false; +#endif + + return true; +} + int add_file(struct thread_data *td, const char *fname, int numjob, int inc) { int cur_files = td->files_index; @@ -1328,12 +1357,14 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc) dprint(FD_FILE, "add file %s\n", fname); if (td->o.directory) - len = set_name_idx(file_name, PATH_MAX, td->o.directory, numjob); + len = set_name_idx(file_name, PATH_MAX, td->o.directory, numjob, + td->o.unique_filename); sprintf(file_name + len, "%s", fname); /* clean cloned siblings using existing files */ - if (numjob && is_already_allocated(file_name)) + if (numjob && is_already_allocated(file_name) && + !exists_and_not_regfile(fname)) return 0; f = alloc_new_file(td); @@ -1364,14 +1395,12 @@ int add_file(struct thread_data *td, const char *fname, int numjob, int inc) /* * init function, io engine may not be loaded yet */ - if (td->io_ops && (td->io_ops->flags & FIO_DISKLESSIO)) + if (td->io_ops && td_ioengine_flagged(td, FIO_DISKLESSIO)) f->real_file_size = -1ULL; f->file_name = smalloc_strdup(file_name); - if (!f->file_name) { - log_err("fio: smalloc OOM\n"); + if (!f->file_name) assert(0); - } get_file_type(f); @@ -1574,10 +1603,8 @@ void dup_files(struct thread_data *td, struct thread_data *org) if (f->file_name) { __f->file_name = smalloc_strdup(f->file_name); - if (!__f->file_name) { - log_err("fio: smalloc OOM\n"); + if (!__f->file_name) assert(0); - } __f->filetype = f->filetype; } @@ -1633,16 +1660,16 @@ void fio_file_reset(struct thread_data *td, struct fio_file *f) lfsr_reset(&f->lfsr, td->rand_seeds[FIO_RAND_BLOCK_OFF]); } -int fio_files_done(struct thread_data *td) +bool fio_files_done(struct thread_data *td) { struct fio_file *f; unsigned int i; for_each_file(td, f, i) if (!fio_file_done(f)) - return 0; + return false; - return 1; + return true; } /* free memory used in initialization phase only */