From: Jens Axboe Date: Tue, 12 Jul 2011 17:47:03 +0000 (+0200) Subject: Allow percentage setting for size= X-Git-Tag: fio-1.56~5 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=7bb591020669b7266c57108f2a68b48a03ae72ee Allow percentage setting for size= Sometimes it's useful to set this to a particular size of a device. Allowing percentages makes this more easy, as one does not have to do the math outside of fio and pass in as environment variables or custom job files. To use, simply add a size=15% or whatever is needed, then fio will use 15% of the total size of the device(s) or file(s) given. Percentage can be from 1 to 100. Signed-off-by: Jens Axboe --- diff --git a/HOWTO b/HOWTO index ee899b8f..ce1bd9e6 100644 --- a/HOWTO +++ b/HOWTO @@ -382,7 +382,10 @@ size=int The total size of file io for this job. Fio will run until fio will divide this size between the available files specified by the job. If not set, fio will use the full size of the given files or devices. If the the files - do not exist, size must be given. + do not exist, size must be given. It is also possible to + give size as a percentage between 1 and 100. If size=20% + is given, fio will use 20% of the full size of the given + files or devices. filesize=int Individual file sizes. May be a range, in which case fio will select sizes for files at random within the given range diff --git a/filesetup.c b/filesetup.c index 2a79e745..8f515923 100644 --- a/filesetup.c +++ b/filesetup.c @@ -759,6 +759,9 @@ int setup_files(struct thread_data *td) } } + if (td->o.size_percent) + total_size = (total_size * td->o.size_percent) / 100; + if (!td->o.size || td->o.size > total_size) td->o.size = total_size; diff --git a/fio.1 b/fio.1 index 0838d07b..b7046d5a 100644 --- a/fio.1 +++ b/fio.1 @@ -257,7 +257,9 @@ been transfered, unless limited by other options (\fBruntime\fR, for instance). Unless \fBnrfiles\fR and \fBfilesize\fR options are given, this amount will be divided between the available files for the job. If not set, fio will use the full size of the given files or devices. If the the files do not exist, size -must be given. +must be given. It is also possible to give size as a percentage between 1 and +100. If size=20% is given, fio will use 20% of the full size of the given files +or devices. .TP .BI fill_device \fR=\fPbool "\fR,\fB fill_fs" \fR=\fPbool Sets size to something really large and waits for ENOSPC (no space left on diff --git a/fio.h b/fio.h index b869dd15..d8e3011b 100644 --- a/fio.h +++ b/fio.h @@ -165,6 +165,7 @@ struct thread_options { unsigned int iodepth_batch_complete; unsigned long long size; + unsigned int size_percent; unsigned int fill_device; unsigned long long file_size_low; unsigned long long file_size_high; diff --git a/options.c b/options.c index b4456a42..74c64780 100644 --- a/options.c +++ b/options.c @@ -744,6 +744,20 @@ static int str_gtod_cpu_cb(void *data, long long *il) return 0; } +static int str_size_cb(void *data, unsigned long long *__val) +{ + struct thread_data *td = data; + unsigned long long v = *__val; + + if (parse_is_percent(v)) { + td->o.size = 0; + td->o.size_percent = -1ULL - v; + } else + td->o.size = v; + + return 0; +} + static int rw_verify(struct fio_option *o, void *data) { struct thread_data *td = data; @@ -1031,8 +1045,7 @@ static struct fio_option options[FIO_MAX_OPTS] = { { .name = "size", .type = FIO_OPT_STR_VAL, - .off1 = td_var_offset(size), - .minval = 1, + .cb = str_size_cb, .help = "Total size of device or files", }, { diff --git a/parse.c b/parse.c index 97ea4aab..ef23fbe9 100644 --- a/parse.c +++ b/parse.c @@ -118,7 +118,8 @@ static unsigned long get_mult_time(char c) } } -static unsigned long long __get_mult_bytes(const char *p, void *data) +static unsigned long long __get_mult_bytes(const char *p, void *data, + int *percent) { unsigned int kb_base = fio_get_kb_base(data); unsigned long long ret = 1; @@ -158,6 +159,10 @@ static unsigned long long __get_mult_bytes(const char *p, void *data) pow = 2; else if (!strcmp("k", c) || !strcmp("kb", c)) pow = 1; + else if (!strcmp("%", c)) { + *percent = 1; + return ret; + } while (pow--) ret *= (unsigned long long) mult; @@ -166,12 +171,13 @@ static unsigned long long __get_mult_bytes(const char *p, void *data) return ret; } -static unsigned long long get_mult_bytes(const char *str, int len, void *data) +static unsigned long long get_mult_bytes(const char *str, int len, void *data, + int *percent) { const char *p = str; if (len < 2) - return __get_mult_bytes(str, data); + return __get_mult_bytes(str, data, percent); /* * Go forward until we hit a non-digit @@ -182,10 +188,10 @@ static unsigned long long get_mult_bytes(const char *str, int len, void *data) p++; } - if (!isalpha((int) *p)) + if (!isalpha((int) *p) && (*p != '%')) p = NULL; - return __get_mult_bytes(p, data); + return __get_mult_bytes(p, data, percent); } /* @@ -208,9 +214,16 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data) if (*val == LONG_MAX && errno == ERANGE) return 1; - if (kilo) - *val *= get_mult_bytes(str, len, data); - else + if (kilo) { + unsigned long long mult; + int perc = 0; + + mult = get_mult_bytes(str, len, data, &perc); + if (perc) + *val = -1ULL - *val; + else + *val *= mult; + } else *val *= get_mult_time(str[len - 1]); return 0; diff --git a/parse.h b/parse.h index 41e3633c..2dd8459f 100644 --- a/parse.h +++ b/parse.h @@ -89,4 +89,9 @@ typedef int (fio_opt_str_set_fn)(void *); #define max(a, b) ((a) > (b) ? (a) : (b)) #endif +static inline int parse_is_percent(unsigned long long val) +{ + return val <= -1ULL && val >= (-1ULL - 100ULL); +} + #endif