[PATCH] Add 'norandommap' option
authorJens Axboe <jens.axboe@oracle.com>
Mon, 30 Oct 2006 14:14:48 +0000 (15:14 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 30 Oct 2006 14:14:48 +0000 (15:14 +0100)
With this option given, fio will not keep track of what parts of a file
has been read/written or not. So for random io, we may read/write a block
a block more than once (or not at all). Thus this option conflicts with
doing write verification.

This is a first step for doing truly randomly sized blocks of io.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
fio.h
init.c
io_u.c

diff --git a/HOWTO b/HOWTO
index ae19834..6d215ac 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -284,6 +284,13 @@ rwmixwrite=int     How large a percentage of the mix should be writes. If both
                up to 100%, the latter of the two will be used to override
                the first.
 
+norandommap    Normally fio will cover every block of the file when doing
+               random IO. If this option is given, fio will just get a
+               new random offset without looking at past io history. This
+               means that some blocks may not be read or written, and that
+               some blocks may be read/written more than once. This option
+               is mutually exclusive with verify= for that reason.
+
 nice=int       Run the job with the given nice value. See man nice(2).
 
 prio=int       Set the io priority value of this job. Linux limits us to
diff --git a/fio.h b/fio.h
index 4af8a4d..b48ef70 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -202,6 +202,7 @@ struct thread_data {
        unsigned int rand_repeatable;
        unsigned int write_lat_log;
        unsigned int write_bw_log;
+       unsigned int norandommap;
 
        unsigned int bs;
        unsigned int min_bs;
diff --git a/init.c b/init.c
index 2ab9419..e4f866a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -51,6 +51,7 @@
 #define DEF_UNLINK             (0)
 #define DEF_WRITE_BW_LOG       (0)
 #define DEF_WRITE_LAT_LOG      (0)
+#define DEF_NO_RAND_MAP                (0)
 
 #define td_var_offset(var)     ((size_t) &((struct thread_data *)0)->var)
 
@@ -342,6 +343,11 @@ static struct fio_option options[] = {
                .type   = FIO_OPT_STR_SET,
                .off1   = td_var_offset(write_lat_log),
        },
+       {
+               .name   = "norandommap",
+               .type   = FIO_OPT_STR_SET,
+               .off1   = td_var_offset(norandommap),
+       },
        {
                .name = NULL,
        },
@@ -479,6 +485,11 @@ static void fixup_options(struct thread_data *td)
                td->max_bs = td->bs;
        if (td_read(td) && !td_rw(td))
                td->verify = 0;
+
+       if (td->norandommap && td->verify != VERIFY_NONE) {
+               log_err("fio: norandommap given, verify disabled\n");
+               td->verify = VERIFY_NONE;
+       }
 }
 
 /*
@@ -674,12 +685,14 @@ int init_random_state(struct thread_data *td)
        if (td->rand_repeatable)
                seeds[3] = DEF_RANDSEED;
 
-       for_each_file(td, f, i) {
-               blocks = (f->file_size + td->min_bs - 1) / td->min_bs;
-               num_maps = blocks / BLOCKS_PER_MAP;
-               f->file_map = malloc(num_maps * sizeof(long));
-               f->num_maps = num_maps;
-               memset(f->file_map, 0, num_maps * sizeof(long));
+       if (!td->norandommap) {
+               for_each_file(td, f, i) {
+                       blocks = (f->file_size + td->min_bs - 1) / td->min_bs;
+                       num_maps = blocks / BLOCKS_PER_MAP;
+                       f->file_map = malloc(num_maps * sizeof(long));
+                       f->num_maps = num_maps;
+                       memset(f->file_map, 0, num_maps * sizeof(long));
+               }
        }
 
        os_random_seed(seeds[3], &td->random_state);
@@ -962,6 +975,7 @@ static int fill_def_thread(void)
        def_thread.unlink = DEF_UNLINK;
        def_thread.write_bw_log = write_bw_log;
        def_thread.write_lat_log = write_lat_log;
+       def_thread.norandommap = DEF_NO_RAND_MAP;
 #ifdef FIO_HAVE_DISK_UTIL
        def_thread.do_disk_util = 1;
 #endif
diff --git a/io_u.c b/io_u.c
index 2605ece..0432079 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -91,6 +91,8 @@ static int get_next_offset(struct thread_data *td, struct fio_file *f,
                do {
                        r = os_random_long(&td->random_state);
                        b = ((max_blocks - 1) * r / (unsigned long long) (RAND_MAX+1.0));
+                       if (td->norandommap)
+                               break;
                        rb = b + (f->file_offset / td->min_bs);
                        loops--;
                } while (!random_map_free(td, f, rb) && loops);
@@ -277,7 +279,7 @@ struct io_u *get_io_u(struct thread_data *td, struct fio_file *f)
                        return NULL;
                }
 
-               if (!td->read_iolog && !td->sequential)
+               if (!td->read_iolog && !td->sequential && !td->norandommap)
                        mark_random_map(td, f, io_u);
 
                f->last_pos += io_u->buflen;