X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=ae7f8171305507d9a28417cb5afb74181cc4c655;hp=eb28826698811058a317fa6544b92bd8f388a368;hb=08c44a557efc1cf301c39b5a81f8db4ccd7baa2d;hpb=f70afaca743f2971312d9928f069a9ea7daeccf7 diff --git a/filesetup.c b/filesetup.c index eb288266..ae7f8171 100644 --- a/filesetup.c +++ b/filesetup.c @@ -130,6 +130,9 @@ static int extend_file(struct thread_data *td, struct fio_file *f) } #endif /* CONFIG_POSIX_FALLOCATE */ + /* + * If our jobs don't require regular files initially, we're done. + */ if (!new_layout) goto done; @@ -375,11 +378,33 @@ static int get_file_size(struct thread_data *td, struct fio_file *f) else if (f->filetype == FIO_TYPE_CHAR) ret = char_size(td, f); else - f->real_file_size = -1; + f->real_file_size = -1ULL; + /* + * Leave ->real_file_size with 0 since it could be expectation + * of initial setup for regular files. + */ if (ret) return ret; + /* + * If ->real_file_size is -1, a conditional for the message + * "offset extends end" is always true, but it makes no sense, + * so just return the same value here. + */ + if (f->real_file_size == -1ULL) { + log_info("%s: failed to get file size of %s\n", td->o.name, + f->file_name); + return 1; + } + + if (td->o.start_offset && f->file_offset == 0) + dprint(FD_FILE, "offset of file %s not initialized yet\n", + f->file_name); + /* + * ->file_offset normally hasn't been initialized yet, so this + * is basically always false. + */ if (f->file_offset > f->real_file_size) { log_err("%s: offset extends end (%llu > %llu)\n", td->o.name, (unsigned long long) f->file_offset, @@ -498,9 +523,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 { @@ -652,6 +674,10 @@ open_again: return 0; } +/* + * This function i.e. get_file_size() is the default .get_file_size + * implementation of majority of I/O engines. + */ int generic_get_file_size(struct thread_data *td, struct fio_file *f) { return get_file_size(td, f); @@ -667,7 +693,7 @@ static int get_file_sizes(struct thread_data *td) int err = 0; for_each_file(td, f, i) { - dprint(FD_FILE, "get file size for %p/%d/%p\n", f, i, + dprint(FD_FILE, "get file size for %p/%d/%s\n", f, i, f->file_name); if (td_io_get_file_size(td, f)) { @@ -679,6 +705,13 @@ static int get_file_sizes(struct thread_data *td) clear_error(td); } + /* + * There are corner cases where we end up with -1 for + * ->real_file_size due to unsupported file type, etc. + * We then just set to size option value divided by number + * of files, similar to the way file ->io_size is set. + * stat(2) failure doesn't set ->real_file_size to -1. + */ if (f->real_file_size == -1ULL && td->o.size) f->real_file_size = td->o.size / td->o.nr_files; } @@ -795,7 +828,9 @@ int setup_files(struct thread_data *td) goto done; /* - * if ioengine defines a setup() method, it's responsible for + * Find out physical size of files or devices for this thread, + * before we determine I/O size and range of our targets. + * If ioengine defines a setup() method, it's responsible for * opening the files and setting f->real_file_size to indicate * the valid range for that file. */ @@ -836,7 +871,7 @@ int setup_files(struct thread_data *td) /* * Calculate per-file size and potential extra size for the - * first files, if needed. + * first files, if needed (i.e. if we don't have a fixed size). */ if (!o->file_size_low && o->nr_files) { uint64_t all_fs; @@ -858,9 +893,17 @@ int setup_files(struct thread_data *td) for_each_file(td, f, i) { f->file_offset = get_start_offset(td, f); + /* + * Update ->io_size depending on options specified. + * ->file_size_low being 0 means filesize option isn't set. + * Non zero ->file_size_low equals ->file_size_high means + * filesize option is set in a fixed size format. + * Non zero ->file_size_low not equals ->file_size_high means + * filesize option is set in a range format. + */ if (!o->file_size_low) { /* - * no file size range given, file size is equal to + * no file size or range given, file size is equal to * total size divided by number of files. If that is * zero, set it to the real file size. If the size * doesn't divide nicely with the min blocksize, @@ -943,7 +986,9 @@ int setup_files(struct thread_data *td) } /* - * See if we need to extend some files + * See if we need to extend some files, typically needed when our + * target regular files don't exist yet, but our jobs require them + * initially due to read I/Os. */ if (need_extend) { temp_stall_ts = 1; @@ -996,8 +1041,8 @@ int setup_files(struct thread_data *td) * stored entries. */ if (!o->read_iolog_file) { - if (o->io_limit) - td->total_io_size = o->io_limit * o->loops; + if (o->io_size) + td->total_io_size = o->io_size * o->loops; else td->total_io_size = o->size * o->loops; }