]> granicus.if.org Git - zfs/commitdiff
Linux 4.13 compat: bio->bi_status and blk_status_t
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 24 Jul 2017 02:37:12 +0000 (19:37 -0700)
committerGitHub <noreply@github.com>
Mon, 24 Jul 2017 02:37:12 +0000 (19:37 -0700)
Commit torvalds/linux@4e4cbee9.  The bio->bi_error field was
replaced with bio->bi_status which is an enum that describes
all possible error types.

Reviewed-by: Chunwei Chen <david.chen@osnexus.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #6351

config/kernel-bio-end-io-t-args.m4
config/kernel.m4
include/linux/blkdev_compat.h
module/zfs/vdev_disk.c

index c8c520f1ba8295be4762b0099f121f92c10df85f..3c420cc0c305b4ccee12dd4e3f1985ac1a32de0c 100644 (file)
@@ -22,3 +22,25 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
                AC_MSG_RESULT(no)
        ])
 ])
+
+dnl #
+dnl # 4.13 API change
+dnl # The bio->bi_error field was replaced with bio->bi_status which is an
+dnl # enum which describes all possible error types.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_STATUS], [
+       AC_MSG_CHECKING([whether bio->bi_status exists])
+       ZFS_LINUX_TRY_COMPILE([
+               #include <linux/bio.h>
+       ],[
+               struct bio bio __attribute__ ((unused));
+               blk_status_t status __attribute__ ((unused)) = BLK_STS_OK;
+
+               bio.bi_status = status;
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_BIO_BI_STATUS, 1, [bio->bi_status exists])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+])
index 324ab816f6a697bd8a9d8283f717ad3e4e92a9e5..e92a659879b4be8e1418bd3d0de072d3ffe6f020 100644 (file)
@@ -30,6 +30,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
        ZFS_AC_KERNEL_REQ_OP_FLUSH
        ZFS_AC_KERNEL_BIO_BI_OPF
        ZFS_AC_KERNEL_BIO_END_IO_T_ARGS
+       ZFS_AC_KERNEL_BIO_BI_STATUS
        ZFS_AC_KERNEL_BIO_RW_BARRIER
        ZFS_AC_KERNEL_BIO_RW_DISCARD
        ZFS_AC_KERNEL_BLK_QUEUE_BDI
index 822e964a71377e8cc943c464c9aa0a0ce96ddb54..428664a0b6b31094800e9e11be7321dc36a4c851 100644 (file)
@@ -221,14 +221,104 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
 #define        DISK_NAME_LEN   32
 #endif /* DISK_NAME_LEN */
 
+#ifdef HAVE_BIO_BI_STATUS
+static inline int
+bi_status_to_errno(blk_status_t status)
+{
+       switch (status) {
+       case BLK_STS_OK:
+               return (0);
+       case BLK_STS_NOTSUPP:
+               return (EOPNOTSUPP);
+       case BLK_STS_TIMEOUT:
+               return (ETIMEDOUT);
+       case BLK_STS_NOSPC:
+               return (ENOSPC);
+       case BLK_STS_TRANSPORT:
+               return (ENOLINK);
+       case BLK_STS_TARGET:
+               return (EREMOTEIO);
+       case BLK_STS_NEXUS:
+               return (EBADE);
+       case BLK_STS_MEDIUM:
+               return (ENODATA);
+       case BLK_STS_PROTECTION:
+               return (EILSEQ);
+       case BLK_STS_RESOURCE:
+               return (ENOMEM);
+       case BLK_STS_AGAIN:
+               return (EAGAIN);
+       case BLK_STS_IOERR:
+               return (EIO);
+       default:
+               return (EIO);
+       }
+}
+
+static inline blk_status_t
+errno_to_bi_status(int error)
+{
+       switch (error) {
+       case 0:
+               return (BLK_STS_OK);
+       case EOPNOTSUPP:
+               return (BLK_STS_NOTSUPP);
+       case ETIMEDOUT:
+               return (BLK_STS_TIMEOUT);
+       case ENOSPC:
+               return (BLK_STS_NOSPC);
+       case ENOLINK:
+               return (BLK_STS_TRANSPORT);
+       case EREMOTEIO:
+               return (BLK_STS_TARGET);
+       case EBADE:
+               return (BLK_STS_NEXUS);
+       case ENODATA:
+               return (BLK_STS_MEDIUM);
+       case EILSEQ:
+               return (BLK_STS_PROTECTION);
+       case ENOMEM:
+               return (BLK_STS_RESOURCE);
+       case EAGAIN:
+               return (BLK_STS_AGAIN);
+       case EIO:
+               return (BLK_STS_IOERR);
+       default:
+               return (BLK_STS_IOERR);
+       }
+}
+#endif /* HAVE_BIO_BI_STATUS */
+
 /*
  * 4.3 API change
  * The bio_endio() prototype changed slightly.  These are helper
  * macro's to ensure the prototype and invocation are handled.
  */
 #ifdef HAVE_1ARG_BIO_END_IO_T
+#ifdef HAVE_BIO_BI_STATUS
+#define        BIO_END_IO_ERROR(bio)           bi_status_to_errno(bio->bi_status)
+#define        BIO_END_IO_PROTO(fn, x, z)      static void fn(struct bio *x)
+#define        BIO_END_IO(bio, error)          bio_set_bi_status(bio, error)
+static inline void
+bio_set_bi_status(struct bio *bio, int error)
+{
+       ASSERT3S(error, <=, 0);
+       bio->bi_status = errno_to_bi_status(-error);
+       bio_endio(bio);
+}
+#else
+#define        BIO_END_IO_ERROR(bio)           (-(bio->bi_error))
 #define        BIO_END_IO_PROTO(fn, x, z)      static void fn(struct bio *x)
-#define        BIO_END_IO(bio, error)          bio->bi_error = error; bio_endio(bio);
+#define        BIO_END_IO(bio, error)          bio_set_bi_error(bio, error)
+static inline void
+bio_set_bi_error(struct bio *bio, int error)
+{
+       ASSERT3S(error, <=, 0);
+       bio->bi_error = error;
+       bio_endio(bio);
+}
+#endif /* HAVE_BIO_BI_STATUS */
+
 #else
 #define        BIO_END_IO_PROTO(fn, x, z)      static void fn(struct bio *x, int z)
 #define        BIO_END_IO(bio, error)          bio_endio(bio, error);
index 3fdf5642b104ce54d20070c8fd6e37d365ec1e8d..f87f7913eacce1442b8707923ee254cea797bd11 100644 (file)
@@ -427,7 +427,7 @@ BIO_END_IO_PROTO(vdev_disk_physio_completion, bio, error)
 
        if (dr->dr_error == 0) {
 #ifdef HAVE_1ARG_BIO_END_IO_T
-               dr->dr_error = -(bio->bi_error);
+               dr->dr_error = BIO_END_IO_ERROR(bio);
 #else
                if (error)
                        dr->dr_error = -(error);
@@ -618,15 +618,16 @@ retry:
        return (error);
 }
 
-BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
+BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, error)
 {
        zio_t *zio = bio->bi_private;
 #ifdef HAVE_1ARG_BIO_END_IO_T
-       int rc = bio->bi_error;
+       zio->io_error = BIO_END_IO_ERROR(bio);
+#else
+       zio->io_error = -error;
 #endif
 
-       zio->io_error = -rc;
-       if (rc && (rc == -EOPNOTSUPP))
+       if (zio->io_error && (zio->io_error == EOPNOTSUPP))
                zio->io_vd->vdev_nowritecache = B_TRUE;
 
        bio_put(bio);