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:
Chunwei Chen 2016-07-27 17:55:32 +00:00 committed by Ned Bass
parent a0591c4370
commit 6ae0dbdc8a
4 changed files with 49 additions and 26 deletions

View File

@ -332,15 +332,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 "

View File

@ -38,7 +38,7 @@ typedef struct vdev_disk {
} vdev_disk_t; } vdev_disk_t;
extern int vdev_disk_physio(struct block_device *, caddr_t, extern int vdev_disk_physio(struct block_device *, caddr_t,
size_t, uint64_t, int); size_t, uint64_t, int, int);
extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **); extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
#endif /* _KERNEL */ #endif /* _KERNEL */

View File

@ -494,41 +494,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, int wait) size_t kbuf_size, uint64_t kbuf_offset, int rw, int flags, int wait)
{ {
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);
@ -541,7 +545,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;
dr->dr_wait = wait; dr->dr_wait = wait;
@ -585,9 +588,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);
@ -605,7 +608,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]);
/* /*
* On synchronous blocking requests we wait for all bio the completion * On synchronous blocking requests we wait for all bio the completion
@ -628,10 +631,11 @@ retry:
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, 1)); return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, rw, flags,
1));
} }
BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc) BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
@ -672,7 +676,8 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
bio->bi_private = zio; bio->bi_private = zio;
bio->bi_bdev = bdev; bio->bi_bdev = bdev;
zio->io_delay = jiffies_64; zio->io_delay = jiffies_64;
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);
@ -684,7 +689,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;
zio_priority_t pri = zio->io_priority; zio_priority_t pri = zio->io_priority;
int flags, error; int rw, flags, error;
switch (zio->io_type) { switch (zio->io_type) {
case ZIO_TYPE_IOCTL: case ZIO_TYPE_IOCTL:
@ -723,17 +728,19 @@ 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 ((pri == ZIO_PRIORITY_SYNC_WRITE) && (v->vdev_nonrot)) if ((pri == ZIO_PRIORITY_SYNC_WRITE) && (v->vdev_nonrot))
flags = WRITE_SYNC; flags = WRITE_SYNC;
else else
flags = WRITE; flags = 0;
break; break;
case ZIO_TYPE_READ: case ZIO_TYPE_READ:
rw = READ;
if ((pri == ZIO_PRIORITY_SYNC_READ) && (v->vdev_nonrot)) if ((pri == ZIO_PRIORITY_SYNC_READ) && (v->vdev_nonrot))
flags = READ_SYNC; flags = READ_SYNC;
else else
flags = READ; flags = 0;
break; break;
default: default:
@ -743,7 +750,7 @@ vdev_disk_io_start(zio_t *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, 0); zio->io_size, zio->io_offset, rw, flags, 0);
if (error) { if (error) {
zio->io_error = error; zio->io_error = error;
zio_interrupt(zio); zio_interrupt(zio);
@ -844,7 +851,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,

View File

@ -766,7 +766,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;
} }