]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - include/linux/blkdev.h
Merge branch 'for-4.11/block' into for-4.11/linus-merge
[karo-tx-linux.git] / include / linux / blkdev.h
index 83695641bd5ec272551857c448cc9b4f354898b8..05675b1dfd204ca6d475774b9ee13dbed30cb739 100644 (file)
@@ -154,6 +154,7 @@ struct request {
 
        /* the following two fields are internal, NEVER access directly */
        unsigned int __data_len;        /* total data len */
+       int tag;
        sector_t __sector;              /* sector cursor */
 
        struct bio *bio;
@@ -220,9 +221,10 @@ struct request {
 
        unsigned short ioprio;
 
+       int internal_tag;
+
        void *special;          /* opaque pointer available for LLD use */
 
-       int tag;
        int errors;
 
        /*
@@ -407,7 +409,7 @@ struct request_queue {
        dma_drain_needed_fn     *dma_drain_needed;
        lld_busy_fn             *lld_busy_fn;
 
-       struct blk_mq_ops       *mq_ops;
+       const struct blk_mq_ops *mq_ops;
 
        unsigned int            *mq_map;
 
@@ -569,6 +571,11 @@ struct request_queue {
        struct list_head        tag_set_list;
        struct bio_set          *bio_split;
 
+#ifdef CONFIG_DEBUG_FS
+       struct dentry           *debugfs_dir;
+       struct dentry           *mq_debugfs_dir;
+#endif
+
        bool                    mq_sysfs_init_done;
 };
 
@@ -600,6 +607,7 @@ struct request_queue {
 #define QUEUE_FLAG_FLUSH_NQ    25      /* flush not queueuable */
 #define QUEUE_FLAG_DAX         26      /* device supports DAX */
 #define QUEUE_FLAG_STATS       27      /* track rq completion times */
+#define QUEUE_FLAG_RESTART     28      /* queue needs restart at completion */
 
 #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
                                 (1 << QUEUE_FLAG_STACKABLE)    |       \
@@ -739,7 +747,7 @@ static inline bool blk_queue_is_zoned(struct request_queue *q)
        }
 }
 
-static inline unsigned int blk_queue_zone_size(struct request_queue *q)
+static inline unsigned int blk_queue_zone_sectors(struct request_queue *q)
 {
        return blk_queue_is_zoned(q) ? q->limits.chunk_sectors : 0;
 }
@@ -1000,6 +1008,19 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
        return blk_rq_cur_bytes(rq) >> 9;
 }
 
+/*
+ * Some commands like WRITE SAME have a payload or data transfer size which
+ * is different from the size of the request.  Any driver that supports such
+ * commands using the RQF_SPECIAL_PAYLOAD flag needs to use this helper to
+ * calculate the data transfer size.
+ */
+static inline unsigned int blk_rq_payload_bytes(struct request *rq)
+{
+       if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
+               return rq->special_vec.bv_len;
+       return blk_rq_bytes(rq);
+}
+
 static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
                                                     int op)
 {
@@ -1536,12 +1557,12 @@ static inline bool bdev_is_zoned(struct block_device *bdev)
        return false;
 }
 
-static inline unsigned int bdev_zone_size(struct block_device *bdev)
+static inline unsigned int bdev_zone_sectors(struct block_device *bdev)
 {
        struct request_queue *q = bdev_get_queue(bdev);
 
        if (q)
-               return blk_queue_zone_size(q);
+               return blk_queue_zone_sectors(q);
 
        return 0;
 }
@@ -1607,6 +1628,25 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,
        return __bvec_gap_to_prev(q, bprv, offset);
 }
 
+/*
+ * Check if the two bvecs from two bios can be merged to one segment.
+ * If yes, no need to check gap between the two bios since the 1st bio
+ * and the 1st bvec in the 2nd bio can be handled in one segment.
+ */
+static inline bool bios_segs_mergeable(struct request_queue *q,
+               struct bio *prev, struct bio_vec *prev_last_bv,
+               struct bio_vec *next_first_bv)
+{
+       if (!BIOVEC_PHYS_MERGEABLE(prev_last_bv, next_first_bv))
+               return false;
+       if (!BIOVEC_SEG_BOUNDARY(q, prev_last_bv, next_first_bv))
+               return false;
+       if (prev->bi_seg_back_size + next_first_bv->bv_len >
+                       queue_max_segment_size(q))
+               return false;
+       return true;
+}
+
 static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
                         struct bio *next)
 {
@@ -1616,7 +1656,8 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
                bio_get_last_bvec(prev, &pb);
                bio_get_first_bvec(next, &nb);
 
-               return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
+               if (!bios_segs_mergeable(q, prev, &pb, &nb))
+                       return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
        }
 
        return false;