1#ifndef BLKTRACE_H 2#define BLKTRACE_H 3 4#include <stdio.h> 5#include <byteswap.h> 6#include <endian.h> 7 8#include "blktrace_api.h" 9#include "rbtree.h" 10 11#define MINORBITS 20 12#define MINORMASK ((1U << MINORBITS) - 1) 13#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) 14#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) 15 16#define SECONDS(x) ((unsigned long long)(x) / 1000000000) 17#define NANO_SECONDS(x) ((unsigned long long)(x) % 1000000000) 18#define DOUBLE_TO_NANO_ULL(d) ((unsigned long long)((d) * 1000000000)) 19 20#define min(a, b) ((a) < (b) ? (a) : (b)) 21#define max(a, b) ((a) > (b) ? (a) : (b)) 22 23#define t_sec(t) ((t)->bytes >> 9) 24#define t_kb(t) ((t)->bytes >> 10) 25 26typedef __u32 u32; 27typedef __u8 u8; 28 29struct io_stats { 30 unsigned long qreads, qwrites, creads, cwrites, mreads, mwrites; 31 unsigned long ireads, iwrites, rrqueue, wrqueue; 32 unsigned long long qread_kb, qwrite_kb, cread_kb, cwrite_kb; 33 unsigned long long iread_kb, iwrite_kb; 34 unsigned long long mread_kb, mwrite_kb; 35 unsigned long qreads_pc, qwrites_pc, ireads_pc, iwrites_pc; 36 unsigned long rrqueue_pc, wrqueue_pc, creads_pc, cwrites_pc; 37 unsigned long long qread_kb_pc, qwrite_kb_pc, iread_kb_pc, iwrite_kb_pc; 38 unsigned long io_unplugs, timer_unplugs; 39}; 40 41struct per_cpu_info { 42 unsigned int cpu; 43 unsigned int nelems; 44 45 int fd; 46 int fdblock; 47 char fname[128]; 48 49 struct io_stats io_stats; 50 51 struct rb_root rb_last; 52 unsigned long rb_last_entries; 53 unsigned long last_sequence; 54 unsigned long smallest_seq_read; 55 56 struct skip_info *skips_head; 57 struct skip_info *skips_tail; 58}; 59 60extern FILE *ofp; 61extern int data_is_native; 62extern struct timespec abs_start_time; 63 64#define CHECK_MAGIC(t) (((t)->magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) 65#define SUPPORTED_VERSION (0x07) 66 67#define __bswap_16 bswap_16 68#define __bswap_32 bswap_32 69#define __bswap_64 bswap_64 70 71#if __BYTE_ORDER == __LITTLE_ENDIAN 72#define be16_to_cpu(x) __bswap_16(x) 73#define be32_to_cpu(x) __bswap_32(x) 74#define be64_to_cpu(x) __bswap_64(x) 75#define cpu_to_be16(x) __bswap_16(x) 76#define cpu_to_be32(x) __bswap_32(x) 77#define cpu_to_be64(x) __bswap_64(x) 78#elif __BYTE_ORDER == __BIG_ENDIAN 79#define be16_to_cpu(x) (x) 80#define be32_to_cpu(x) (x) 81#define be64_to_cpu(x) (x) 82#define cpu_to_be16(x) (x) 83#define cpu_to_be32(x) (x) 84#define cpu_to_be64(x) (x) 85#else 86#error "Bad arch" 87#endif 88 89static inline int verify_trace(struct blk_io_trace *t) 90{ 91 if (!CHECK_MAGIC(t)) { 92 fprintf(stderr, "bad trace magic %x\n", t->magic); 93 return 1; 94 } 95 if ((t->magic & 0xff) != SUPPORTED_VERSION) { 96 fprintf(stderr, "unsupported trace version %x\n", 97 t->magic & 0xff); 98 return 1; 99 } 100 101 return 0; 102} 103 104static inline void trace_to_cpu(struct blk_io_trace *t) 105{ 106 if (data_is_native) 107 return; 108 109 t->magic = be32_to_cpu(t->magic); 110 t->sequence = be32_to_cpu(t->sequence); 111 t->time = be64_to_cpu(t->time); 112 t->sector = be64_to_cpu(t->sector); 113 t->bytes = be32_to_cpu(t->bytes); 114 t->action = be32_to_cpu(t->action); 115 t->pid = be32_to_cpu(t->pid); 116 t->device = be32_to_cpu(t->device); 117 t->cpu = be16_to_cpu(t->cpu); 118 t->error = be16_to_cpu(t->error); 119 t->pdu_len = be16_to_cpu(t->pdu_len); 120} 121 122/* 123 * check whether data is native or not 124 */ 125static inline int check_data_endianness(u32 magic) 126{ 127 if ((magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { 128 data_is_native = 1; 129 return 0; 130 } 131 132 magic = __bswap_32(magic); 133 if ((magic & 0xffffff00) == BLK_IO_TRACE_MAGIC) { 134 data_is_native = 0; 135 return 0; 136 } 137 138 return 1; 139} 140 141extern void set_all_format_specs(char *); 142extern int add_format_spec(char *); 143extern void process_fmt(char *, struct per_cpu_info *, struct blk_io_trace *, 144 unsigned long long, int, unsigned char *); 145extern int valid_act_opt(int); 146extern int find_mask_map(char *); 147extern char *find_process_name(pid_t); 148 149#endif 150