Add pre_read option
authorZhang, Yanmin <yanmin_zhang@linux.intel.com>
Wed, 20 May 2009 09:30:55 +0000 (11:30 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Wed, 20 May 2009 09:30:55 +0000 (11:30 +0200)
With this option set, files will be pre-read into memory before
starting the given IO operation(s).

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

diff --git a/HOWTO b/HOWTO
index 9bfa437..1390f38 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -713,6 +713,9 @@ create_fsync=bool   fsync the data file after creation. This is the
 create_on_open=bool    Don't pre-setup the files for IO, just create open()
                        when it's time to do IO to that file.
 
+pre_read=bool  If this is given, files will be pre-read into memory before
+               starting the given IO operation.
+
 unlink=bool    Unlink the job files when done. Not the default, as repeated
                runs of that job would then waste time recreating the file
                set again and again.
index 04d7b98..2858018 100644 (file)
@@ -119,6 +119,39 @@ err:
        return 1;
 }
 
+static int pre_read_file(struct thread_data *td, struct fio_file *f)
+{
+       int r;
+       unsigned long long left;
+       unsigned int bs;
+       char *b;
+
+       bs = td->o.max_bs[DDIR_READ];
+       b = malloc(bs);
+       memset(b, 0, bs);
+
+       lseek(f->fd, f->file_offset, SEEK_SET);
+       left = f->io_size;
+
+       while (left && !td->terminate) {
+               if (bs > left)
+                       bs = left;
+
+               r = read(f->fd, b, bs);
+
+               if (r == (int) bs) {
+                       left -= bs;
+                       continue;
+               } else {
+                       td_verror(td, EIO, "pre_read");
+                       break;
+               }
+       }
+
+       free(b);
+       return 0;
+}
+
 static unsigned long long get_rand_file_size(struct thread_data *td)
 {
        unsigned long long ret, sized;
@@ -572,6 +605,20 @@ err_offset:
        return 1;
 }
 
+int pre_read_files(struct thread_data *td)
+{
+       struct fio_file *f;
+       unsigned int i;
+
+       dprint(FD_FILE, "pre_read files\n");
+
+       for_each_file(td, f, i) {
+               pre_read_file(td, f);
+       }
+
+       return 1;
+}
+
 int init_random_map(struct thread_data *td)
 {
        unsigned long long blocks, num_maps;
diff --git a/fio.c b/fio.c
index 4a02f2e..185f99a 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -1018,6 +1018,11 @@ static void *thread_main(void *data)
                        goto err;
        }
 
+       if (td->o.pre_read) {
+               if (pre_read_files(td) < 0)
+                       goto err;
+       }
+
        fio_gettime(&td->epoch, NULL);
        getrusage(RUSAGE_SELF, &td->ts.ru_start);
 
diff --git a/fio.h b/fio.h
index 1ccc862..cb80a11 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -447,6 +447,7 @@ struct thread_options {
        unsigned int create_fsync;
        unsigned int create_on_open;
        unsigned int end_fsync;
+       unsigned int pre_read;
        unsigned int sync_io;
        unsigned int verify;
        unsigned int do_verify;
@@ -874,6 +875,7 @@ extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_f
 extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
 extern int __must_check generic_close_file(struct thread_data *, struct fio_file *);
 extern int __must_check generic_get_file_size(struct thread_data *, struct fio_file *);
+extern int __must_check pre_read_files(struct thread_data *);
 extern int add_file(struct thread_data *, const char *);
 extern void get_file(struct fio_file *);
 extern int __must_check put_file(struct thread_data *, struct fio_file *);
index 9267f79..a45d1af 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1334,6 +1334,13 @@ static struct fio_option options[] = {
                .help   = "Create files when they are opened for IO",
                .def    = "0",
        },
+       {
+               .name   = "pre_read",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(pre_read),
+               .help   = "Preread files before starting official testing",
+               .def    = "0",
+       },
        {
                .name   = "cpuload",
                .type   = FIO_OPT_INT,