blktrace improvements and fixups
[fio.git] / fio.h
diff --git a/fio.h b/fio.h
index 0d57b608c3a29d49f0c8e8008b5c78388a73d110..dab66d2b94766d7073fbe03ceab6ae1651b3879e 100644 (file)
--- a/fio.h
+++ b/fio.h
 #include "arch/arch.h"
 #include "os/os.h"
 #include "mutex.h"
-
-#ifdef FIO_HAVE_SYSLET
-#include "syslet.h"
-#endif
+#include "log.h"
+#include "debug.h"
 
 #ifdef FIO_HAVE_GUASI
 #include <guasi.h>
@@ -48,6 +46,12 @@ enum td_ddir {
        TD_DDIR_RANDRW          = TD_DDIR_RW | TD_DDIR_RAND,
 };
 
+enum file_lock_mode {
+       FILE_LOCK_NONE,
+       FILE_LOCK_EXCLUSIVE,
+       FILE_LOCK_READWRITE,
+};
+
 /*
  * Use for maintaining statistics
  */
@@ -99,14 +103,6 @@ struct io_piece {
        };
 };
 
-#ifdef FIO_HAVE_SYSLET
-struct syslet_req {
-       struct syslet_uatom atom;       /* the atom to submit */
-       struct syslet_uatom *head;      /* head of the sequence */
-       long ret;                       /* syscall return value */
-};
-#endif
-
 enum {
        IO_U_F_FREE     = 1 << 0,
        IO_U_F_FLIGHT   = 1 << 1,
@@ -128,9 +124,6 @@ struct io_u {
 #ifdef FIO_HAVE_SGIO
                struct sg_io_hdr hdr;
 #endif
-#ifdef FIO_HAVE_SYSLET
-               struct syslet_req req;
-#endif
 #ifdef FIO_HAVE_GUASI
                guasi_req_t greq;
 #endif
@@ -199,7 +192,6 @@ enum {
        VERIFY_SHA256,                  /* sha256 sum data blocks */
        VERIFY_SHA512,                  /* sha512 sum data blocks */
        VERIFY_META,                    /* block_num, timestamp etc. */
-       VERIFY_PATTERN,                 /* verify a specific pattern */
        VERIFY_NULL,                    /* pretend to verify */
 };
 
@@ -278,16 +270,17 @@ enum fio_ioengine_flags {
        FIO_NOEXTEND    = 1 << 3,       /* engine can't extend file */
        FIO_NODISKUTIL  = 1 << 4,       /* diskutil can't handle filename */
        FIO_UNIDIR      = 1 << 5,       /* engine is uni-directional */
+       FIO_NOIO        = 1 << 6,       /* thread does only pseudo IO */
+       FIO_SIGQUIT     = 1 << 7,       /* needs SIGQUIT to exit */
 };
 
 enum fio_file_flags {
        FIO_FILE_OPEN           = 1 << 0,       /* file is open */
        FIO_FILE_CLOSING        = 1 << 1,       /* file being closed */
-       FIO_FILE_EXISTS         = 1 << 2,       /* file there */
-       FIO_FILE_EXTEND         = 1 << 3,       /* needs extend */
-       FIO_FILE_NOSORT         = 1 << 4,       /* don't sort verify blocks */
-       FIO_FILE_DONE           = 1 << 5,       /* io completed to this file */
-       FIO_SIZE_KNOWN          = 1 << 6,       /* size has been set */
+       FIO_FILE_EXTEND         = 1 << 2,       /* needs extend */
+       FIO_FILE_DONE           = 1 << 3,       /* io completed to this file */
+       FIO_SIZE_KNOWN          = 1 << 4,       /* size has been set */
+       FIO_FILE_HASHED         = 1 << 5,       /* file is on hash */
 };
 
 /*
@@ -295,6 +288,7 @@ enum fio_file_flags {
  * this structure holds state information for a single file.
  */
 struct fio_file {
+       struct list_head hash_list;
        enum fio_filetype filetype;
 
        /*
@@ -320,7 +314,14 @@ struct fio_file {
        unsigned long long io_size;
 
        unsigned long long last_pos;
-       unsigned long long last_completed_pos;
+
+       /*
+        * if io is protected by a semaphore, this is set
+        */
+       struct fio_mutex *lock;
+       void *lock_owner;
+       unsigned int lock_batch;
+       enum fio_ddir lock_ddir;
 
        /*
         * block map for random io
@@ -387,6 +388,11 @@ struct thread_stat {
        unsigned long total_run_time;
 };
 
+struct bssplit {
+       unsigned int bs;
+       unsigned char perc;
+};
+
 struct thread_options {
        int pad;
        char *description;
@@ -402,6 +408,7 @@ struct thread_options {
        unsigned int iodepth_batch;
 
        unsigned long long size;
+       unsigned int fill_device;
        unsigned long long file_size_low;
        unsigned long long file_size_high;
        unsigned long long start_offset;
@@ -409,9 +416,13 @@ struct thread_options {
        unsigned int bs[2];
        unsigned int min_bs[2];
        unsigned int max_bs[2];
+       struct bssplit *bssplit;
+       unsigned int bssplit_nr;
 
        unsigned int nr_files;
        unsigned int open_files;
+       enum file_lock_mode file_lock_mode;
+       unsigned int lockfile_batch;
 
        unsigned int odirect;
        unsigned int invalidate_cache;
@@ -504,7 +515,7 @@ struct thread_data {
        int thread_number;
        int groupid;
        struct thread_stat ts;
-       struct fio_file *files;
+       struct fio_file **files;
        unsigned int files_index;
        unsigned int nr_open_files;
        unsigned int nr_done_files;
@@ -521,6 +532,7 @@ struct thread_data {
        volatile int terminate;
        volatile int runstate;
        unsigned int ioprio;
+       unsigned int ioprio_set;
        unsigned int last_was_sync;
 
        char *mmapfile;
@@ -568,7 +580,7 @@ struct thread_data {
        unsigned long long io_skip_bytes;
        unsigned long long this_io_bytes[2];
        unsigned long long zone_bytes;
-       struct fio_sem *mutex;
+       struct fio_mutex *mutex;
 
        /*
         * State for random io, a bitmap of blocks done vs not done
@@ -666,13 +678,12 @@ extern int nr_process, nr_thread;
 extern int shm_id;
 extern int groupid;
 extern int terse_output;
-extern FILE *f_out;
-extern FILE *f_err;
 extern int temp_stall_ts;
 extern unsigned long long mlock_size;
 extern unsigned long page_mask, page_size;
 extern int read_only;
 extern int eta_print;
+extern char *job_section;
 
 extern struct thread_data *threads;
 
@@ -687,7 +698,7 @@ static inline void fio_ro_check(struct thread_data *td, struct io_u *io_u)
 }
 
 #define BLOCKS_PER_MAP         (8 * sizeof(long))
-#define TO_MAP_BLOCK(td, f, b) ((b) - ((f)->file_offset / (td)->o.rw_min_bs))
+#define TO_MAP_BLOCK(td, f, b) (b)
 #define RAND_MAP_IDX(td, f, b) (TO_MAP_BLOCK(td, f, b) / BLOCKS_PER_MAP)
 #define RAND_MAP_BIT(td, f, b) (TO_MAP_BLOCK(td, f, b) & (BLOCKS_PER_MAP - 1))
 
@@ -751,6 +762,7 @@ 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 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 *);
 
@@ -775,8 +787,8 @@ extern void add_agg_sample(unsigned long, enum fio_ddir);
 /*
  * Time functions
  */
-extern unsigned long utime_since(struct timeval *, struct timeval *);
-extern unsigned long utime_since_now(struct timeval *);
+extern unsigned long long utime_since(struct timeval *, struct timeval *);
+extern unsigned long long utime_since_now(struct timeval *);
 extern unsigned long mtime_since(struct timeval *, struct timeval *);
 extern unsigned long mtime_since_now(struct timeval *);
 extern unsigned long time_since_now(struct timeval *);
@@ -806,14 +818,18 @@ extern void options_mem_free(struct thread_data *);
  * File setup/shutdown
  */
 extern void close_files(struct thread_data *);
+extern void close_and_free_files(struct thread_data *);
 extern int __must_check setup_files(struct thread_data *);
 extern int __must_check open_files(struct thread_data *);
 extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_file *);
 extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
-extern void generic_close_file(struct thread_data *, struct fio_file *);
+extern int __must_check generic_close_file(struct thread_data *, struct fio_file *);
 extern int add_file(struct thread_data *, const char *);
 extern void get_file(struct fio_file *);
-extern void put_file(struct thread_data *, struct fio_file *);
+extern int __must_check put_file(struct thread_data *, struct fio_file *);
+extern void lock_file(struct thread_data *, struct fio_file *, enum fio_ddir);
+extern void unlock_file(struct thread_data *, struct fio_file *);
+extern void unlock_file_all(struct thread_data *, struct fio_file *);
 extern int add_dir_files(struct thread_data *, const char *);
 extern int init_random_map(struct thread_data *);
 extern void dup_files(struct thread_data *, struct thread_data *);
@@ -896,10 +912,10 @@ extern int __must_check td_io_init(struct thread_data *);
 extern int __must_check td_io_prep(struct thread_data *, struct io_u *);
 extern int __must_check td_io_queue(struct thread_data *, struct io_u *);
 extern int __must_check td_io_sync(struct thread_data *, struct fio_file *);
-extern int __must_check td_io_getevents(struct thread_data *, int, int, struct timespec *);
+extern int __must_check td_io_getevents(struct thread_data *, unsigned int, unsigned int, struct timespec *);
 extern int __must_check td_io_commit(struct thread_data *);
 extern int __must_check td_io_open_file(struct thread_data *, struct fio_file *);
-extern void td_io_close_file(struct thread_data *, struct fio_file *);
+extern int td_io_close_file(struct thread_data *, struct fio_file *);
 
 /*
  * blktrace support
@@ -909,20 +925,6 @@ extern int is_blktrace(const char *);
 extern int load_blktrace(struct thread_data *, const char *);
 #endif
 
-/*
- * If logging output to a file, stderr should go to both stderr and f_err
- */
-#define log_err(args...)       do {            \
-       fprintf(f_err, ##args);                 \
-       if (f_err != stderr)                    \
-               fprintf(stderr, ##args);        \
-       } while (0)
-
-#define log_info(args...)      fprintf(f_out, ##args)
-
-FILE *get_f_out(void);
-FILE *get_f_err(void);
-
 struct ioengine_ops {
        struct list_head list;
        char name[16];
@@ -933,17 +935,17 @@ struct ioengine_ops {
        int (*prep)(struct thread_data *, struct io_u *);
        int (*queue)(struct thread_data *, struct io_u *);
        int (*commit)(struct thread_data *);
-       int (*getevents)(struct thread_data *, int, int, struct timespec *);
+       int (*getevents)(struct thread_data *, unsigned int, unsigned int, struct timespec *);
        struct io_u *(*event)(struct thread_data *, int);
        int (*cancel)(struct thread_data *, struct io_u *);
        void (*cleanup)(struct thread_data *);
        int (*open_file)(struct thread_data *, struct fio_file *);
-       void (*close_file)(struct thread_data *, struct fio_file *);
+       int (*close_file)(struct thread_data *, struct fio_file *);
        void *data;
        void *dlhandle;
 };
 
-#define FIO_IOOPS_VERSION      7
+#define FIO_IOOPS_VERSION      9
 
 extern struct ioengine_ops *load_ioengine(struct thread_data *, const char *);
 extern void register_ioengine(struct ioengine_ops *);
@@ -960,7 +962,10 @@ extern void close_ioengine(struct thread_data *);
 #define for_each_td(td, i)     \
        for ((i) = 0, (td) = &threads[0]; (i) < (int) thread_number; (i)++, (td)++)
 #define for_each_file(td, f, i)        \
-       for ((i) = 0, (f) = &(td)->files[0]; (i) < (td)->o.nr_files; (i)++, (f)++)
+       if ((td)->files_index)                                          \
+               for ((i) = 0, (f) = (td)->files[0];                     \
+                (i) < (td)->o.nr_files && ((f) = (td)->files[i]) != NULL; \
+                (i)++)
 
 #define fio_assert(td, cond)   do {    \
        if (!(cond)) {                  \
@@ -978,4 +983,22 @@ static inline void clear_error(struct thread_data *td)
        td->verror[0] = '\0';
 }
 
+#ifdef FIO_INC_DEBUG
+static inline void dprint_io_u(struct io_u *io_u, const char *p)
+{
+       struct fio_file *f = io_u->file;
+
+       dprint(FD_IO, "%s: io_u %p: off=%llu/len=%lu/ddir=%d", p, io_u,
+                                       io_u->offset, io_u->buflen, io_u->ddir);
+       if (fio_debug & (1 << FD_IO)) {
+               if (f)
+                       log_info("/%s", f->file_name);
+
+               log_info("\n");
+       }
+}
+#else
+#define dprint_io_u(io_u, p)
+#endif
+
 #endif