blkparse: Avoid segfault for wrong cpu number.
[blktrace.git] / btt / trace_remap.c
index 54a26e3edb8875802729028a8ec1d22ee29826a1..560ae2b3cceb4ea1663d847bd31b5defbaaedff1 100644 (file)
  */
 #include "globals.h"
 
-void run_remap(struct io *a_iop, struct io *c_iop, void *param)
+static inline void cvt_pdu_remap(struct blk_io_trace_remap *rp)
 {
-       struct bilink *blp = blp, *blp2;
-       struct list_head *rmhd = param;
-       struct io *q_iop, *l_iop = bilink_first_down(a_iop, &blp);
-
-       ASSERT(l_iop);
-       q_iop = bilink_first_down(l_iop, &blp2);
-       if (q_iop) {
-               run_queue(q_iop, c_iop, rmhd);
-               biunlink(blp2);
-       }
-
-       dump_iop2(a_iop, l_iop);
-
-       biunlink(blp);
-       list_add_tail(&l_iop->f_head, rmhd);
-       list_add_tail(&a_iop->f_head, rmhd);
+       rp->device_from = be32_to_cpu(rp->device_from);
+       rp->device_to   = be32_to_cpu(rp->device_to);
+       rp->sector_from = be64_to_cpu(rp->sector_from);
 }
 
-int ready_dev_remap(struct io *l_iop, struct io *c_iop)
+/*
+ * q_iop == volume device
+ * a_iop == underlying device
+ */
+void trace_remap(struct io *a_iop)
 {
        struct io *q_iop;
+       struct d_info *q_dip;
+       struct blk_io_trace_remap *rp;
 
-       if (!list_empty(&l_iop->down_list)) 
-               return 1;
+       if (ignore_remaps)
+               goto out;
 
-       q_iop = dip_find_sec(l_iop->dip, IOP_Q, l_iop->t.sector);
-       if (!q_iop || !ready_queue(q_iop, c_iop))
-               return 0;
-
-       ASSERT(l_iop->t.bytes <= q_iop->t.bytes);
-       update_q2a(q_iop, tdelta(q_iop, l_iop));
-       bilink(q_iop, l_iop);
-
-       q_iop->bytes_left -= l_iop->t.bytes;
-       if (q_iop->bytes_left == 0)
-               dip_rem(q_iop);
-       return 1;
-}
-
-int ready_self_remap(struct io *l_iop)
-{
-       struct io *a_iop = dip_find_sec(l_iop->dip, IOP_A, l_iop->t.sector);
-
-       if (a_iop) {
-               update_q2a(a_iop, tdelta(a_iop, l_iop));
-               dip_rem(a_iop);
-       }
-
-       return 1;
-}
-
-int ready_remap(struct io *a_iop, struct io *c_iop)
-{
-       struct io *l_iop = bilink_first_down(a_iop, NULL);
-
-       ASSERT(l_iop);
-       if (remapper_dev(l_iop->t.device))
-               return ready_dev_remap(l_iop, c_iop);
-       else
-               return ready_self_remap(l_iop);
-}
-
-void trace_remap(struct io *a_iop)
-{
-       struct io *l_iop;
-       struct blk_io_trace_remap *rp = a_iop->pdu;
+       rp = a_iop->pdu;
+       cvt_pdu_remap(rp);
 
-       a_iop->t.device = be32_to_cpu(rp->device_from);
-       if (!io_setup(a_iop, IOP_A)) {
-               io_release(a_iop);
-               return;
-       }
+       if (!io_setup(a_iop, IOP_A))
+               goto out;
 
-       l_iop = io_alloc();
-       memcpy(&l_iop->t, &a_iop->t, sizeof(a_iop->t));
-       if (l_iop->t.pdu_len) {
-               l_iop->pdu = malloc(l_iop->t.pdu_len);
-               memcpy(l_iop->pdu, a_iop->pdu, l_iop->t.pdu_len);
-       }
+       q_dip = __dip_find(rp->device_from);
+       if (!q_dip)
+               goto out;
 
-       l_iop->t.device = be32_to_cpu(rp->device);
-       l_iop->t.sector = be64_to_cpu(rp->sector);
-       if (!io_setup(l_iop, IOP_L)) {
-               io_release(l_iop);
-               io_release(a_iop);
-               return;
-       }
+       q_iop = dip_find_sec(q_dip, IOP_Q, rp->sector_from);
+       if (q_iop)
+               update_q2a(q_iop, tdelta(q_iop->t.time, a_iop->t.time));
 
-       bilink(l_iop, a_iop);
+out:
+       io_release(a_iop);
 }