block: use bio_has_data() in the IO completion path
[deliverable/linux.git] / block / blk-core.c
index 1905aaba49fb2cd1d999bce222949c938fa3e9e5..b5776c1fd52aca777ae9dc185a936121caf0e8a9 100644 (file)
@@ -143,6 +143,10 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
 
                bio->bi_size -= nbytes;
                bio->bi_sector += (nbytes >> 9);
+
+               if (bio_integrity(bio))
+                       bio_integrity_advance(bio, nbytes);
+
                if (bio->bi_size == 0)
                        bio_endio(bio, error);
        } else {
@@ -201,14 +205,31 @@ void blk_plug_device(struct request_queue *q)
        if (blk_queue_stopped(q))
                return;
 
-       if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
-               __set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags);
+       if (!queue_flag_test_and_set(QUEUE_FLAG_PLUGGED, q)) {
                mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
                blk_add_trace_generic(q, NULL, 0, BLK_TA_PLUG);
        }
 }
 EXPORT_SYMBOL(blk_plug_device);
 
+/**
+ * blk_plug_device_unlocked - plug a device without queue lock held
+ * @q:    The &struct request_queue to plug
+ *
+ * Description:
+ *   Like @blk_plug_device(), but grabs the queue lock and disables
+ *   interrupts.
+ **/
+void blk_plug_device_unlocked(struct request_queue *q)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(q->queue_lock, flags);
+       blk_plug_device(q);
+       spin_unlock_irqrestore(q->queue_lock, flags);
+}
+EXPORT_SYMBOL(blk_plug_device_unlocked);
+
 /*
  * remove the queue from the plugged list, if present. called with
  * queue lock held and interrupts disabled.
@@ -217,10 +238,9 @@ int blk_remove_plug(struct request_queue *q)
 {
        WARN_ON(!irqs_disabled());
 
-       if (!test_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
+       if (!queue_flag_test_and_clear(QUEUE_FLAG_PLUGGED, q))
                return 0;
 
-       queue_flag_clear(QUEUE_FLAG_PLUGGED, q);
        del_timer(&q->unplug_timer);
        return 1;
 }
@@ -324,8 +344,7 @@ void blk_start_queue(struct request_queue *q)
         * one level of recursion is ok and is much faster than kicking
         * the unplug handling
         */
-       if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
-               queue_flag_set(QUEUE_FLAG_REENTER, q);
+       if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
                q->request_fn(q);
                queue_flag_clear(QUEUE_FLAG_REENTER, q);
        } else {
@@ -390,8 +409,7 @@ void __blk_run_queue(struct request_queue *q)
         * handling reinvoke the handler shortly if we already got there.
         */
        if (!elv_queue_empty(q)) {
-               if (!test_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
-                       queue_flag_set(QUEUE_FLAG_REENTER, q);
+               if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) {
                        q->request_fn(q);
                        queue_flag_clear(QUEUE_FLAG_REENTER, q);
                } else {
@@ -564,6 +582,8 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
 
        q->sg_reserved_size = INT_MAX;
 
+       blk_set_cmd_filter_defaults(&q->cmd_filter);
+
        /*
         * all done
         */
@@ -1042,15 +1062,9 @@ void blk_put_request(struct request *req)
        unsigned long flags;
        struct request_queue *q = req->q;
 
-       /*
-        * Gee, IDE calls in w/ NULL q.  Fix IDE and remove the
-        * following if (q) test.
-        */
-       if (q) {
-               spin_lock_irqsave(q->queue_lock, flags);
-               __blk_put_request(q, req);
-               spin_unlock_irqrestore(q->queue_lock, flags);
-       }
+       spin_lock_irqsave(q->queue_lock, flags);
+       __blk_put_request(q, req);
+       spin_unlock_irqrestore(q->queue_lock, flags);
 }
 EXPORT_SYMBOL(blk_put_request);
 
@@ -1381,6 +1395,9 @@ end_io:
                 */
                blk_partition_remap(bio);
 
+               if (bio_integrity_enabled(bio) && bio_integrity_prep(bio))
+                       goto end_io;
+
                if (old_sector != -1)
                        blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
                                            old_sector);
@@ -1473,10 +1490,7 @@ void submit_bio(int rw, struct bio *bio)
         * If it's a regular read/write or a barrier with data attached,
         * go through the normal accounting stuff before submission.
         */
-       if (!bio_empty_barrier(bio)) {
-
-               BIO_BUG_ON(!bio->bi_size);
-               BIO_BUG_ON(!bio->bi_io_vec);
+       if (bio_has_data(bio)) {
 
                if (rw & WRITE) {
                        count_vm_events(PGPGOUT, count);
@@ -1871,7 +1885,7 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes,
        struct request_queue *q = rq->q;
        unsigned long flags = 0UL;
 
-       if (blk_fs_request(rq) || blk_pc_request(rq)) {
+       if (bio_has_data(rq->bio)) {
                if (__end_that_request_first(rq, error, nr_bytes))
                        return 1;
 
@@ -1929,10 +1943,9 @@ EXPORT_SYMBOL_GPL(blk_end_request);
  **/
 int __blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
-       if (blk_fs_request(rq) || blk_pc_request(rq)) {
-               if (__end_that_request_first(rq, error, nr_bytes))
-                       return 1;
-       }
+       if (bio_has_data(rq->bio) &&
+           __end_that_request_first(rq, error, nr_bytes))
+               return 1;
 
        add_disk_randomness(rq->rq_disk);
 
@@ -2045,7 +2058,7 @@ int __init blk_dev_init(void)
        for_each_possible_cpu(i)
                INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i));
 
-       open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
+       open_softirq(BLOCK_SOFTIRQ, blk_done_softirq);
        register_hotcpu_notifier(&blk_cpu_notifier);
 
        return 0;
This page took 0.025227 seconds and 5 git commands to generate.