Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / kernel / trace / blktrace.c
index 16fc34a..fa85588 100644 (file)
@@ -296,7 +296,7 @@ static void blk_trace_cleanup(struct blk_trace *bt)
                blk_unregister_tracepoints();
 }
 
-int blk_trace_remove(struct request_queue *q)
+static int __blk_trace_remove(struct request_queue *q)
 {
        struct blk_trace *bt;
 
@@ -309,6 +309,17 @@ int blk_trace_remove(struct request_queue *q)
 
        return 0;
 }
+
+int blk_trace_remove(struct request_queue *q)
+{
+       int ret;
+
+       mutex_lock(&q->blk_trace_mutex);
+       ret = __blk_trace_remove(q);
+       mutex_unlock(&q->blk_trace_mutex);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(blk_trace_remove);
 
 static int blk_dropped_open(struct inode *inode, struct file *filp)
@@ -402,7 +413,7 @@ static int blk_remove_buf_file_callback(struct dentry *dentry)
 
 static struct dentry *blk_create_buf_file_callback(const char *filename,
                                                   struct dentry *parent,
-                                                  int mode,
+                                                  umode_t mode,
                                                   struct rchan_buf *buf,
                                                   int *is_global)
 {
@@ -538,9 +549,8 @@ err:
        return ret;
 }
 
-int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
-                   struct block_device *bdev,
-                   char __user *arg)
+static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+                            struct block_device *bdev, char __user *arg)
 {
        struct blk_user_trace_setup buts;
        int ret;
@@ -559,6 +569,19 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
        }
        return 0;
 }
+
+int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+                   struct block_device *bdev,
+                   char __user *arg)
+{
+       int ret;
+
+       mutex_lock(&q->blk_trace_mutex);
+       ret = __blk_trace_setup(q, name, dev, bdev, arg);
+       mutex_unlock(&q->blk_trace_mutex);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(blk_trace_setup);
 
 #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
@@ -596,7 +619,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name,
 }
 #endif
 
-int blk_trace_startstop(struct request_queue *q, int start)
+static int __blk_trace_startstop(struct request_queue *q, int start)
 {
        int ret;
        struct blk_trace *bt = q->blk_trace;
@@ -629,8 +652,25 @@ int blk_trace_startstop(struct request_queue *q, int start)
 
        return ret;
 }
+
+int blk_trace_startstop(struct request_queue *q, int start)
+{
+       int ret;
+
+       mutex_lock(&q->blk_trace_mutex);
+       ret = __blk_trace_startstop(q, start);
+       mutex_unlock(&q->blk_trace_mutex);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(blk_trace_startstop);
 
+/*
+ * When reading or writing the blktrace sysfs files, the references to the
+ * opened sysfs or device files should prevent the underlying block device
+ * from being removed. So no further delete protection is really needed.
+ */
+
 /**
  * blk_trace_ioctl: - handle the ioctls associated with tracing
  * @bdev:      the block device
@@ -648,12 +688,12 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
        if (!q)
                return -ENXIO;
 
-       mutex_lock(&bdev->bd_mutex);
+       mutex_lock(&q->blk_trace_mutex);
 
        switch (cmd) {
        case BLKTRACESETUP:
                bdevname(bdev, b);
-               ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
+               ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
                break;
 #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
        case BLKTRACESETUP32:
@@ -664,17 +704,17 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
        case BLKTRACESTART:
                start = 1;
        case BLKTRACESTOP:
-               ret = blk_trace_startstop(q, start);
+               ret = __blk_trace_startstop(q, start);
                break;
        case BLKTRACETEARDOWN:
-               ret = blk_trace_remove(q);
+               ret = __blk_trace_remove(q);
                break;
        default:
                ret = -ENOTTY;
                break;
        }
 
-       mutex_unlock(&bdev->bd_mutex);
+       mutex_unlock(&q->blk_trace_mutex);
        return ret;
 }
 
@@ -685,10 +725,14 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
  **/
 void blk_trace_shutdown(struct request_queue *q)
 {
+       mutex_lock(&q->blk_trace_mutex);
+
        if (q->blk_trace) {
-               blk_trace_startstop(q, 0);
-               blk_trace_remove(q);
+               __blk_trace_startstop(q, 0);
+               __blk_trace_remove(q);
        }
+
+       mutex_unlock(&q->blk_trace_mutex);
 }
 
 /*
@@ -699,6 +743,7 @@ void blk_trace_shutdown(struct request_queue *q)
  * blk_add_trace_rq - Add a trace for a request oriented action
  * @q:         queue the io is for
  * @rq:                the source request
+ * @nr_bytes:  number of completed bytes
  * @what:      the action
  *
  * Description:
@@ -706,7 +751,7 @@ void blk_trace_shutdown(struct request_queue *q)
  *
  **/
 static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
-                            u32 what)
+                            unsigned int nr_bytes, u32 what)
 {
        struct blk_trace *bt = q->blk_trace;
 
@@ -715,11 +760,11 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
 
        if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                what |= BLK_TC_ACT(BLK_TC_PC);
-               __blk_add_trace(bt, 0, blk_rq_bytes(rq), rq->cmd_flags,
+               __blk_add_trace(bt, 0, nr_bytes, rq->cmd_flags,
                                what, rq->errors, rq->cmd_len, rq->cmd);
        } else  {
                what |= BLK_TC_ACT(BLK_TC_FS);
-               __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+               __blk_add_trace(bt, blk_rq_pos(rq), nr_bytes,
                                rq->cmd_flags, what, rq->errors, 0, NULL);
        }
 }
