tracing/kprobes: Fix field creation's bad error handling
[safe/jmp/linux-2.6] / kernel / trace / blktrace.c
index 1090b0a..d9d6206 100644 (file)
@@ -65,13 +65,15 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action,
 {
        struct blk_io_trace *t;
        struct ring_buffer_event *event = NULL;
+       struct ring_buffer *buffer = NULL;
        int pc = 0;
        int cpu = smp_processor_id();
        bool blk_tracer = blk_tracer_enabled;
 
        if (blk_tracer) {
+               buffer = blk_tr->buffer;
                pc = preempt_count();
-               event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+               event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + len,
                                                  0, pc);
                if (!event)
@@ -96,7 +98,7 @@ record_it:
                memcpy((void *) t + sizeof(*t), data, len);
 
                if (blk_tracer)
-                       trace_buffer_unlock_commit(blk_tr, event, 0, pc);
+                       trace_buffer_unlock_commit(buffer, event, 0, pc);
        }
 }
 
@@ -179,6 +181,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
 {
        struct task_struct *tsk = current;
        struct ring_buffer_event *event = NULL;
+       struct ring_buffer *buffer = NULL;
        struct blk_io_trace *t;
        unsigned long flags = 0;
        unsigned long *sequence;
@@ -204,8 +207,9 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
        if (blk_tracer) {
                tracing_record_cmdline(current);
 
+               buffer = blk_tr->buffer;
                pc = preempt_count();
-               event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+               event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + pdu_len,
                                                  0, pc);
                if (!event)
@@ -252,7 +256,7 @@ record_it:
                        memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
 
                if (blk_tracer) {
-                       trace_buffer_unlock_commit(blk_tr, event, 0, pc);
+                       trace_buffer_unlock_commit(buffer, event, 0, pc);
                        return;
                }
        }
@@ -267,8 +271,8 @@ static void blk_trace_free(struct blk_trace *bt)
 {
        debugfs_remove(bt->msg_file);
        debugfs_remove(bt->dropped_file);
-       debugfs_remove(bt->dir);
        relay_close(bt->rchan);
+       debugfs_remove(bt->dir);
        free_percpu(bt->sequence);
        free_percpu(bt->msg_data);
        kfree(bt);
@@ -378,18 +382,8 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
 
 static int blk_remove_buf_file_callback(struct dentry *dentry)
 {
-       struct dentry *parent = dentry->d_parent;
        debugfs_remove(dentry);
 
-       /*
-       * this will fail for all but the last file, but that is ok. what we
-       * care about is the top level buts->name directory going away, when
-       * the last trace file is gone. Then we don't have to rmdir() that
-       * manually on trace stop, so it nicely solves the issue with
-       * force killing of running traces.
-       */
-
-       debugfs_remove(parent);
        return 0;
 }
 
@@ -862,6 +856,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
 }
 
 /**
+ * blk_add_trace_rq_remap - Add a trace for a request-remap operation
+ * @q:         queue the io is for
+ * @rq:                the source request
+ * @dev:       target device
+ * @from:      source sector
+ *
+ * Description:
+ *     Device mapper remaps request to other devices.
+ *     Add a trace for that action.
+ *
+ **/
+static void blk_add_trace_rq_remap(struct request_queue *q,
+                                  struct request *rq, dev_t dev,
+                                  sector_t from)
+{
+       struct blk_trace *bt = q->blk_trace;
+       struct blk_io_trace_remap r;
+
+       if (likely(!bt))
+               return;
+
+       r.device_from = cpu_to_be32(dev);
+       r.device_to   = cpu_to_be32(disk_devt(rq->rq_disk));
+       r.sector_from = cpu_to_be64(from);
+
+       __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+                       rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors,
+                       sizeof(r), &r);
+}
+
+/**
  * blk_add_driver_data - Add binary message with driver-specific data
  * @q:         queue the io is for
  * @rq:                io request
@@ -928,10 +953,13 @@ static void blk_register_tracepoints(void)
        WARN_ON(ret);
        ret = register_trace_block_remap(blk_add_trace_remap);
        WARN_ON(ret);
+       ret = register_trace_block_rq_remap(blk_add_trace_rq_remap);
+       WARN_ON(ret);
 }
 
 static void blk_unregister_tracepoints(void)
 {
+       unregister_trace_block_rq_remap(blk_add_trace_rq_remap);
        unregister_trace_block_remap(blk_add_trace_remap);
        unregister_trace_block_split(blk_add_trace_split);
        unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
@@ -1663,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev)
        return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
 }
 
+void blk_trace_remove_sysfs(struct device *dev)
+{
+       sysfs_remove_group(&dev->kobj, &blk_trace_attr_group);
+}
+
 #endif /* CONFIG_BLK_DEV_IO_TRACE */
 
 #ifdef CONFIG_EVENT_TRACING