]> granicus.if.org Git - zfs/commitdiff
Linux 4.8 compat: REQ_OP and bio_set_op_attrs()
authorChunwei Chen <david.chen@osnexus.com>
Wed, 27 Jul 2016 17:55:32 +0000 (17:55 +0000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 29 Jul 2016 21:48:19 +0000 (14:48 -0700)
New REQ_OP_* definitions have been introduced to separate the
WRITE, READ, and DISCARD operations from the flags.  This included
changing the encoding of bi_rw.  It places REQ_OP_* in high order
bits and other stuff in low order bits.  This encoding is done
through the new helper function bio_set_op_attrs.  For complete
details refer to:

https://github.com/torvalds/linux/commit/f215082
https://github.com/torvalds/linux/commit/4e1b2d5

Signed-off-by: Tim Chase <tim@chase2k.com>
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4892
Closes #4899

include/linux/blkdev_compat.h
module/zfs/vdev_disk.c
module/zfs/zvol.c

index e263dc8360811b875bb4de61e531013ee37168ab..01bfad600ce2c99381bf62ac33b8322c8faa097b 100644 (file)
@@ -334,15 +334,30 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
 #endif
 
 /*
- * 2.6.32 API change
- * Use the normal I/O patch for discards.
+ * 2.6.28 - 2.6.35 API,
+ *   BIO_RW_DISCARD
+ *
+ * 2.6.36 - 4.7 API,
+ *   REQ_DISCARD
+ *
+ * 4.8 - 4.x API,
+ *   REQ_OP_DISCARD
+ *
+ * In all cases the normal I/O path is used for discards.  The only
+ * difference is how the kernel tags individual I/Os as discards.
  */
 #ifdef QUEUE_FLAG_DISCARD
-#ifdef HAVE_BIO_RW_DISCARD
-#define        VDEV_REQ_DISCARD                (1 << BIO_RW_DISCARD)
+static inline boolean_t
+bio_is_discard(struct bio *bio)
+{
+#if defined(HAVE_BIO_RW_DISCARD)
+       return (bio->bi_rw & (1 << BIO_RW_DISCARD));
+#elif defined(REQ_DISCARD)
+       return (bio->bi_rw & REQ_DISCARD);
 #else
-#define        VDEV_REQ_DISCARD                REQ_DISCARD
+       return (bio_op(bio) == REQ_OP_DISCARD);
 #endif
+}
 #else
 #error "Allowing the build will cause discard requests to become writes "
        "potentially triggering the DMU_MAX_ACCESS assertion. Please file a "
index 28f145d049fb73341e23b44894a4d886c3a3c640..ccf1d839d99a32be2220d0d629d8f3fb4db4c61a 100644 (file)
@@ -484,41 +484,45 @@ bio_map(struct bio *bio, void *bio_ptr, unsigned int bio_size)
        return (bio_size);
 }
 
+#ifndef bio_set_op_attrs
+#define        bio_set_op_attrs(bio, rw, flags) \
+       do { (bio)->bi_rw |= (rw)|(flags); } while (0)
+#endif
+
 static inline void
-vdev_submit_bio_impl(int rw, struct bio *bio)
+vdev_submit_bio_impl(struct bio *bio)
 {
 #ifdef HAVE_1ARG_SUBMIT_BIO
-       bio->bi_rw |= rw;
        submit_bio(bio);
 #else
-       submit_bio(rw, bio);
+       submit_bio(0, bio);
 #endif
 }
 
 static inline void
-vdev_submit_bio(int rw, struct bio *bio)
+vdev_submit_bio(struct bio *bio)
 {
 #ifdef HAVE_CURRENT_BIO_TAIL
        struct bio **bio_tail = current->bio_tail;
        current->bio_tail = NULL;
-       vdev_submit_bio_impl(rw, bio);
+       vdev_submit_bio_impl(bio);
        current->bio_tail = bio_tail;
 #else
        struct bio_list *bio_list = current->bio_list;
        current->bio_list = NULL;
-       vdev_submit_bio_impl(rw, bio);
+       vdev_submit_bio_impl(bio);
        current->bio_list = bio_list;
 #endif
 }
 
 static int
 __vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
-    size_t kbuf_size, uint64_t kbuf_offset, int flags)
+    size_t kbuf_size, uint64_t kbuf_offset, int rw, int flags)
 {
        dio_request_t *dr;
        caddr_t bio_ptr;
        uint64_t bio_offset;
-       int rw, bio_size, bio_count = 16;
+       int bio_size, bio_count = 16;
        int i = 0, error = 0;
 
        ASSERT3U(kbuf_offset + kbuf_size, <=, bdev->bd_inode->i_size);
@@ -531,7 +535,6 @@ retry:
        if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))
                bio_set_flags_failfast(bdev, &flags);
 
