Allow profiles to override internal io_u functions
authorJens Axboe <jens.axboe@oracle.com>
Fri, 5 Mar 2010 09:59:06 +0000 (10:59 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 5 Mar 2010 09:59:06 +0000 (10:59 +0100)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fio.h
init.c
io_u.c
profile.c
profile.h

diff --git a/fio.h b/fio.h
index 23e007b..751fc3d 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -426,6 +426,12 @@ struct thread_data {
         */
        unsigned int total_err_count;
        int first_error;
+
+       /*
+        * Can be overloaded by profiles
+        */
+       int (*fill_io_u_off)(struct thread_data *, struct io_u *);
+       int (*fill_io_u_size)(struct thread_data *, struct io_u *);
 };
 
 /*
diff --git a/init.c b/init.c
index acebb7d..a79bd1a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -168,6 +168,8 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent)
        dup_files(td, parent);
        options_mem_dupe(td);
 
+       profile_add_hooks(td);
+
        td->thread_number = thread_number;
        return td;
 }
diff --git a/io_u.c b/io_u.c
index 1845d3b..278d47a 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -187,7 +187,7 @@ static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
  * until we find a free one. For sequential io, just return the end of
  * the last io issued.
  */
-static int get_next_offset(struct thread_data *td, struct io_u *io_u)
+static int __get_next_offset(struct thread_data *td, struct io_u *io_u)
 {
        struct fio_file *f = io_u->file;
        unsigned long long b;
@@ -231,7 +231,15 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
        return 0;
 }
 
-static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
+static int get_next_offset(struct thread_data *td, struct io_u *io_u)
+{
+       if (td->fill_io_u_off)
+               return td->fill_io_u_off(td, io_u);
+
+       return __get_next_offset(td, io_u);
+}
+
+static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
 {
        const int ddir = io_u->ddir;
        unsigned int uninitialized_var(buflen);
@@ -276,6 +284,14 @@ static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
        return buflen;
 }
 
+static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
+{
+       if (td->fill_io_u_size)
+               return td->fill_io_u_size(td, io_u);
+
+       return __get_next_buflen(td, io_u);
+}
+
 static void set_rwmix_bytes(struct thread_data *td)
 {
        unsigned int diff;
index 92e1902..0e2b97d 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -6,13 +6,11 @@
 
 static FLIST_HEAD(profile_list);
 
-int load_profile(const char *profile)
+struct profile_ops *find_profile(const char *profile)
 {
-       struct profile_ops *ops;
+       struct profile_ops *ops = NULL;
        struct flist_head *n;
 
-       dprint(FD_PROFILE, "loading profile '%s'\n", profile);
-
        flist_for_each(n, &profile_list) {
                ops = flist_entry(n, struct profile_ops, list);
                if (!strcmp(profile, ops->name))
@@ -21,6 +19,16 @@ int load_profile(const char *profile)
                ops = NULL;
        }
 
+       return ops;
+}
+
+int load_profile(const char *profile)
+{
+       struct profile_ops *ops;
+
+       dprint(FD_PROFILE, "loading profile '%s'\n", profile);
+
+       ops = find_profile(profile);
        if (ops) {
                ops->prep_cmd();
                add_job_opts(ops->cmdline);
@@ -73,3 +81,18 @@ void unregister_profile(struct profile_ops *ops)
        invalidate_profile_options(ops->name);
        del_opt_posval("profile", ops->name);
 }
+
+void profile_add_hooks(struct thread_data *td)
+{
+       struct profile_ops *ops;
+
+       if (!exec_profile)
+               return;
+
+       ops = find_profile(exec_profile);
+       if (!ops)
+               return;
+
+       td->fill_io_u_off = ops->fill_io_u_off;
+       td->fill_io_u_size = ops->fill_io_u_size;
+}
index 1185006..3bae500 100644 (file)
--- a/profile.h
+++ b/profile.h
@@ -23,10 +23,18 @@ struct profile_ops {
         * The complete command line
         */
        const char **cmdline;
+
+       /*
+        * Functions for overriding internal fio io_u functions
+        */
+       int (*fill_io_u_off)(struct thread_data *, struct io_u *);
+       int (*fill_io_u_size)(struct thread_data *, struct io_u *);
 };
 
 int register_profile(struct profile_ops *);
 void unregister_profile(struct profile_ops *);
 int load_profile(const char *);
+struct profile_ops *find_profile(const char *);
+void profile_add_hooks(struct thread_data *);
 
 #endif