Linux 4.8 compat: REQ_OP and bio_set_op_attrs()
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
This commit is contained in:
parent
76e5f6fe10
commit
3b86aeb295
|
@ -334,15 +334,30 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.6.32 API change
|
* 2.6.28 - 2.6.35 API,
|
||||||
* Use the normal I/O patch for discards.
|
* 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 QUEUE_FLAG_DISCARD
|
||||||
#ifdef HAVE_BIO_RW_DISCARD
|
static inline boolean_t
|
||||||
#define VDEV_REQ_DISCARD (1 << BIO_RW_DISCARD)
|
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
|
#else
|
||||||
#define VDEV_REQ_DISCARD REQ_DISCARD
|
return (bio_op(bio) == REQ_OP_DISCARD);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error "Allowing the build will cause discard requests to become writes "
|
#error "Allowing the build will cause discard requests to become writes "
|
||||||
"potentially triggering the DMU_MAX_ACCESS assertion. Please file a "
|
"potentially triggering the DMU_MAX_ACCESS assertion. Please file a "
|
||||||
|
|
|
@ -484,41 +484,45 @@ bio_map(struct bio *bio, void *bio_ptr, unsigned int bio_size)
|
||||||
return (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
|
static inline void
|
||||||
vdev_submit_bio_impl(int rw, struct bio *bio)
|
vdev_submit_bio_impl(struct bio *bio)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_1ARG_SUBMIT_BIO
|
#ifdef HAVE_1ARG_SUBMIT_BIO
|
||||||
bio->bi_rw |= rw;
|
|
||||||
submit_bio(bio);
|
submit_bio(bio);
|
||||||
#else
|
#else
|
||||||
submit_bio(rw, bio);
|
submit_bio(0, bio);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
vdev_submit_bio(int rw, struct bio *bio)
|
vdev_submit_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CURRENT_BIO_TAIL
|
#ifdef HAVE_CURRENT_BIO_TAIL
|
||||||
struct bio **bio_tail = current->bio_tail;
|
struct bio **bio_tail = current->bio_tail;
|
||||||
current->bio_tail = NULL;
|
current->bio_tail = NULL;
|
||||||
vdev_submit_bio_impl(rw, bio);
|
vdev_submit_bio_impl(bio);
|
||||||
current->bio_tail = bio_tail;
|
current->bio_tail = bio_tail;
|
||||||
#else
|
#else
|
||||||
struct bio_list *bio_list = current->bio_list;
|
struct bio_list *bio_list = current->bio_list;
|
||||||
current->bio_list = NULL;
|
current->bio_list = NULL;
|
||||||
vdev_submit_bio_impl(rw, bio);
|
vdev_submit_bio_impl(bio);
|
||||||
current->bio_list = bio_list;
|
current->bio_list = bio_list;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
|
__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;
|
dio_request_t *dr;
|
||||||
caddr_t bio_ptr;
|
caddr_t bio_ptr;
|
||||||
uint64_t bio_offset;
|
uint64_t bio_offset;
|
||||||
int rw, bio_size, bio_count = 16;
|
int bio_size, bio_count = 16;
|
||||||
int i = 0, error = 0;
|
int i = 0, error = 0;
|
||||||
|
|
||||||
ASSERT3U(kbuf_offset + kbuf_size, <=, bdev->bd_inode->i_size);
|
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)))
|
if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))
|
||||||
bio_set_flags_failfast(bdev, &flags);
|
bio_set_flags_failfast(bdev, &flags);
|
||||||
|
|
||||||
rw = flags;
|
|
||||||
dr->dr_zio = zio;
|
dr->dr_zio = zio;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -574,9 +577,9 @@ retry:
|
||||||
|
|
||||||
dr->dr_bio[i]->bi_bdev = bdev;
|
dr->dr_bio[i]->bi_bdev = bdev;
|
||||||
BIO_BI_SECTOR(dr->dr_bio[i]) = bio_offset >> 9;
|
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_end_io = vdev_disk_physio_completion;
|
||||||
dr->dr_bio[i]->bi_private = dr;
|
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 */
|
/* Remaining size is returned to become the new size */
|
||||||
bio_size = bio_map(dr->dr_bio[i], bio_ptr, bio_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 */
|
/* Submit all bio's associated with this dio */
|
||||||
for (i = 0; i < dr->dr_bio_count; i++)
|
for (i = 0; i < dr->dr_bio_count; i++)
|
||||||
if (dr->dr_bio[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);
|
(void) vdev_disk_dio_put(dr);
|
||||||
|
|
||||||
|
@ -602,10 +605,10 @@ retry:
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
int
|
int
|
||||||
vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
|
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);
|
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
|
#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_end_io = vdev_disk_io_flush_completion;
|
||||||
bio->bi_private = zio;
|
bio->bi_private = zio;
|
||||||
bio->bi_bdev = bdev;
|
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);
|
invalidate_bdev(bdev);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -656,7 +660,7 @@ vdev_disk_io_start(zio_t *zio)
|
||||||
{
|
{
|
||||||
vdev_t *v = zio->io_vd;
|
vdev_t *v = zio->io_vd;
|
||||||
vdev_disk_t *vd = v->vdev_tsd;
|
vdev_disk_t *vd = v->vdev_tsd;
|
||||||
int flags, error;
|
int rw, flags, error;
|
||||||
|
|
||||||
switch (zio->io_type) {
|
switch (zio->io_type) {
|
||||||
case ZIO_TYPE_IOCTL:
|
case ZIO_TYPE_IOCTL:
|
||||||
|
@ -695,22 +699,24 @@ vdev_disk_io_start(zio_t *zio)
|
||||||
zio_execute(zio);
|
zio_execute(zio);
|
||||||
return;
|
return;
|
||||||
case ZIO_TYPE_WRITE:
|
case ZIO_TYPE_WRITE:
|
||||||
|
rw = WRITE;
|
||||||
#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
|
#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
|
||||||
flags = WRITE | (1 << BIO_RW_UNPLUG);
|
flags = (1 << BIO_RW_UNPLUG);
|
||||||
#elif defined(REQ_UNPLUG)
|
#elif defined(REQ_UNPLUG)
|
||||||
flags = WRITE | REQ_UNPLUG;
|
flags = REQ_UNPLUG;
|
||||||
#else
|
#else
|
||||||
flags = WRITE;
|
flags = 0;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZIO_TYPE_READ:
|
case ZIO_TYPE_READ:
|
||||||
|
rw = READ;
|
||||||
#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
|
#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
|
||||||
flags = READ | (1 << BIO_RW_UNPLUG);
|
flags = (1 << BIO_RW_UNPLUG);
|
||||||
#elif defined(REQ_UNPLUG)
|
#elif defined(REQ_UNPLUG)
|
||||||
flags = READ | REQ_UNPLUG;
|
flags = REQ_UNPLUG;
|
||||||
#else
|
#else
|
||||||
flags = READ;
|
flags = 0;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -722,7 +728,7 @@ vdev_disk_io_start(zio_t *zio)
|
||||||
|
|
||||||
zio->io_target_timestamp = zio_handle_io_delay(zio);
|
zio->io_target_timestamp = zio_handle_io_delay(zio);
|
||||||
error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
|
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) {
|
if (error) {
|
||||||
zio->io_error = error;
|
zio->io_error = error;
|
||||||
zio_interrupt(zio);
|
zio_interrupt(zio);
|
||||||
|
@ -824,7 +830,8 @@ vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config)
|
||||||
/* read vdev label */
|
/* read vdev label */
|
||||||
offset = vdev_label_offset(size, i, 0);
|
offset = vdev_label_offset(size, i, 0);
|
||||||
if (vdev_disk_physio(bdev, (caddr_t)label,
|
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;
|
continue;
|
||||||
|
|
||||||
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
|
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
|
||||||
|
|
|
@ -812,7 +812,7 @@ zvol_request(struct request_queue *q, struct bio *bio)
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bio->bi_rw & VDEV_REQ_DISCARD) {
|
if (bio_is_discard(bio)) {
|
||||||
error = zvol_discard(bio);
|
error = zvol_discard(bio);
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue