#include "blktrace.h"
-#define VALID_SPECS "BCDFGMPQRSTU"
+#define VALID_SPECS "ABCDFGMPQRSTUWX"
#define HEADER "%D %2c %8s %5T.%9t %5p %2a %3d "
rwbs[i] = '\0';
}
+static inline int pdu_rest_is_zero(unsigned char *pdu, int len)
+{
+ static char zero[4096];
+
+ return !memcmp(pdu, zero, len);
+}
+
static char *dump_pdu(unsigned char *pdu_buf, int pdu_len)
{
static char p[4096];
len += sprintf(p + len, " ");
len += sprintf(p + len, "%02x", pdu_buf[i]);
+
+ /*
+ * usually dump for cdb dumps where we can see lots of
+ * zeroes, stop when the rest is just zeroes and indicate
+ * so with a .. appended
+ */
+ if (!pdu_buf[i] && pdu_rest_is_zero(pdu_buf + i, pdu_len - i)) {
+ sprintf(p + len, " ..");
+ break;
+ }
}
return p;
}
+#define pdu_start(t) (((void *) (t) + sizeof(struct blk_io_trace)))
+
static unsigned int get_pdu_int(struct blk_io_trace *t)
{
- __u64 *val = (__u64 *) ((char *) t + sizeof(*t));
+ __u64 *val = pdu_start(t);
return be64_to_cpu(*val);
}
+static void get_pdu_remap(struct blk_io_trace *t, struct blk_io_trace_remap *r)
+{
+ struct blk_io_trace_remap *__r = pdu_start(t);
+ __u64 sector = __r->sector;
+
+ r->device = be32_to_cpu(__r->device);
+ r->sector = be64_to_cpu(sector);
+}
+
static void print_field(char *act, struct per_cpu_info *pci,
struct blk_io_trace *t, unsigned long long elapsed,
int pdu_len, unsigned char *pdu_buf, char field,
case 'c':
fprintf(ofp, strcat(format, "d"), pci->cpu);
break;
- case 'C':
- fprintf(ofp, strcat(format, "s"), t->comm);
+ case 'C': {
+ char *name = find_process_name(t->pid);
+
+ fprintf(ofp, strcat(format, "s"), name);
break;
+ }
case 'd': {
char rwbs[4];
fprintf(ofp, strcat(format, "d"), MINOR(t->device));
break;
case 'n':
- fprintf(ofp, strcat(format, "u"), t->bytes >> 9);
+ fprintf(ofp, strcat(format, "u"), t_sec(t));
break;
case 'N':
fprintf(ofp, strcat(format, "u"), t->bytes);
int pdu_len, unsigned char *pdu_buf)
{
char rwbs[4];
+ char *name;
fill_rwbs(rwbs, t);
(int) SECONDS(t->time), (unsigned long) NANO_SECONDS(t->time),
t->pid, act, rwbs);
+ name = find_process_name(t->pid);
+
switch (act[0]) {
+ case 'R': /* Requeue */
case 'C': /* Complete */
if (t->action & BLK_TC_ACT(BLK_TC_PC)) {
char *p = dump_pdu(pdu_buf, pdu_len);
if (elapsed != -1ULL) {
fprintf(ofp, "%llu + %u (%8llu) [%d]\n",
(unsigned long long) t->sector,
- t->bytes >> 9, elapsed, t->error);
+ t_sec(t), elapsed, t->error);
} else {
fprintf(ofp, "%llu + %u [%d]\n",
(unsigned long long) t->sector,
- t->bytes >> 9, t->error);
+ t_sec(t), t->error);
}
}
break;
p = dump_pdu(pdu_buf, pdu_len);
if (p)
fprintf(ofp, "(%s) ", p);
- fprintf(ofp, "[%s]\n", t->comm);
+ fprintf(ofp, "[%s]\n", name);
} else {
if (elapsed != -1ULL) {
fprintf(ofp, "%llu + %u (%8llu) [%s]\n",
(unsigned long long) t->sector,
- t->bytes >> 9, elapsed, t->comm);
+ t_sec(t), elapsed, name);
} else {
fprintf(ofp, "%llu + %u [%s]\n",
(unsigned long long) t->sector,
- t->bytes >> 9, t->comm);
+ t_sec(t), name);
}
}
break;
case 'G': /* Get request */
case 'S': /* Sleep request */
fprintf(ofp, "%llu + %u [%s]\n", (unsigned long long) t->sector,
- t->bytes >> 9, t->comm);
+ t_sec(t), name);
break;
case 'P': /* Plug */
- fprintf(ofp, "[%s]\n", t->comm);
+ fprintf(ofp, "[%s]\n", name);
break;
case 'U': /* Unplug IO */
- case 'T': { /* Unplug timer */
- fprintf(ofp, "[%s] %u\n", t->comm, get_pdu_int(t));
+ case 'T': /* Unplug timer */
+ fprintf(ofp, "[%s] %u\n", name, get_pdu_int(t));
break;
- }
+ case 'A': { /* remap */
+ struct blk_io_trace_remap r;
+
+ get_pdu_remap(t, &r);
+ fprintf(ofp, "%llu + %u <- (%d,%d) %llu\n",
+ (unsigned long long) r.sector, t_sec(t),
+ MAJOR(r.device), MINOR(r.device),
+ (unsigned long long) t->sector);
+ break;
+ }
+
case 'X': /* Split */
fprintf(ofp, "%llu / %u [%s]\n", (unsigned long long) t->sector,
- get_pdu_int(t), t->comm);
+ get_pdu_int(t), name);
break;
default: