Linux 5.18 compat: bio_alloc()
As for the Linux 5.18 kernel bio_alloc() expects a block_device struct as an argument. This removes the need for the bio_set_dev() compatibility code for 5.18 and newer kernels. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #13515
This commit is contained in:
parent
090bda59e3
commit
5a639f0802
|
@ -460,6 +460,13 @@ vdev_submit_bio_impl(struct bio *bio)
|
||||||
#define preempt_schedule_notrace(x) preempt_schedule(x)
|
#define preempt_schedule_notrace(x) preempt_schedule(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As for the Linux 5.18 kernel bio_alloc() expects a block_device struct
|
||||||
|
* as an argument removing the need to set it with bio_set_dev(). This
|
||||||
|
* removes the need for all of the following compatibility code.
|
||||||
|
*/
|
||||||
|
#if !defined(HAVE_BIO_ALLOC_4ARG)
|
||||||
|
|
||||||
#ifdef HAVE_BIO_SET_DEV
|
#ifdef HAVE_BIO_SET_DEV
|
||||||
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
|
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
|
||||||
/*
|
/*
|
||||||
|
@ -556,6 +563,7 @@ bio_set_dev(struct bio *bio, struct block_device *bdev)
|
||||||
bio->bi_bdev = bdev;
|
bio->bi_bdev = bdev;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_BIO_SET_DEV */
|
#endif /* HAVE_BIO_SET_DEV */
|
||||||
|
#endif /* !HAVE_BIO_ALLOC_4ARG */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
vdev_submit_bio(struct bio *bio)
|
vdev_submit_bio(struct bio *bio)
|
||||||
|
@ -566,10 +574,36 @@ vdev_submit_bio(struct bio *bio)
|
||||||
current->bio_list = bio_list;
|
current->bio_list = bio_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct bio *
|
||||||
|
vdev_bio_alloc(struct block_device *bdev, gfp_t gfp_mask,
|
||||||
|
unsigned short nr_vecs)
|
||||||
|
{
|
||||||
|
struct bio *bio;
|
||||||
|
|
||||||
#ifdef HAVE_BIO_ALLOC_4ARG
|
#ifdef HAVE_BIO_ALLOC_4ARG
|
||||||
#define bio_alloc(gfp_mask, nr_iovecs) bio_alloc(NULL, nr_iovecs, 0, gfp_mask)
|
bio = bio_alloc(bdev, nr_vecs, 0, gfp_mask);
|
||||||
|
#else
|
||||||
|
bio = bio_alloc(gfp_mask, nr_vecs);
|
||||||
|
if (likely(bio != NULL))
|
||||||
|
bio_set_dev(bio, bdev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return (bio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
vdev_bio_max_segs(zio_t *zio, int bio_size, uint64_t abd_offset)
|
||||||
|
{
|
||||||
|
unsigned long nr_segs = abd_nr_pages_off(zio->io_abd,
|
||||||
|
bio_size, abd_offset);
|
||||||
|
|
||||||
|
#ifdef HAVE_BIO_MAX_SEGS
|
||||||
|
return (bio_max_segs(nr_segs));
|
||||||
|
#else
|
||||||
|
return (MIN(nr_segs, BIO_MAX_PAGES));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__vdev_disk_physio(struct block_device *bdev, zio_t *zio,
|
__vdev_disk_physio(struct block_device *bdev, zio_t *zio,
|
||||||
size_t io_size, uint64_t io_offset, int rw, int flags)
|
size_t io_size, uint64_t io_offset, int rw, int flags)
|
||||||
|
@ -581,6 +615,7 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
|
||||||
int bio_count = 16;
|
int bio_count = 16;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct blk_plug plug;
|
struct blk_plug plug;
|
||||||
|
unsigned short nr_vecs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accessing outside the block device is never allowed.
|
* Accessing outside the block device is never allowed.
|
||||||
|
@ -630,15 +665,8 @@ retry:
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bio_alloc() with __GFP_WAIT never returns NULL */
|
nr_vecs = vdev_bio_max_segs(zio, bio_size, abd_offset);
|
||||||
#ifdef HAVE_BIO_MAX_SEGS
|
dr->dr_bio[i] = vdev_bio_alloc(bdev, GFP_NOIO, nr_vecs);
|
||||||
dr->dr_bio[i] = bio_alloc(GFP_NOIO, bio_max_segs(
|
|
||||||
abd_nr_pages_off(zio->io_abd, bio_size, abd_offset)));
|
|
||||||
#else
|
|
||||||
dr->dr_bio[i] = bio_alloc(GFP_NOIO,
|
|
||||||
MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
|
|
||||||
BIO_MAX_PAGES));
|
|
||||||
#endif
|
|
||||||
if (unlikely(dr->dr_bio[i] == NULL)) {
|
if (unlikely(dr->dr_bio[i] == NULL)) {
|
||||||
vdev_disk_dio_free(dr);
|
vdev_disk_dio_free(dr);
|
||||||
return (SET_ERROR(ENOMEM));
|
return (SET_ERROR(ENOMEM));
|
||||||
|
@ -647,7 +675,6 @@ retry:
|
||||||
/* Matching put called by vdev_disk_physio_completion */
|
/* Matching put called by vdev_disk_physio_completion */
|
||||||
vdev_disk_dio_get(dr);
|
vdev_disk_dio_get(dr);
|
||||||
|
|
||||||
bio_set_dev(dr->dr_bio[i], 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_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;
|
||||||
|
@ -711,14 +738,12 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
|
||||||
if (!q)
|
if (!q)
|
||||||
return (SET_ERROR(ENXIO));
|
return (SET_ERROR(ENXIO));
|
||||||
|
|
||||||
bio = bio_alloc(GFP_NOIO, 0);
|
bio = vdev_bio_alloc(bdev, GFP_NOIO, 0);
|
||||||
/* bio_alloc() with __GFP_WAIT never returns NULL */
|
|
||||||
if (unlikely(bio == NULL))
|
if (unlikely(bio == NULL))
|
||||||
return (SET_ERROR(ENOMEM));
|
return (SET_ERROR(ENOMEM));
|
||||||
|
|
||||||
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_set_dev(bio, bdev);
|
|
||||||
bio_set_flush(bio);
|
bio_set_flush(bio);
|
||||||
vdev_submit_bio(bio);
|
vdev_submit_bio(bio);
|
||||||
invalidate_bdev(bdev);
|
invalidate_bdev(bdev);
|
||||||
|
|
Loading…
Reference in New Issue