From 89978a6b26f81bdbd63228e2e2a86f604ee46c56 Mon Sep 17 00:00:00 2001 From: Brantley West Date: Tue, 16 May 2017 17:10:05 -0400 Subject: [PATCH] allow a percent value for the offset parameter --- HOWTO | 9 +++++---- cconv.c | 2 ++ filesetup.c | 27 +++++++++++++++++++++++++-- fio.1 | 6 +++++- options.c | 16 ++++++++++++++++ server.h | 2 +- thread_options.h | 3 ++- 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/HOWTO b/HOWTO index d9e881ab..e39111fa 100644 --- a/HOWTO +++ b/HOWTO @@ -1072,10 +1072,11 @@ I/O type .. option:: offset=int - Start I/O at the given offset in the file. The data before the given offset - will not be touched. This effectively caps the file size at `real_size - - offset`. Can be combined with :option:`size` to constrain the start and - end range that I/O will be done within. + Start I/O at the provided offset in the file, given as either a fixed size or + a percentage. If a percentage is given, the next ``blockalign``-ed offset + will be used. Data before the given offset will not be touched. This + effectively caps the file size at `real_size - offset`. Can be combined with + :option:`size` to constrain the start and end range of the I/O workload. .. option:: offset_increment=int diff --git a/cconv.c b/cconv.c index 3295824b..bf4c5175 100644 --- a/cconv.c +++ b/cconv.c @@ -104,6 +104,7 @@ void convert_thread_options_to_cpu(struct thread_options *o, o->file_size_low = le64_to_cpu(top->file_size_low); o->file_size_high = le64_to_cpu(top->file_size_high); o->start_offset = le64_to_cpu(top->start_offset); + o->start_offset_percent = le32_to_cpu(top->start_offset_percent); for (i = 0; i < DDIR_RWDIR_CNT; i++) { o->bs[i] = le32_to_cpu(top->bs[i]); @@ -543,6 +544,7 @@ void convert_thread_options_to_net(struct thread_options_pack *top, top->file_size_low = __cpu_to_le64(o->file_size_low); top->file_size_high = __cpu_to_le64(o->file_size_high); top->start_offset = __cpu_to_le64(o->start_offset); + top->start_offset_percent = __cpu_to_le32(o->start_offset_percent); top->trim_backlog = __cpu_to_le64(o->trim_backlog); top->offset_increment = __cpu_to_le64(o->offset_increment); top->number_ios = __cpu_to_le64(o->number_ios); diff --git a/filesetup.c b/filesetup.c index 612e7947..25ce0c0d 100644 --- a/filesetup.c +++ b/filesetup.c @@ -833,12 +833,35 @@ 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; /* align the offset to this block size */ + unsigned long long offset; /* align_bs-aligned 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 + o->start_offset + + td->subjob_number * o->offset_increment; + } + return offset; } /* diff --git a/fio.1 b/fio.1 index 0167c23e..31eb161c 100644 --- a/fio.1 +++ b/fio.1 @@ -904,7 +904,11 @@ If true, use buffered I/O. This is the opposite of the \fBdirect\fR parameter. Default: true. .TP .BI offset \fR=\fPint -Offset in the file to start I/O. Data before the offset will not be touched. +Start I/O at the provided offset in the file, given as either a fixed size or a +percentage. If a percentage is given, the next \fBblockalign\fR-ed offset will +be used. Data before the given offset will not be touched. This effectively +caps the file size at (real_size - offset). Can be combined with \fBsize\fR to +constrain the start and end range of the I/O workload. .TP .BI offset_increment \fR=\fPint If this is provided, then the real offset becomes the diff --git a/options.c b/options.c index b489e902..dcee7e55 100644 --- a/options.c +++ b/options.c @@ -1381,6 +1381,21 @@ static int str_gtod_reduce_cb(void *data, int *il) return 0; } +static int str_offset_cb(void *data, unsigned long long *__val) +{ + struct thread_data *td = cb_data_to_td(data); + unsigned long long v = *__val; + + if (parse_is_percent(v)) { + td->o.start_offset = 0; + td->o.start_offset_percent = -1ULL - v; + dprint(FD_PARSE, "SET start_offset_percent %d\n", td->o.start_offset_percent); + } else + td->o.start_offset = v; + + return 0; +} + static int str_size_cb(void *data, unsigned long long *__val) { struct thread_data *td = cb_data_to_td(data); @@ -1938,6 +1953,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "IO offset", .alias = "fileoffset", .type = FIO_OPT_STR_VAL, + .cb = str_offset_cb, .off1 = offsetof(struct thread_options, start_offset), .help = "Start IO from this offset", .def = "0", diff --git a/server.h b/server.h index 5c720d46..fff68040 100644 --- a/server.h +++ b/server.h @@ -49,7 +49,7 @@ struct fio_net_cmd_reply { }; enum { - FIO_SERVER_VER = 61, + FIO_SERVER_VER = 62, FIO_SERVER_MAX_FRAGMENT_PDU = 1024, FIO_SERVER_MAX_CMD_MB = 2048, diff --git a/thread_options.h b/thread_options.h index d0f3fe93..493e92ec 100644 --- a/thread_options.h +++ b/thread_options.h @@ -200,6 +200,7 @@ struct thread_options { unsigned int numa_mem_prefer_node; char *numa_memnodes; unsigned int gpu_dev_id; + unsigned int start_offset_percent; unsigned int iolog; unsigned int rwmixcycle; @@ -469,7 +470,7 @@ struct thread_options_pack { uint8_t log_gz_cpumask[FIO_TOP_STR_MAX]; #endif uint32_t gpu_dev_id; - uint32_t pad; + uint32_t start_offset_percent; uint32_t cpus_allowed_policy; uint32_t iolog; uint32_t rwmixcycle; -- 2.25.1