From 15dc1934435dc84d66547c4fc92d936224d7238f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 5 Mar 2010 10:59:06 +0100 Subject: [PATCH] Allow profiles to override internal io_u functions Signed-off-by: Jens Axboe --- fio.h | 6 ++++++ init.c | 2 ++ io_u.c | 20 ++++++++++++++++++-- profile.c | 31 +++++++++++++++++++++++++++---- profile.h | 8 ++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/fio.h b/fio.h index 23e007b8..751fc3d1 100644 --- 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 acebb7d1..a79bd1a6 100644 --- 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 1845d3b8..278d47a4 100644 --- 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; diff --git a/profile.c b/profile.c index 92e19026..0e2b97d4 100644 --- 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; +} diff --git a/profile.h b/profile.h index 11850067..3bae5002 100644 --- 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 -- 2.25.1