X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=85a174766de9a3872a550b011d8e1356bbb41f0a;hp=8b04560907b911f8bcc7a484f71964e36d055708;hb=55c39e2764f4b2ab2f66ab495126b821c568c032;hpb=bc3456fa06cc7777c4764da8c7b1c0fd0a3c3772 diff --git a/filesetup.c b/filesetup.c index 8b045609..85a17476 100644 --- a/filesetup.c +++ b/filesetup.c @@ -119,6 +119,54 @@ err: return 1; } +static int pre_read_file(struct thread_data *td, struct fio_file *f) +{ + int r, did_open = 0, old_runstate; + unsigned long long left; + unsigned int bs; + char *b; + + if (!(f->flags & FIO_FILE_OPEN)) { + if (td->io_ops->open_file(td, f)) { + log_err("fio: cannot pre-read, failed to open file\n"); + return 1; + } + did_open = 1; + } + + old_runstate = td->runstate; + td_set_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); + left = f->io_size; + + while (left && !td->terminate) { + if (bs > left) + bs = left; + + r = read(f->fd, b, bs); + + if (r == (int) bs) { + left -= bs; + continue; + } else { + td_verror(td, EIO, "pre_read"); + break; + } + } + + td_set_runstate(td, old_runstate); + + if (did_open) + td->io_ops->close_file(td, f); + free(b); + return 0; +} + static unsigned long long get_rand_file_size(struct thread_data *td) { unsigned long long ret, sized; @@ -136,7 +184,7 @@ static int file_size(struct thread_data *td, struct fio_file *f) { struct stat st; - if (fstat(f->fd, &st) == -1) { + if (stat(f->file_name, &st) == -1) { td_verror(td, errno, "fstat"); return 1; } @@ -150,14 +198,28 @@ static int bdev_size(struct thread_data *td, struct fio_file *f) unsigned long long bytes; int r; + if (td->io_ops->open_file(td, f)) { + log_err("fio: failed opening blockdev %s for size check\n", + f->file_name); + return 1; + } + r = blockdev_size(f->fd, &bytes); if (r) { td_verror(td, r, "blockdev_size"); - return 1; + goto err; + } + + if (!bytes) { + log_err("%s: zero sized block device?\n", f->file_name); + goto err; } f->real_file_size = bytes; return 0; +err: + td->io_ops->close_file(td, f); + return 1; } static int get_file_size(struct thread_data *td, struct fio_file *f) @@ -309,6 +371,8 @@ int generic_open_file(struct thread_data *td, struct fio_file *f) flags |= O_SYNC; if (f->filetype != FIO_TYPE_FILE) flags |= FIO_O_NOATIME; + if (td->o.create_on_open) + flags |= O_CREAT; open_again: if (td_write(td)) { @@ -348,9 +412,6 @@ open_again: td_verror(td, __e, buf); } - if (get_file_size(td, f)) - goto err; - if (!from_hash && f->fd != -1) { if (add_file_hash(f)) { int ret; @@ -364,43 +425,11 @@ open_again: } return 0; -err: - close(f->fd); - return 1; } -int open_files(struct thread_data *td) +int generic_get_file_size(struct thread_data *td, struct fio_file *f) { - struct fio_file *f; - unsigned int i; - int err = 0; - - dprint(FD_FILE, "open files\n"); - - for_each_file(td, f, i) { - err = td_io_open_file(td, f); - if (err) { - if (td->error == EMFILE) { - log_err("fio: limited open files to: %d\n", - td->nr_open_files); - td->o.open_files = td->nr_open_files; - err = 0; - clear_error(td); - } - break; - } - - if (td->o.open_files == td->nr_open_files) - break; - } - - if (!err) - return 0; - - for_each_file(td, f, i) - td_io_close_file(td, f); - - return err; + return get_file_size(td, f); } /* @@ -416,15 +445,12 @@ static int get_file_sizes(struct thread_data *td) dprint(FD_FILE, "get file size for %p/%d/%p\n", f, i, f->file_name); - if (td->io_ops->open_file(td, f)) { + if (td_io_get_file_size(td, f)) { if (td->error != ENOENT) { log_err("%s\n", td->verror); err = 1; } clear_error(td); - } else { - if (td->io_ops->close_file) - td->io_ops->close_file(td, f); } if (f->real_file_size == -1ULL && td->o.size) @@ -529,8 +555,11 @@ int setup_files(struct thread_data *td) if (f->filetype == FIO_TYPE_FILE && (f->io_size + f->file_offset) > f->real_file_size && !(td->io_ops->flags & FIO_DISKLESSIO)) { - need_extend++; - extend_size += (f->io_size + f->file_offset); + if (!td->o.create_on_open) { + need_extend++; + extend_size += (f->io_size + f->file_offset); + } else + f->real_file_size = f->io_size + f->file_offset; f->flags |= FIO_FILE_EXTEND; } } @@ -543,8 +572,10 @@ int setup_files(struct thread_data *td) */ if (need_extend) { temp_stall_ts = 1; - log_info("%s: Laying out IO file(s) (%u file(s) / %LuMiB)\n", - td->o.name, need_extend, extend_size >> 20); + if (!terse_output) + log_info("%s: Laying out IO file(s) (%u file(s) /" + " %LuMiB)\n", td->o.name, need_extend, + extend_size >> 20); for_each_file(td, f, i) { unsigned long long old_len, extend_len; @@ -589,6 +620,20 @@ err_offset: return 1; } +int pre_read_files(struct thread_data *td) +{ + struct fio_file *f; + unsigned int i; + + dprint(FD_FILE, "pre_read files\n"); + + for_each_file(td, f, i) { + pre_read_file(td, f); + } + + return 1; +} + int init_random_map(struct thread_data *td) { unsigned long long blocks, num_maps; @@ -647,6 +692,7 @@ void close_and_free_files(struct thread_data *td) } td_io_close_file(td, f); + remove_file_hash(f); sfree(f->file_name); f->file_name = NULL; @@ -694,11 +740,21 @@ int add_file(struct thread_data *td, const char *fname) dprint(FD_FILE, "add file %s\n", fname); f = smalloc(sizeof(*f)); + if (!f) { + log_err("fio: smalloc OOM\n"); + assert(0); + } + f->fd = -1; - dprint(FD_FILE, "resize file array to %d files\n", cur_files + 1); + if (td->files_size <= td->files_index) { + int new_size = td->o.nr_files + 1; - td->files = realloc(td->files, (cur_files + 1) * sizeof(f)); + dprint(FD_FILE, "resize file array to %d files\n", new_size); + + td->files = realloc(td->files, new_size * sizeof(f)); + td->files_size = new_size; + } td->files[cur_files] = f; /* @@ -712,7 +768,11 @@ int add_file(struct thread_data *td, const char *fname) sprintf(file_name + len, "%s", fname); f->file_name = smalloc_strdup(file_name); - + if (!f->file_name) { + log_err("fio: smalloc OOM\n"); + assert(0); + } + get_file_type(f); switch (td->o.file_lock_mode) { @@ -905,9 +965,18 @@ void dup_files(struct thread_data *td, struct thread_data *org) struct fio_file *__f; __f = smalloc(sizeof(*__f)); - + if (!__f) { + log_err("fio: smalloc OOM\n"); + assert(0); + } + if (f->file_name) { __f->file_name = smalloc_strdup(f->file_name); + if (!__f->file_name) { + log_err("fio: smalloc OOM\n"); + assert(0); + } + __f->filetype = f->filetype; }