X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=filesetup.c;h=38ad9edc6e206fd919309087bf4590dd76231ea1;hp=8a0968d66debfe329e816ee0f5f92abc749f018e;hb=dae887f3e2ac761886980cd3197522f3be46082d;hpb=5761ab72a4e5007e08b996888d39e1b9c476c5b5 diff --git a/filesetup.c b/filesetup.c index 8a0968d6..38ad9edc 100644 --- a/filesetup.c +++ b/filesetup.c @@ -38,12 +38,77 @@ static inline void clear_error(struct thread_data *td) td->verror[0] = '\0'; } +static inline int native_fallocate(struct thread_data *td, struct fio_file *f) +{ + bool success; + + success = fio_fallocate(f, 0, f->real_file_size); + dprint(FD_FILE, "native fallocate of file %s size %llu was " + "%ssuccessful\n", f->file_name, + (unsigned long long) f->real_file_size, + !success ? "un": ""); + + if (success) + return 0; + + if (errno == ENOSYS) + dprint(FD_FILE, "native fallocate is not implemented\n"); + + return -1; +} + +static void fallocate_file(struct thread_data *td, struct fio_file *f) +{ + int r; + + if (td->o.fill_device) + return; + + switch (td->o.fallocate_mode) { + case FIO_FALLOCATE_NATIVE: + r = native_fallocate(td, f); + if (r != 0) + log_err("fio: native_fallocate call failed: %s\n", + strerror(errno)); + break; + case FIO_FALLOCATE_NONE: + break; +#ifdef CONFIG_POSIX_FALLOCATE + case FIO_FALLOCATE_POSIX: + dprint(FD_FILE, "posix_fallocate file %s size %llu\n", + f->file_name, + (unsigned long long) f->real_file_size); + + r = posix_fallocate(f->fd, 0, f->real_file_size); + if (r > 0) + log_err("fio: posix_fallocate fails: %s\n", strerror(r)); + break; +#endif /* CONFIG_POSIX_FALLOCATE */ +#ifdef CONFIG_LINUX_FALLOCATE + case FIO_FALLOCATE_KEEP_SIZE: + dprint(FD_FILE, "fallocate(FALLOC_FL_KEEP_SIZE) " + "file %s size %llu\n", f->file_name, + (unsigned long long) f->real_file_size); + + r = fallocate(f->fd, FALLOC_FL_KEEP_SIZE, 0, f->real_file_size); + if (r != 0) + td_verror(td, errno, "fallocate"); + + break; +#endif /* CONFIG_LINUX_FALLOCATE */ + default: + log_err("fio: unknown fallocate mode: %d\n", td->o.fallocate_mode); + assert(0); + } + +} + /* * Leaves f->fd open on success, caller must close */ static int extend_file(struct thread_data *td, struct fio_file *f) { - int r, new_layout = 0, unlink_file = 0, flags; + int new_layout = 0, unlink_file = 0, flags; unsigned long long left; unsigned int bs; char *b = NULL; @@ -100,43 +165,7 @@ static int extend_file(struct thread_data *td, struct fio_file *f) return 1; } -#ifdef CONFIG_POSIX_FALLOCATE - if (!td->o.fill_device) { - switch (td->o.fallocate_mode) { - case FIO_FALLOCATE_NONE: - break; - case FIO_FALLOCATE_POSIX: - dprint(FD_FILE, "posix_fallocate file %s size %llu\n", - f->file_name, - (unsigned long long) f->real_file_size); - - r = posix_fallocate(f->fd, 0, f->real_file_size); - if (r > 0) { - log_err("fio: posix_fallocate fails: %s\n", - strerror(r)); - } - break; -#ifdef CONFIG_LINUX_FALLOCATE - case FIO_FALLOCATE_KEEP_SIZE: - dprint(FD_FILE, - "fallocate(FALLOC_FL_KEEP_SIZE) " - "file %s size %llu\n", f->file_name, - (unsigned long long) f->real_file_size); - - r = fallocate(f->fd, FALLOC_FL_KEEP_SIZE, 0, - f->real_file_size); - if (r != 0) - td_verror(td, errno, "fallocate"); - - break; -#endif /* CONFIG_LINUX_FALLOCATE */ - default: - log_err("fio: unknown fallocate mode: %d\n", - td->o.fallocate_mode); - assert(0); - } - } -#endif /* CONFIG_POSIX_FALLOCATE */ + fallocate_file(td, f); /* * If our jobs don't require regular files initially, we're done. @@ -171,6 +200,8 @@ static int extend_file(struct thread_data *td, struct fio_file *f) } while (left && !td->terminate) { + ssize_t r; + if (bs > left) bs = left; @@ -833,12 +864,42 @@ static unsigned long long get_fs_free_counts(struct thread_data *td) uint64_t get_start_offset(struct thread_data *td, struct fio_file *f) { struct thread_options *o = &td->o; + unsigned long long align_bs; + unsigned long long offset; if (o->file_append && f->filetype == FIO_TYPE_FILE) return f->real_file_size; - return td->o.start_offset + - td->subjob_number * td->o.offset_increment; + if (o->start_offset_percent > 0) { + /* + * if blockalign is provided, find the min across read, write, + * and trim + */ + if (fio_option_is_set(o, ba)) { + align_bs = (unsigned long long) min(o->ba[DDIR_READ], o->ba[DDIR_WRITE]); + align_bs = min((unsigned long long) o->ba[DDIR_TRIM], align_bs); + } else { + /* else take the minimum block size */ + align_bs = td_min_bs(td); + } + + /* calculate the raw offset */ + offset = (f->real_file_size * o->start_offset_percent / 100) + + (td->subjob_number * o->offset_increment); + + /* + * block align the offset at the next available boundary at + * ceiling(offset / align_bs) * align_bs + */ + offset = (offset / align_bs + (offset % align_bs != 0)) * align_bs; + + } else { + /* start_offset_percent not set */ + offset = o->start_offset + + td->subjob_number * o->offset_increment; + } + + return offset; } /*