Add option for including byte offset for each log entry
authorJens Axboe <axboe@fb.com>
Tue, 1 Jul 2014 02:59:03 +0000 (20:59 -0600)
committerJens Axboe <axboe@fb.com>
Tue, 1 Jul 2014 02:59:03 +0000 (20:59 -0600)
When iops/latency/bw logs are used in the job, we can note the offset
at which the specific data entry took place.

Based on an initial patch from Abutalib Aghayev <agayev@gmail.com>.
Extended by me to:

- Not do this by default, as not to add 8 bytes to each log entry
  stored.

- Add support for the client/server protocol.

- Add documentation.

We should bump the server protocol rev again, but that was just done
in the previous commit, so...

Signed-off-by: Jens Axboe <axboe@fb.com>
13 files changed:
HOWTO
backend.c
client.c
fio.1
init.c
io_u.c
iolog.c
iolog.h
options.c
server.c
server.h
stat.c
thread_options.h

diff --git a/HOWTO b/HOWTO
index d9f3095ee1c7a82a8753cf1f14b0280a24378d77..3001fe74a0b6cffe19fba612e95c082580085c01 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -1333,6 +1333,9 @@ log_avg_msec=int By default, fio will log an entry in the iops, latency,
                specified period of time, reducing the resolution of the log.
                Defaults to 0.
 
+log_offset=int If this is set, the iolog options will include the byte
+               offset for the IO entry as well as the other data values.
+
 lockmem=int    Pin down the specified amount of memory with mlock(2). Can
                potentially be used instead of removing memory or booting
                with less memory to simulate a smaller amount of memory.
index ee75566af84cd6f07a8a4e824ba79e9788667d1b..ac6ed3e45fc2c8cc319a6a614165214ae266464a 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -2020,9 +2020,9 @@ int fio_backend(void)
                return 0;
 
        if (write_bw_log) {
-               setup_log(&agg_io_log[DDIR_READ], 0, IO_LOG_TYPE_BW);
-               setup_log(&agg_io_log[DDIR_WRITE], 0, IO_LOG_TYPE_BW);
-               setup_log(&agg_io_log[DDIR_TRIM], 0, IO_LOG_TYPE_BW);
+               setup_log(&agg_io_log[DDIR_READ], 0, IO_LOG_TYPE_BW, 0);
+               setup_log(&agg_io_log[DDIR_WRITE], 0, IO_LOG_TYPE_BW, 0);
+               setup_log(&agg_io_log[DDIR_TRIM], 0, IO_LOG_TYPE_BW, 0);
        }
 
        startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
