block: Clean up special command handling logic
authorMartin K. Petersen <martin.petersen@oracle.com>
Tue, 18 Sep 2012 16:19:25 +0000 (12:19 -0400)
committerJens Axboe <axboe@kernel.dk>
Thu, 20 Sep 2012 12:31:38 +0000 (14:31 +0200)
Remove special-casing of non-rw fs style requests (discard). The nomerge
flags are consolidated in blk_types.h, and rq_mergeable() and
bio_mergeable() have been modified to use them.

bio_is_rw() is used in place of bio_has_data() a few places. This is
done to to distinguish true reads and writes from other fs type requests
that carry a payload (e.g. write same).

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-core.c
block/blk-merge.c
block/blk.h
block/elevator.c
include/linux/bio.h
include/linux/blk_types.h
include/linux/blkdev.h

index 2d739ca109238dd6e50e8a3e59d97ff48efc687d..5cc29299f6ac63c429beba4485e1105a66bf5783 100644 (file)
@@ -1657,8 +1657,8 @@ generic_make_request_checks(struct bio *bio)
                goto end_io;
        }
 
-       if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
-                    nr_sectors > queue_max_hw_sectors(q))) {
+       if (likely(bio_is_rw(bio) &&
+                  nr_sectors > queue_max_hw_sectors(q))) {
                printk(KERN_ERR "bio too big device %s (%u > %u)\n",
                       bdevname(bio->bi_bdev, b),
                       bio_sectors(bio),
@@ -1699,8 +1699,7 @@ generic_make_request_checks(struct bio *bio)
 
        if ((bio->bi_rw & REQ_DISCARD) &&
            (!blk_queue_discard(q) ||
-            ((bio->bi_rw & REQ_SECURE) &&
-             !blk_queue_secdiscard(q)))) {
+            ((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
                err = -EOPNOTSUPP;
                goto end_io;
        }
@@ -1818,7 +1817,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_has_data(bio) && !(rw & REQ_DISCARD)) {
+       if (bio_has_data(bio)) {
                if (rw & WRITE) {
                        count_vm_events(PGPGOUT, count);
                } else {
@@ -1864,7 +1863,7 @@ EXPORT_SYMBOL(submit_bio);
  */
 int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 {
-       if (rq->cmd_flags & REQ_DISCARD)
+       if (!rq_mergeable(rq))
                return 0;
 
        if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
@@ -2338,7 +2337,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
        req->buffer = bio_data(req->bio);
 
        /* update sector only for requests with clear definition of sector */
-       if (req->cmd_type == REQ_TYPE_FS || (req->cmd_flags & REQ_DISCARD))
+       if (req->cmd_type == REQ_TYPE_FS)
                req->__sector += total_bytes >> 9;
 
        /* mixed attributes always follow the first bio */
index e76279e411622519eebb54d4802eb11b796788db..86710ca408b862d38f1876c59332ff3753033ec4 100644 (file)
@@ -417,18 +417,6 @@ static int attempt_merge(struct request_queue *q, struct request *req,
        if (!rq_mergeable(req) || !rq_mergeable(next))
                return 0;
 
-       /*
-        * Don't merge file system requests and discard requests
-        */
-       if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
-               return 0;
-
-       /*
-        * Don't merge discard requests and secure discard requests
-        */
-       if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
-               return 0;
-
        /*
         * not contiguous
         */
@@ -521,15 +509,7 @@ int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
 
 bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 {
-       if (!rq_mergeable(rq))
-               return false;
-
-       /* don't merge file system requests and discard requests */
-       if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
-               return false;
-
-       /* don't merge discard requests and secure discard requests */
-       if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
+       if (!rq_mergeable(rq) || !bio_mergeable(bio))
                return false;
 
        /* different data direction or already started, don't merge */
index 2a0ea32d249fdaa9694e0249e435777565535d70..ca51543b248ca16f0eb28e937ec321e52f3130c8 100644 (file)
@@ -171,14 +171,13 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
  *
  *     a) it's attached to a gendisk, and
  *     b) the queue had IO stats enabled when this request was started, and
- *     c) it's a file system request or a discard request
+ *     c) it's a file system request
  */
 static inline int blk_do_io_stat(struct request *rq)
 {
        return rq->rq_disk &&
               (rq->cmd_flags & REQ_IO_STAT) &&
-              (rq->cmd_type == REQ_TYPE_FS ||
-               (rq->cmd_flags & REQ_DISCARD));
+               (rq->cmd_type == REQ_TYPE_FS);
 }
 
 /*
index 6a55d418896f5ceee0042da69c0177c495219cbc..9b1d42b62f207d5a37f657e21fc65769bc9e85c2 100644 (file)
@@ -562,8 +562,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
 
        if (rq->cmd_flags & REQ_SOFTBARRIER) {
                /* barriers are scheduling boundary, update end_sector */
-               if (rq->cmd_type == REQ_TYPE_FS ||
-                   (rq->cmd_flags & REQ_DISCARD)) {
+               if (rq->cmd_type == REQ_TYPE_FS) {
                        q->end_sector = rq_end_sector(rq);
                        q->boundary_rq = rq;
                }
@@ -605,8 +604,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where)
                if (elv_attempt_insert_merge(q, rq))
                        break;
        case ELEVATOR_INSERT_SORT:
-               BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
-                      !(rq->cmd_flags & REQ_DISCARD));
+               BUG_ON(rq->cmd_type != REQ_TYPE_FS);
                rq->cmd_flags |= REQ_SORTED;
                q->nr_sorted++;
                if (rq_mergeable(rq)) {
index 52b9cbc3e4dac80e2229a0d65be621b7b0f15ebc..e54305cacc9821e4ffbb40aebbd89ddb97401710 100644 (file)
@@ -386,9 +386,28 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
 /*
  * Check whether this bio carries any data or not. A NULL bio is allowed.
  */
-static inline int bio_has_data(struct bio *bio)
+static inline bool bio_has_data(struct bio *bio)
 {
-       return bio && bio->bi_io_vec != NULL;
+       if (bio && bio->bi_vcnt)
+               return true;
+
+       return false;
+}
+
+static inline bool bio_is_rw(struct bio *bio)
+{
+       if (!bio_has_data(bio))
+               return false;
+
+       return true;
+}
+
+static inline bool bio_mergeable(struct bio *bio)
+{
+       if (bio->bi_rw & REQ_NOMERGE_FLAGS)
+               return false;
+
+       return true;
 }
 
 /*
index 3eefbb2911922b6f0e28d8bdd72b362ed376913d..1b229664f573a2bf19997a1c6b78e6e604bdb4d4 100644 (file)
@@ -194,6 +194,10 @@ enum rq_flag_bits {
         REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
 #define REQ_CLONE_MASK         REQ_COMMON_MASK
 
+/* This mask is used for both bio and request merge checking */
+#define REQ_NOMERGE_FLAGS \
+       (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
+
 #define REQ_RAHEAD             (1 << __REQ_RAHEAD)
 #define REQ_THROTTLED          (1 << __REQ_THROTTLED)
 
index 4a2ab7c85393df48fd8d93e085f3b7ead5de7be2..3a6fea7460f1f0309508432696609e3376b2195d 100644 (file)
@@ -540,8 +540,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 
 #define blk_account_rq(rq) \
        (((rq)->cmd_flags & REQ_STARTED) && \
-        ((rq)->cmd_type == REQ_TYPE_FS || \
-         ((rq)->cmd_flags & REQ_DISCARD)))
+        ((rq)->cmd_type == REQ_TYPE_FS))
 
 #define blk_pm_request(rq)     \
        ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
@@ -595,17 +594,16 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync)
        rl->flags &= ~flag;
 }
 
+static inline bool rq_mergeable(struct request *rq)
+{
+       if (rq->cmd_type != REQ_TYPE_FS)
+               return false;
 
-/*
- * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may
- * it already be started by driver.
- */
-#define RQ_NOMERGE_FLAGS       \
-       (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD)
-#define rq_mergeable(rq)       \
-       (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
-        (((rq)->cmd_flags & REQ_DISCARD) || \
-         (rq)->cmd_type == REQ_TYPE_FS))
+       if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
+               return false;
+
+       return true;
+}
 
 /*
  * q->prep_rq_fn return values