-       rw = flags;
        dr->dr_zio = zio;
 
        /*
@@ -574,9 +577,9 @@ retry:
 
                dr->dr_bio[i]->bi_bdev = bdev;
                BIO_BI_SECTOR(dr->dr_bio[i]) = bio_offset >> 9;
-               dr->dr_bio[i]->bi_rw = rw;
                dr->dr_bio[i]->bi_end_io = vdev_disk_physio_completion;
                dr->dr_bio[i]->bi_private = dr;
+               bio_set_op_attrs(dr->dr_bio[i], rw, flags);
 
                /* Remaining size is returned to become the new size */
                bio_size = bio_map(dr->dr_bio[i], bio_ptr, bio_size);
@@ -592,7 +595,7 @@ retry:
        /* Submit all bio's associated with this dio */
        for (i = 0; i < dr->dr_bio_count; i++)
                if (dr->dr_bio[i])
-                       vdev_submit_bio(rw, dr->dr_bio[i]);
+                       vdev_submit_bio(dr->dr_bio[i]);
 
        (void) vdev_disk_dio_put(dr);
 
@@ -602,10 +605,10 @@ retry:
 #ifndef __linux__
 int
 vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
-    size_t size, uint64_t offset, int flags)
+    size_t size, uint64_t offset, int rw, int flags)
 {
        bio_set_flags_failfast(bdev, &flags);
-       return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags));
+       return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, rw, flags));
 }
 #endif
 
@@ -645,7 +648,8 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
        bio->bi_end_io = vdev_disk_io_flush_completion;
        bio->bi_private = zio;
        bio->bi_bdev = bdev;
-       vdev_submit_bio(VDEV_WRITE_FLUSH_FUA, bio);
+       bio_set_op_attrs(bio, 0, VDEV_WRITE_FLUSH_FUA);
+       vdev_submit_bio(bio);
        invalidate_bdev(bdev);
 
        return (0);
@@ -656,7 +660,7 @@ vdev_disk_io_start(zio_t *zio)
 {
        vdev_t *v = zio->io_vd;
        vdev_disk_t *vd = v->vdev_tsd;
-       int flags, error;
+       int rw, flags, error;
 
        switch (zio->io_type) {
        case ZIO_TYPE_IOCTL:
@@ -695,22 +699,24 @@ vdev_disk_io_start(zio_t *zio)
                zio_execute(zio);
                return;
        case ZIO_TYPE_WRITE:
+               rw = WRITE;
 #if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
-               flags = WRITE | (1 << BIO_RW_UNPLUG);
+               flags = (1 << BIO_RW_UNPLUG);
 #elif defined(REQ_UNPLUG)
-               flags = WRITE | REQ_UNPLUG;
+               flags = REQ_UNPLUG;
 #else
-               flags = WRITE;
+               flags = 0;
 #endif
                break;
 
        case ZIO_TYPE_READ:
+               rw = READ;
 #if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
-               flags = READ | (1 << BIO_RW_UNPLUG);
+               flags = (1 << BIO_RW_UNPLUG);
 #elif defined(REQ_UNPLUG)
-               flags = READ | REQ_UNPLUG;
+               flags = REQ_UNPLUG;
 #else
-               flags = READ;
+               flags = 0;
 #endif
                break;
 
@@ -722,7 +728,7 @@ vdev_disk_io_start(zio_t *zio)
 
        zio->io_target_timestamp = zio_handle_io_delay(zio);
        error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
-           zio->io_size, zio->io_offset, flags);
+           zio->io_size, zio->io_offset, rw, flags);
        if (error) {
                zio->io_error = error;
                zio_interrupt(zio);
@@ -824,7 +830,8 @@ vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config)
                /* read vdev label */
                offset = vdev_label_offset(size, i, 0);
                if (vdev_disk_physio(bdev, (caddr_t)label,
-                   VDEV_SKIP_SIZE + VDEV_PHYS_SIZE, offset, READ_SYNC) != 0)
+                   VDEV_SKIP_SIZE + VDEV_PHYS_SIZE, offset, READ,
+                   REQ_SYNC) != 0)
                        continue;
 
                if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
index 73277901ff16f57b77442645fea20b8535e8acee..c25b243db3a82b9c6cfd5a36a3c2544dc26ae6a0 100644 (file)
@@ -812,7 +812,7 @@ zvol_request(struct request_queue *q, struct bio *bio)
                        goto out2;
                }
 
-               if (bio->bi_rw & VDEV_REQ_DISCARD) {
+               if (bio_is_discard(bio)) {
                        error = zvol_discard(bio);
                        goto out2;
                }