index 828dd97b0b355c079fc978e9f65baa07ef37aa54..4587824b9c1daba3fab4ecc59069af939bbd7c66 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1156,7 +1156,7 @@ static struct cmd_iolog_pdu *convert_iolog_gz(struct fio_net_cmd *cmd,
         */
        nr_samples = le32_to_cpu(pdu->nr_samples);
 
-       total = nr_samples * sizeof(struct io_sample);
+       total = nr_samples * __log_entry_sz(pdu->log_offset);
        ret = malloc(total + sizeof(*pdu));
        ret->nr_samples = nr_samples;
 
@@ -1206,7 +1206,8 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
 {
        struct cmd_iolog_pdu *pdu = (struct cmd_iolog_pdu *) cmd->payload;
        struct cmd_iolog_pdu *ret;
-       int i;
+       uint64_t i;
+       void *samples;
 
        /*
         * Convert if compressed and we support it. If it's not
@@ -1225,18 +1226,27 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd)
        } else
                ret = pdu;
 
+       ret->nr_samples         = le64_to_cpu(ret->nr_samples);
        ret->thread_number      = le32_to_cpu(ret->thread_number);
-       ret->nr_samples         = le32_to_cpu(ret->nr_samples);
        ret->log_type           = le32_to_cpu(ret->log_type);
        ret->compressed         = le32_to_cpu(ret->compressed);
+       ret->log_offset         = le32_to_cpu(ret->log_offset);
 
+       samples = &ret->samples[i];
        for (i = 0; i < ret->nr_samples; i++) {
-               struct io_sample *s = &ret->samples[i];
+               struct io_sample *s;
 
+               s = __get_sample(samples, ret->log_offset, i);
                s->time = le64_to_cpu(s->time);
                s->val  = le64_to_cpu(s->val);
                s->ddir = le32_to_cpu(s->ddir);
                s->bs   = le32_to_cpu(s->bs);
+
+               if (ret->log_offset) {
+                       struct io_sample_offset *so = (void *) s;
+
+                       so->offset = le64_to_cpu(so->offset);
+               }
        }
 
        return ret;
diff --git a/fio.1 b/fio.1
index 62f40ea294d1695a926dcc420abce6f599c5dc2e..da44e570167fb16010fed7f6a392b6f3dc241f9f 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -1210,6 +1210,10 @@ very large size. Setting this option makes fio average the each log entry
 over the specified period of time, reducing the resolution of the log.
 Defaults to 0.
 .TP
+.BI log_offset \fR=\fPbool
+If this is set, the iolog options will include the byte offset for the IO
+entry as well as the other data values.
+.TP
 .BI disable_lat \fR=\fPbool
 Disable measurements of total latency numbers. Useful only for cutting
 back the number of calls to \fBgettimeofday\fR\|(2), as that does impact performance at
diff --git a/init.c b/init.c
index 6b29aa702407a69799f54ff15a60011a105be5d8..4f8b38d6e6324f5acab8ccd074a23cdeaf74d3ca 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1146,14 +1146,19 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                goto err;
 
        if (o->lat_log_file || write_lat_log) {
-               setup_log(&td->lat_log, o->log_avg_msec, IO_LOG_TYPE_LAT);
-               setup_log(&td->slat_log, o->log_avg_msec, IO_LOG_TYPE_SLAT);
-               setup_log(&td->clat_log, o->log_avg_msec, IO_LOG_TYPE_CLAT);
+               setup_log(&td->lat_log, o->log_avg_msec, IO_LOG_TYPE_LAT,
+                               o->log_offset);
+               setup_log(&td->slat_log, o->log_avg_msec, IO_LOG_TYPE_SLAT,
+                               o->log_offset);
+               setup_log(&td->clat_log, o->log_avg_msec, IO_LOG_TYPE_CLAT,
+                               o->log_offset);
        }
        if (o->bw_log_file || write_bw_log)
-               setup_log(&td->bw_log, o->log_avg_msec, IO_LOG_TYPE_BW);
+               setup_log(&td->bw_log, o->log_avg_msec, IO_LOG_TYPE_BW,
+                               o->log_offset);
        if (o->iops_log_file)
-               setup_log(&td->iops_log, o->log_avg_msec, IO_LOG_TYPE_IOPS);
+               setup_log(&td->iops_log, o->log_avg_msec, IO_LOG_TYPE_IOPS,
+                               o->log_offset);
 
        if (!o->name)
                o->name = strdup(jobname);
diff --git a/io_u.c b/io_u.c
index 997e1137ab906c090040213f8fe7eecf1c72af76..5b9d483dcd330b69ff0ddff4f86cb9512247cf31 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1567,7 +1567,7 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
                unsigned long tusec;
 
                tusec = utime_since(&io_u->start_time, &icd->time);
-               add_lat_sample(td, idx, tusec, bytes);
+               add_lat_sample(td, idx, tusec, bytes, io_u->offset);
 
                if (td->flags & TD_F_PROFILE_OPS) {
                        struct prof_io_ops *ops = &td->prof_io_ops;
@@ -1585,7 +1585,7 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
        }
 
        if (!td->o.disable_clat) {
-               add_clat_sample(td, idx, lusec, bytes);
+               add_clat_sample(td, idx, lusec, bytes, io_u->offset);
                io_u_mark_latency(td, lusec);
        }
 
@@ -1823,7 +1823,8 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
                unsigned long slat_time;
 
                slat_time = utime_since(&io_u->start_time, &io_u->issue_time);
-               add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen);
+               add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen,
+                               io_u->offset);
        }
 }
 
diff --git a/iolog.c b/iolog.c
index fd1e9e49dd18ad216eaad2cf15d15da879df4c3e..a79efe2afb491a96657f0638a52b5ad63029add4 100644 (file)
--- a/iolog.c
+++ b/iolog.c
@@ -539,7 +539,8 @@ int init_iolog(struct thread_data *td)
        return ret;
 }
 
-void setup_log(struct io_log **log, unsigned long avg_msec, int log_type)
+void setup_log(struct io_log **log, unsigned long avg_msec, int log_type,
+              int log_offset)
 {
        struct io_log *l = malloc(sizeof(*l));
 
@@ -547,7 +548,8 @@ void setup_log(struct io_log **log, unsigned long avg_msec, int log_type)
        l->nr_samples = 0;
        l->max_samples = 1024;
        l->log_type = log_type;
-       l->log = malloc(l->max_samples * sizeof(struct io_sample));
+       l->log_offset = log_offset;
+       l->log = malloc(l->max_samples * log_entry_sz(l));
        l->avg_msec = avg_msec;
        *log = l;
 }
@@ -580,7 +582,7 @@ static void clear_file_buffer(void *buf)
 
 void __finish_log(struct io_log *log, const char *name)
 {
-       unsigned int i;
+       uint64_t i;
        void *buf;
        FILE *f;
 
@@ -593,10 +595,22 @@ void __finish_log(struct io_log *log, const char *name)
        buf = set_file_buffer(f);
 
        for (i = 0; i < log->nr_samples; i++) {
-               fprintf(f, "%lu, %lu, %u, %u\n",
-                               (unsigned long) log->log[i].time,
-                               (unsigned long) log->log[i].val,
-                               log->log[i].ddir, log->log[i].bs);
+               struct io_sample *s = get_sample(log, i);
+
+               if (!log->log_offset) {
+                       fprintf(f, "%lu, %lu, %u, %u\n",
+                                       (unsigned long) s->time,
+                                       (unsigned long) s->val,
+                                       s->ddir, s->bs);
+               } else {
+                       struct io_sample_offset *so = (void *) s;
+
+                       fprintf(f, "%lu, %lu, %u, %u, %llu\n",
+                                       (unsigned long) s->time,
+                                       (unsigned long) s->val,
+                                       s->ddir, s->bs,
+                                       (unsigned long long) so->offset);
+               }
        }
 
        fclose(f);
diff --git a/iolog.h b/iolog.h
index 3af56682c64eaeecbd35e19c753cb315ecabec80..b387f48d1600b651a47f7969e0ab3c9ea8ffe49b 100644 (file)
--- a/iolog.h
+++ b/iolog.h
@@ -28,6 +28,11 @@ struct io_sample {
        uint32_t bs;
 };
 
+struct io_sample_offset {
+       struct io_sample s;
+       uint64_t offset;
+};
+
 enum {
        IO_LOG_TYPE_LAT = 1,
        IO_LOG_TYPE_CLAT,
@@ -45,7 +50,7 @@ struct io_log {
         */
        unsigned long nr_samples;
        unsigned long max_samples;
-       struct io_sample *log;
+       void *log;
 
        unsigned int log_type;
 
@@ -54,6 +59,11 @@ struct io_log {
         */
        unsigned int disabled;
 
+       /*
+        * Log offsets
+        */
+       unsigned int log_offset;
+
        /*
         * Windowed average, for logging single entries average over some
         * period of time.
@@ -63,6 +73,31 @@ struct io_log {
        unsigned long avg_last;
 };
 
+static inline size_t __log_entry_sz(int log_offset)
+{
+       if (log_offset)
+               return sizeof(struct io_sample_offset);
+       else
+               return sizeof(struct io_sample);
+}
+
+static inline size_t log_entry_sz(struct io_log *log)
+{
+       return __log_entry_sz(log->log_offset);
+}
+
+static inline struct io_sample *__get_sample(void *samples, int log_offset,
+                                            uint64_t sample)
+{
+       return samples + sample * __log_entry_sz(log_offset);
+}
+
+static inline struct io_sample *get_sample(struct io_log *iolog,
+                                          uint64_t sample)
+{
+       return __get_sample(iolog->log, iolog->log_offset, sample);
+}
+
 enum {
        IP_F_ONRB       = 1,
        IP_F_ONLIST     = 2,
@@ -121,18 +156,18 @@ extern void write_iolog_close(struct thread_data *);
  */
 extern void finalize_logs(struct thread_data *td);
 extern void add_lat_sample(struct thread_data *, enum fio_ddir, unsigned long,
-                               unsigned int);
+                               unsigned int, uint64_t);
 extern void add_clat_sample(struct thread_data *, enum fio_ddir, unsigned long,
-                               unsigned int);
+                               unsigned int, uint64_t);
 extern void add_slat_sample(struct thread_data *, enum fio_ddir, unsigned long,
-                               unsigned int);
+                               unsigned int, uint64_t);
 extern void add_bw_sample(struct thread_data *, enum fio_ddir, unsigned int,
                                struct timeval *);
 extern void add_iops_sample(struct thread_data *, enum fio_ddir, unsigned int,
                                struct timeval *);
 extern void init_disk_util(struct thread_data *);
 extern void update_rusage_stat(struct thread_data *);
