Allow percentage setting for size=
authorJens Axboe <jaxboe@fusionio.com>
Tue, 12 Jul 2011 17:47:03 +0000 (19:47 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Tue, 12 Jul 2011 17:47:03 +0000 (19:47 +0200)
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 <jaxboe@fusionio.com>
HOWTO
filesetup.c
fio.1
fio.h
options.c
parse.c
parse.h

diff --git a/HOWTO b/HOWTO
index ee899b8..ce1bd9e 100644 (file)
--- 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
index 2a79e74..8f51592 100644 (file)
@@ -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 0838d07..b7046d5 100644 (file)
--- 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 b869dd1..d8e3011 100644 (file)
--- 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;
index b4456a4..74c6478 100644 (file)
--- 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 97ea4aa..ef23fbe 100644 (file)
--- 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 41e3633..2dd8459 100644 (file)
--- 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