From 67d31d626fa4bcf2c4752166f4fc3fa96527048d Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 24 Jul 2009 15:08:09 -0700 Subject: [PATCH 1/2] The bi_end_io API changes make partial IO's impossible Kernel commit 6712ecf8f648118c3363c142196418f89a510b90 which removes the size argument from bio_endio and bi_end_io, also removes the need to handle partial IOs in the handler. --- module/zfs/vdev_disk.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index d8343d8d2f..3d7f04afc4 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -136,18 +136,17 @@ vdev_disk_physio_completion(struct bio *bio, unsigned int size, int rc) if (dr == NULL) { printk("FATAL: bio->bi_private == NULL\n" "bi_next: %p, bi_flags: %lx, bi_rw: %lu, bi_vcnt: %d\n" - "bi_idx: %d, bi->size: %d, bi_end_io: %p, bi_cnt: %d\n", + "bi_idx: %d, bi_size: %d, bi_end_io: %p, bi_cnt: %d\n", bio->bi_next, bio->bi_flags, bio->bi_rw, bio->bi_vcnt, bio->bi_idx, bio->bi_size, bio->bi_end_io, atomic_read(&bio->bi_cnt)); SBUG(); } - /* Incomplete */ - if (bio->bi_size) { - rc = 1; - goto out; - } +#ifndef HAVE_2ARGS_BIO_END_IO_T + if (bio->bi_size) + return 1; +#endif /* HAVE_2ARGS_BIO_END_IO_T */ error = rc; if (error == 0 && !test_bit(BIO_UPTODATE, &bio->bi_flags)) @@ -168,7 +167,7 @@ vdev_disk_physio_completion(struct bio *bio, unsigned int size, int rc) zio = dr->dr_zio; spin_unlock(&dr->dr_lock); - /* Syncronous dio cleanup handled by waiter */ + /* Synchronous dio cleanup handled by waiter */ if (dr->dr_rw & (1 << BIO_RW_SYNC)) { complete(&dr->dr_comp); } else { @@ -188,7 +187,7 @@ vdev_disk_physio_completion(struct bio *bio, unsigned int size, int rc) } rc = 0; -out: + #ifdef HAVE_2ARGS_BIO_END_IO_T return; #else From 1fc5fb504cf9a20fee8e786a245f2d4b502d5c2f Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 24 Jul 2009 15:16:13 -0700 Subject: [PATCH 2/2] BIO_RW_FAILFAST replaced with BIO_RW_FAILFAST_{DEV|_TRANSPORT|_DRIVER} Use the legacy BIO_RW_FAILFAST flag if it exists. If it is missing it means we are running against a kernel with the newer API. We should be able to enable some fairly smart behavior one we intergrate with the new API, but until I get around to writing that code just remove the flag entirely. It's not critical for correctness. --- module/zfs/vdev_disk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index 3d7f04afc4..56357addb4 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -260,10 +260,6 @@ __vdev_disk_physio(struct block_device *vd_lh, zio_t *zio, caddr_t kbuf_ptr, int i, j, error = 0, bio_count, bio_size, dio_size; ASSERT3S(kbuf_offset % SECTOR_SIZE, ==, 0); - ASSERT3S(flags & - ~((1 << BIO_RW) | - (1 << BIO_RW_SYNC) | - (1 << BIO_RW_FAILFAST)), ==, 0); bio_count = (kbuf_size / (q->max_hw_sectors << 9)) + 1; dio_size = sizeof(dio_request_t) + sizeof(struct bio *) * bio_count; @@ -282,8 +278,10 @@ __vdev_disk_physio(struct block_device *vd_lh, zio_t *zio, caddr_t kbuf_ptr, if (flags & (1 << BIO_RW)) dr->dr_rw = (flags & (1 << BIO_RW_SYNC)) ? WRITE_SYNC : WRITE; +#ifdef BIO_RW_FAILFAST if (flags & (1 << BIO_RW_FAILFAST)) dr->dr_rw |= 1 << BIO_RW_FAILFAST; +#endif /* BIO_RW_FAILFAST */ /* * When the IO size exceeds the maximum bio size for the request @@ -439,8 +437,10 @@ vdev_disk_io_start(zio_t *zio) */ flags = ((zio->io_type == ZIO_TYPE_READ) ? READ : WRITE); +#ifdef BIO_RW_FAILFAST if (zio->io_flags & ZIO_FLAG_IO_RETRY) flags |= (1 << BIO_RW_FAILFAST); +#endif /* BIO_RW_FAILFAST */ error = __vdev_disk_physio(dvd->vd_lh, zio, zio->io_data, zio->io_size, zio->io_offset, flags);