-extern void setup_log(struct io_log **, unsigned long, int);
+extern void setup_log(struct io_log **, unsigned long, int, int);
 extern void __finish_log(struct io_log *, const char *);
 extern struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 extern int write_bw_log;
index 74347f3554e02b027d42f8012ebe96cbb9cbc716..6d326d4e6fca447e52b52d3493ee1ffc829a60d9 100644 (file)
--- a/options.c
+++ b/options.c
@@ -3094,6 +3094,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
        },
+       {
+               .name   = "log_offset",
+               .lname  = "Log offset of IO",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(log_offset),
+               .help   = "Include offset of IO for each log entry",
+               .def    = "0",
+               .category = FIO_OPT_C_LOG,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "bwavgtime",
                .lname  = "Bandwidth average time",
index 76b6b54d369bbf0ec18afe502631f9d287150c41..cd00cc65f8525a44706e1fa79e0ef085f532a086 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1177,7 +1177,7 @@ static int fio_send_iolog_gz(struct cmd_iolog_pdu *pdu, struct io_log *log)
        }
 
        stream.next_in = (void *) log->log;
-       stream.avail_in = log->nr_samples * sizeof(struct io_sample);
+       stream.avail_in = log->nr_samples * log_entry_sz(log);
 
        do {
                unsigned int this_len, flags = 0;
@@ -1214,8 +1214,8 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
        struct cmd_iolog_pdu pdu;
        int i, ret = 0;
 
+       pdu.nr_samples = cpu_to_le64(log->nr_samples);
        pdu.thread_number = cpu_to_le32(td->thread_number);
-       pdu.nr_samples = __cpu_to_le32(log->nr_samples);
        pdu.log_type = cpu_to_le32(log->log_type);
        pdu.compressed = cpu_to_le32(use_zlib);
 
@@ -1223,12 +1223,18 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
        pdu.name[FIO_NET_NAME_MAX - 1] = '\0';
 
        for (i = 0; i < log->nr_samples; i++) {
-               struct io_sample *s = &log->log[i];
+               struct io_sample *s = get_sample(log, i);
 
                s->time = cpu_to_le64(s->time);
                s->val  = cpu_to_le64(s->val);
                s->ddir = cpu_to_le32(s->ddir);
                s->bs   = cpu_to_le32(s->bs);
+
+               if (log->log_offset) {
+                       struct io_sample_offset *so = (void *) s;
+
+                       so->offset = cpu_to_le64(so->offset);
+               }
        }
 
        /*
@@ -1246,7 +1252,7 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name)
                return fio_send_iolog_gz(&pdu, log);
 
        return fio_send_cmd_ext_pdu(server_fd, FIO_NET_CMD_IOLOG, log->log,
-                       log->nr_samples * sizeof(struct io_sample), 0, 0);
+                       log->nr_samples * log_entry_sz(log), 0, 0);
 }
 
 void fio_server_send_add_job(struct thread_data *td)
index 52ad4a1518fbc813111ba1555f940f8ef925350d..cc4c5b435a2f022164638cf99274f8f60ff75cd9 100644 (file)
--- a/server.h
+++ b/server.h
@@ -143,10 +143,11 @@ struct cmd_text_pdu {
 };
 
 struct cmd_iolog_pdu {
+       uint64_t nr_samples;
        uint32_t thread_number;
-       uint32_t nr_samples;
        uint32_t log_type;
        uint32_t compressed;
+       uint32_t log_offset;
        uint8_t name[FIO_NET_NAME_MAX];
        struct io_sample samples[0];
 };
diff --git a/stat.c b/stat.c
index 3adb46eab8087cc53ae0fd2b7c15ad048596c040..58744a82e7e1eafbdbf1e12dc3717a5ca8cffd60 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1563,9 +1563,10 @@ static inline void add_stat_sample(struct io_stat *is, unsigned long data)
 
 static void __add_log_sample(struct io_log *iolog, unsigned long val,
                             enum fio_ddir ddir, unsigned int bs,
-                            unsigned long t)
+                            unsigned long t, uint64_t offset)
 {
        const int nr_samples = iolog->nr_samples;
+       struct io_sample *s;
 
        if (iolog->disabled)
                return;
@@ -1574,9 +1575,10 @@ static void __add_log_sample(struct io_log *iolog, unsigned long val,
                iolog->avg_last = t;
 
        if (iolog->nr_samples == iolog->max_samples) {
-               int new_size = sizeof(struct io_sample) * iolog->max_samples*2;
+               size_t new_size;
                void *new_log;
 
+               new_size = 2 * iolog->max_samples * log_entry_sz(iolog);
                new_log = realloc(iolog->log, new_size);
                if (!new_log) {
                        log_err("fio: failed extending iolog! Will stop logging.\n");
@@ -1587,10 +1589,19 @@ static void __add_log_sample(struct io_log *iolog, unsigned long val,
                iolog->max_samples <<= 1;
        }
 
-       iolog->log[nr_samples].val = val;
-       iolog->log[nr_samples].time = t;
-       iolog->log[nr_samples].ddir = ddir;
-       iolog->log[nr_samples].bs = bs;
+       s = get_sample(iolog, nr_samples);
+
+       s->val = val;
+       s->time = t;
+       s->ddir = ddir;
+       s->bs = bs;
+
+       if (iolog->log_offset) {
+               struct io_sample_offset *so = (void *) s;
+
+               so->offset = offset;
+       }
+
        iolog->nr_samples++;
 }
 
@@ -1646,19 +1657,19 @@ static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed)
                unsigned long mr;
 
                mr = iolog->avg_window[DDIR_READ].mean.u.f + 0.50;
-               __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed);
+               __add_log_sample(iolog, mr, DDIR_READ, 0, elapsed, 0);
        }
        if (iolog->avg_window[DDIR_WRITE].samples) {
                unsigned long mw;
 
                mw = iolog->avg_window[DDIR_WRITE].mean.u.f + 0.50;
-               __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed);
+               __add_log_sample(iolog, mw, DDIR_WRITE, 0, elapsed, 0);
        }
        if (iolog->avg_window[DDIR_TRIM].samples) {
                unsigned long mw;
 
                mw = iolog->avg_window[DDIR_TRIM].mean.u.f + 0.50;
-               __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed);
+               __add_log_sample(iolog, mw, DDIR_TRIM, 0, elapsed, 0);
        }
 
        reset_io_stat(&iolog->avg_window[DDIR_READ]);
@@ -1668,7 +1679,7 @@ static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed)
 
 static void add_log_sample(struct thread_data *td, struct io_log *iolog,
                           unsigned long val, enum fio_ddir ddir,
-                          unsigned int bs)
+                          unsigned int bs, uint64_t offset)
 {
        unsigned long elapsed, this_window;
 
@@ -1681,7 +1692,7 @@ static void add_log_sample(struct thread_data *td, struct io_log *iolog,
         * If no time averaging, just add the log sample.
         */
        if (!iolog->avg_msec) {
-               __add_log_sample(iolog, val, ddir, bs, elapsed);
+               __add_log_sample(iolog, val, ddir, bs, elapsed, offset);
                return;
        }
 
@@ -1730,7 +1741,7 @@ void add_agg_sample(unsigned long val, enum fio_ddir ddir, unsigned int bs)
                return;
 
        iolog = agg_io_log[ddir];
-       __add_log_sample(iolog, val, ddir, bs, mtime_since_genesis());
+       __add_log_sample(iolog, val, ddir, bs, mtime_since_genesis(), 0);
 }
 
 static void add_clat_percentile_sample(struct thread_stat *ts,
@@ -1743,7 +1754,7 @@ static void add_clat_percentile_sample(struct thread_stat *ts,
 }
 
 void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
-                    unsigned long usec, unsigned int bs)
+                    unsigned long usec, unsigned int bs, uint64_t offset)
 {
        struct thread_stat *ts = &td->ts;
 
@@ -1753,14 +1764,14 @@ void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
        add_stat_sample(&ts->clat_stat[ddir], usec);
 
        if (td->clat_log)
-               add_log_sample(td, td->clat_log, usec, ddir, bs);
+               add_log_sample(td, td->clat_log, usec, ddir, bs, offset);
 
        if (ts->clat_percentiles)
                add_clat_percentile_sample(ts, usec, ddir);
 }
 
 void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