@@ -727,33 +772,34 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
 static void blk_add_trace_rq_abort(void *ignore,
                                   struct request_queue *q, struct request *rq)
 {
-       blk_add_trace_rq(q, rq, BLK_TA_ABORT);
+       blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_ABORT);
 }
 
 static void blk_add_trace_rq_insert(void *ignore,
                                    struct request_queue *q, struct request *rq)
 {
-       blk_add_trace_rq(q, rq, BLK_TA_INSERT);
+       blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_INSERT);
 }
 
 static void blk_add_trace_rq_issue(void *ignore,
                                   struct request_queue *q, struct request *rq)
 {
-       blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
+       blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_ISSUE);
 }
 
 static void blk_add_trace_rq_requeue(void *ignore,
                                     struct request_queue *q,
                                     struct request *rq)
 {
-       blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
+       blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_REQUEUE);
 }
 
 static void blk_add_trace_rq_complete(void *ignore,
                                      struct request_queue *q,
-                                     struct request *rq)
+                                     struct request *rq,
+                                     unsigned int nr_bytes)
 {
-       blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
+       blk_add_trace_rq(q, rq, nr_bytes, BLK_TA_COMPLETE);
 }
 
 /**
@@ -1658,7 +1704,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
        if (q == NULL)
                goto out_bdput;
 
-       mutex_lock(&bdev->bd_mutex);
+       mutex_lock(&q->blk_trace_mutex);
 
        if (attr == &dev_attr_enable) {
                ret = sprintf(buf, "%u\n", !!q->blk_trace);
@@ -1677,7 +1723,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
                ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba);
 
 out_unlock_bdev:
-       mutex_unlock(&bdev->bd_mutex);
+       mutex_unlock(&q->blk_trace_mutex);
 out_bdput:
        bdput(bdev);
 out:
@@ -1719,7 +1765,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
        if (q == NULL)
                goto out_bdput;
 
-       mutex_lock(&bdev->bd_mutex);
+       mutex_lock(&q->blk_trace_mutex);
 
        if (attr == &dev_attr_enable) {
                if (value)
@@ -1745,7 +1791,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
        }
 
 out_unlock_bdev:
-       mutex_unlock(&bdev->bd_mutex);
+       mutex_unlock(&q->blk_trace_mutex);
 out_bdput:
        bdput(bdev);
 out: