}
#endif /* CONFIG_POSIX_FALLOCATE */
+ /*
+ * If our jobs don't require regular files initially, we're done.
+ */
if (!new_layout)
goto done;
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
+ else {
f->real_file_size = -1;
+ log_info("%s: failed to get file size of %s\n", td->o.name,
+ f->file_name);
+ return 1; /* avoid offset extends end error message */
+ }
+ /*
+ * Leave ->real_file_size with 0 since it could be expectation
+ * of initial setup for regular files.
+ */
if (ret)
return ret;
+ /*
+ * ->file_offset normally hasn't been initialized yet, so this
+ * is basically always false unless ->real_file_size is -1, but
+ * if ->real_file_size is -1 this message doesn't make sense.
+ * As a result, this message is basically useless.
+ */
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,
ret = posix_fadvise(f->fd, off, len, POSIX_FADV_DONTNEED);
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);
__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 {
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);
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;
}
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;
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.
*/
/*
* 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;
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,
}
/*
- * 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;
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;
* 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;
}
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;
}
/* \\.\ 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))
}
}
-static bool __is_already_allocated(const char *fname)
+static bool __is_already_allocated(const char *fname, bool set)
{
struct flist_head *entry;
+ bool ret;
- if (flist_empty(&filename_list))
- return false;
+ ret = file_bloom_exists(fname, set);
+ if (!ret)
+ return ret;
flist_for_each(entry, &filename_list) {
struct file_name *fn;
bool ret;
fio_file_hash_lock();
- ret = __is_already_allocated(fname);
+ ret = __is_already_allocated(fname, false);
fio_file_hash_unlock();
return ret;
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;
}
}
}
-
static void free_already_allocated(void)
{
struct flist_head *entry, *tmp;
f = smalloc(sizeof(*f));
if (!f) {
- log_err("fio: smalloc OOM\n");
assert(0);
return NULL;
}
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);
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;
}
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 */