-                    unsigned long usec, unsigned int bs)
+                    unsigned long usec, unsigned int bs, uint64_t offset)
 {
        struct thread_stat *ts = &td->ts;
 
@@ -1770,11 +1781,11 @@ void add_slat_sample(struct thread_data *td, enum fio_ddir ddir,
        add_stat_sample(&ts->slat_stat[ddir], usec);
 
        if (td->slat_log)
-               add_log_sample(td, td->slat_log, usec, ddir, bs);
+               add_log_sample(td, td->slat_log, usec, ddir, bs, offset);
 }
 
 void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
-                   unsigned long usec, unsigned int bs)
+                   unsigned long usec, unsigned int bs, uint64_t offset)
 {
        struct thread_stat *ts = &td->ts;
 
@@ -1784,7 +1795,7 @@ void add_lat_sample(struct thread_data *td, enum fio_ddir ddir,
        add_stat_sample(&ts->lat_stat[ddir], usec);
 
        if (td->lat_log)
-               add_log_sample(td, td->lat_log, usec, ddir, bs);
+               add_log_sample(td, td->lat_log, usec, ddir, bs, offset);
 }
 
 void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs,
@@ -1818,7 +1829,7 @@ void add_bw_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs,
                add_stat_sample(&ts->bw_stat[ddir], rate);
 
                if (td->bw_log)
-                       add_log_sample(td, td->bw_log, rate, ddir, bs);
+                       add_log_sample(td, td->bw_log, rate, ddir, bs, 0);
 
                td->stat_io_bytes[ddir] = td->this_io_bytes[ddir];
        }
@@ -1857,7 +1868,7 @@ void add_iops_sample(struct thread_data *td, enum fio_ddir ddir, unsigned int bs
                add_stat_sample(&ts->iops_stat[ddir], iops);
 
                if (td->iops_log)
-                       add_log_sample(td, td->iops_log, iops, ddir, bs);
+                       add_log_sample(td, td->iops_log, iops, ddir, bs, 0);
 
                td->stat_io_blocks[ddir] = td->this_io_blocks[ddir];
        }
index 57d84dbba3defda3df5ae44fa0880954a3c28a93..e53000ab248b4d74baba2d5b4caa58c846f49307 100644 (file)
@@ -108,6 +108,7 @@ struct thread_options {
        unsigned long long rand_seed;
        unsigned int use_os_rand;
        unsigned int log_avg_msec;
+       unsigned int log_offset;
        unsigned int norandommap;
        unsigned int softrandommap;
        unsigned int bs_unaligned;
@@ -335,6 +336,7 @@ struct thread_options_pack {
        uint64_t rand_seed;
        uint32_t use_os_rand;
        uint32_t log_avg_msec;
+       uint32_t log_offset;
        uint32_t norandommap;
        uint32_t softrandommap;
        uint32_t bs_unaligned;