Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
[cascardo/linux.git] / block / ll_rw_blk.c
index 31512cd..a541b42 100644 (file)
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
+#include <linux/task_io_accounting_ops.h>
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
 #include <linux/blktrace_api.h>
+#include <linux/fault-inject.h>
 
 /*
  * for max sense size
@@ -127,13 +129,6 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
 }
 EXPORT_SYMBOL(blk_get_backing_dev_info);
 
-void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data)
-{
-       q->activity_fn = fn;
-       q->activity_data = data;
-}
-EXPORT_SYMBOL(blk_queue_activity_fn);
-
 /**
  * blk_queue_prep_rq - set a prepare_request function for queue
  * @q:         queue
@@ -236,8 +231,6 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
         * by default assume old behaviour and bounce for any highmem page
         */
        blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
-
-       blk_queue_activity_fn(q, NULL, NULL);
 }
 
 EXPORT_SYMBOL(blk_queue_make_request);
@@ -2694,9 +2687,6 @@ static inline void add_request(request_queue_t * q, struct request * req)
 {
        drive_stat_acct(req, req->nr_sectors, 1);
 
-       if (q->activity_fn)
-               q->activity_fn(q->activity_data, rq_data_dir(req));
-
        /*
         * elevator indicated where it wants this request to be
         * inserted at elevator_merge time
@@ -3056,6 +3046,42 @@ static void handle_bad_sector(struct bio *bio)
        set_bit(BIO_EOF, &bio->bi_flags);
 }
 
+#ifdef CONFIG_FAIL_MAKE_REQUEST
+
+static DECLARE_FAULT_ATTR(fail_make_request);
+
+static int __init setup_fail_make_request(char *str)
+{
+       return setup_fault_attr(&fail_make_request, str);
+}
+__setup("fail_make_request=", setup_fail_make_request);
+
+static int should_fail_request(struct bio *bio)
+{
+       if ((bio->bi_bdev->bd_disk->flags & GENHD_FL_FAIL) ||
+           (bio->bi_bdev->bd_part && bio->bi_bdev->bd_part->make_it_fail))
+               return should_fail(&fail_make_request, bio->bi_size);
+
+       return 0;
+}
+
+static int __init fail_make_request_debugfs(void)
+{
+       return init_fault_attr_dentries(&fail_make_request,
+                                       "fail_make_request");
+}
+
+late_initcall(fail_make_request_debugfs);
+
+#else /* CONFIG_FAIL_MAKE_REQUEST */
+
+static inline int should_fail_request(struct bio *bio)
+{
+       return 0;
+}
+
+#endif /* CONFIG_FAIL_MAKE_REQUEST */
+
 /**
  * generic_make_request: hand a buffer to its device driver for I/O
  * @bio:  The bio describing the location in memory and on the device.
@@ -3141,6 +3167,9 @@ end_io:
                if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
                        goto end_io;
 
+               if (should_fail_request(bio))
+                       goto end_io;
+
                /*
                 * If this device has partitions, remap block n
                 * of partition p to block n+start(p) of the disk.
@@ -3195,10 +3224,12 @@ void submit_bio(int rw, struct bio *bio)
        BIO_BUG_ON(!bio->bi_size);
        BIO_BUG_ON(!bio->bi_io_vec);
        bio->bi_rw |= rw;
-       if (rw & WRITE)
+       if (rw & WRITE) {
                count_vm_events(PGPGOUT, count);
-       else
+       } else {
+               task_io_account_read(bio->bi_size);
                count_vm_events(PGPGIN, count);
+       }
 
        if (unlikely(block_dump)) {
                char b[BDEVNAME_SIZE];