log: fix use-after-free
[fio.git] / iolog.h
diff --git a/iolog.h b/iolog.h
index 50d09e26bfbe3a3abe49d1b56c414a38854b5417..f97d91f792f717f2d4286e2ac9374939e832ba8f 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,
@@ -43,9 +48,11 @@ struct io_log {
        /*
         * Entries already logged
         */
-       unsigned long nr_samples;
-       unsigned long max_samples;
-       struct io_sample *log;
+       uint64_t nr_samples;
+       uint64_t max_samples;
+       void *log;
+
+       char *filename;
 
        unsigned int log_type;
 
@@ -54,6 +61,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 +75,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,
@@ -110,6 +147,8 @@ extern void log_io_u(struct thread_data *, struct io_u *);
 extern void log_file(struct thread_data *, struct fio_file *, enum file_log_act);
 extern int __must_check init_iolog(struct thread_data *td);
 extern void log_io_piece(struct thread_data *, struct io_u *);
+extern void unlog_io_piece(struct thread_data *, struct io_u *);
+extern void trim_io_piece(struct thread_data *, struct io_u *);
 extern void queue_io_piece(struct thread_data *, struct io_piece *);
 extern void prune_io_piece_log(struct thread_data *);
 extern void write_iolog_close(struct thread_data *);
@@ -119,19 +158,20 @@ 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 __finish_log(struct io_log *, const char *);
+extern void setup_log(struct io_log **, unsigned long, int, int, const char *);
+extern void __finish_log(struct io_log *);
+extern void free_log(struct io_log *);
 extern struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 extern int write_bw_log;
 extern void add_agg_sample(unsigned long, enum fio_ddir, unsigned int);