block: fix rq-qos breakage from skipping rq_qos_done_bio()
[linux-2.6-microblaze.git] / block / blk-rq-qos.h
index 3cfbc86..6826700 100644 (file)
@@ -177,20 +177,20 @@ static inline void rq_qos_requeue(struct request_queue *q, struct request *rq)
                __rq_qos_requeue(q->rq_qos, rq);
 }
 
-static inline void rq_qos_done_bio(struct request_queue *q, struct bio *bio)
+static inline void rq_qos_done_bio(struct bio *bio)
 {
-       if (q->rq_qos)
-               __rq_qos_done_bio(q->rq_qos, bio);
+       if (bio->bi_bdev && (bio_flagged(bio, BIO_QOS_THROTTLED) ||
+                            bio_flagged(bio, BIO_QOS_MERGED))) {
+               struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+               if (q->rq_qos)
+                       __rq_qos_done_bio(q->rq_qos, bio);
+       }
 }
 
 static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
 {
-       /*
-        * BIO_TRACKED lets controllers know that a bio went through the
-        * normal rq_qos path.
-        */
        if (q->rq_qos) {
-               bio_set_flag(bio, BIO_TRACKED);
+               bio_set_flag(bio, BIO_QOS_THROTTLED);
                __rq_qos_throttle(q->rq_qos, bio);
        }
 }
@@ -205,8 +205,10 @@ static inline void rq_qos_track(struct request_queue *q, struct request *rq,
 static inline void rq_qos_merge(struct request_queue *q, struct request *rq,
                                struct bio *bio)
 {
-       if (q->rq_qos)
+       if (q->rq_qos) {
+               bio_set_flag(bio, BIO_QOS_MERGED);
                __rq_qos_merge(q->rq_qos, rq, bio);
+       }
 }
 
 static inline void rq_qos_queue_depth_changed(struct request_queue *q)