Linux 4.3 compat: bio_end_io_t / BIO_UPTODATE

Commit torvalds/linux@4246a0b63b
("block: add a bi_error field to struct bio") dropped the error
argument from bio_endio in favor of newly introduced bio->bi_error.
This also replaces bio->bi_flags value BIO_UPTODATE.

bio_endio was a 3 argument function until Linux 2.6.24, which made it
a 2 argument function, and now the prototype has changed yet again to
a 1 argument function. Support for pre 2.6.24 kernels was already
dropped with 37f9dac592 ("zvol processing should use struct bio")
which assumed the 2 argument version in zvol_request(). Remaining code
to support the 3 argument version is hereby removed.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Issue #3799
This commit is contained in:
Lukas Wunner 2015-09-23 17:55:15 +02:00 committed by Brian Behlendorf
parent 4a4809faab
commit 784a7fe5d9
4 changed files with 34 additions and 40 deletions

View File

@ -1,25 +1,23 @@
dnl # dnl #
dnl # 2.6.24 API change dnl # 4.3 API change
dnl # Size argument dropped from bio_endio and bi_end_io, because the dnl # Error argument dropped from bio_endio in favor of newly introduced
dnl # bi_end_io is only called once now when the request is complete. dnl # bio->bi_error. This also replaces bio->bi_flags value BIO_UPTODATE.
dnl # There is no longer any need for a size argument. This also means dnl # Introduced by torvalds/linux@4246a0b63bd8f56a1469b12eafeb875b1041a451
dnl # that partial IO's are no longer possibe and the end_io callback dnl # ("block: add a bi_error field to struct bio").
dnl # should not check bi->bi_size. Finally, the return type was updated
dnl # to void.
dnl # dnl #
AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [ AC_DEFUN([ZFS_AC_KERNEL_BIO_END_IO_T_ARGS], [
AC_MSG_CHECKING([whether bio_end_io_t wants 2 args]) AC_MSG_CHECKING([whether bio_end_io_t wants 1 arg])
ZFS_LINUX_TRY_COMPILE([ ZFS_LINUX_TRY_COMPILE([
#include <linux/bio.h> #include <linux/bio.h>
void wanted_end_io(struct bio *bio, int x) { return; } void wanted_end_io(struct bio *bio) { return; }
bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io; bio_end_io_t *end_io __attribute__ ((unused)) = wanted_end_io;
],[ ],[
],[ ],[
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_2ARGS_BIO_END_IO_T, 1, AC_DEFINE(HAVE_1ARG_BIO_END_IO_T, 1,
[bio_end_io_t wants 2 args]) [bio_end_io_t wants 1 arg])
],[ ],[
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
]) ])

View File

@ -182,20 +182,17 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
#endif /* DISK_NAME_LEN */ #endif /* DISK_NAME_LEN */
/* /*
* 2.6.24 API change, * 4.3 API change
* The bio_end_io() prototype changed slightly. These are helper * The bio_endio() prototype changed slightly. These are helper
* macro's to ensure the prototype and return value are handled. * macro's to ensure the prototype and invocation are handled.
*/ */
#ifdef HAVE_2ARGS_BIO_END_IO_T #ifdef HAVE_1ARG_BIO_END_IO_T
#define BIO_END_IO_PROTO(fn, x, y, z) static void fn(struct bio *x, int z) #define BIO_END_IO_PROTO(fn, x, z) static void fn(struct bio *x)
#define BIO_END_IO_RETURN(rc) return #define BIO_END_IO(bio, error) bio->bi_error = error; bio_endio(bio);
#else #else
#define BIO_END_IO_PROTO(fn, x, y, z) static int fn( \ #define BIO_END_IO_PROTO(fn, x, z) static void fn(struct bio *x, int z)
struct bio *x, \ #define BIO_END_IO(bio, error) bio_endio(bio, error);
unsigned int y, \ #endif /* HAVE_1ARG_BIO_END_IO_T */
int z)
#define BIO_END_IO_RETURN(rc) return rc
#endif /* HAVE_2ARGS_BIO_END_IO_T */
/* /*
* 2.6.38 - 2.6.x API, * 2.6.38 - 2.6.x API,

View File

@ -424,21 +424,21 @@ vdev_disk_dio_put(dio_request_t *dr)
return (rc); return (rc);
} }
BIO_END_IO_PROTO(vdev_disk_physio_completion, bio, size, error) BIO_END_IO_PROTO(vdev_disk_physio_completion, bio, error)
{ {
dio_request_t *dr = bio->bi_private; dio_request_t *dr = bio->bi_private;
int rc; int rc;
#ifndef HAVE_2ARGS_BIO_END_IO_T if (dr->dr_error == 0) {
if (BIO_BI_SIZE(bio)) #ifdef HAVE_1ARG_BIO_END_IO_T
return (1); dr->dr_error = -(bio->bi_error);
#endif /* HAVE_2ARGS_BIO_END_IO_T */ #else
if (error)
if (error == 0 && !test_bit(BIO_UPTODATE, &bio->bi_flags)) dr->dr_error = -(error);
error = (-EIO); else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
dr->dr_error = EIO;
if (dr->dr_error == 0) #endif
dr->dr_error = -error; }
/* Drop reference aquired by __vdev_disk_physio */ /* Drop reference aquired by __vdev_disk_physio */
rc = vdev_disk_dio_put(dr); rc = vdev_disk_dio_put(dr);
@ -446,8 +446,6 @@ BIO_END_IO_PROTO(vdev_disk_physio_completion, bio, size, error)
/* Wake up synchronous waiter this is the last outstanding bio */ /* Wake up synchronous waiter this is the last outstanding bio */
if ((rc == 1) && vdev_disk_dio_is_sync(dr)) if ((rc == 1) && vdev_disk_dio_is_sync(dr))
complete(&dr->dr_comp); complete(&dr->dr_comp);
BIO_END_IO_RETURN(0);
} }
static inline unsigned long static inline unsigned long
@ -624,9 +622,12 @@ vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags)); return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags));
} }
BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, size, rc) BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
{ {
zio_t *zio = bio->bi_private; zio_t *zio = bio->bi_private;
#ifdef HAVE_1ARG_BIO_END_IO_T
int rc = bio->bi_error;
#endif
zio->io_delay = jiffies_64 - zio->io_delay; zio->io_delay = jiffies_64 - zio->io_delay;
zio->io_error = -rc; zio->io_error = -rc;
@ -638,8 +639,6 @@ BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, size, rc)
if (zio->io_error) if (zio->io_error)
vdev_disk_error(zio); vdev_disk_error(zio);
zio_interrupt(zio); zio_interrupt(zio);
BIO_END_IO_RETURN(0);
} }
static int static int

View File

@ -752,7 +752,7 @@ zvol_request(struct request_queue *q, struct bio *bio)
out2: out2:
generic_end_io_acct(rw, &zv->zv_disk->part0, start); generic_end_io_acct(rw, &zv->zv_disk->part0, start);
out1: out1:
bio_endio(bio, -error); BIO_END_IO(bio, -error);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
#ifdef HAVE_MAKE_REQUEST_FN_RET_INT #ifdef HAVE_MAKE_REQUEST_FN_RET_INT
return (0); return (0);