mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-24 07:40:52 +00:00
fix an architectural problem introduced in r320156, ZFS ABD import
The implementation of ZFS refcount_t uses the emulated illumos mutex (the sx lock) and the waiting memory allocation when ZFS_DEBUG is enabled. This makes refcount_t unsuitable for use in GEOM g_up thread where sleeping is prohibited. When importing the ABD change I modified vdev_geom using illumos vdev_disk as an example. As a result, I added a call to abd_return_buf in vdev_geom_io_intr. The latter is called on g_up thread while the former uses refcount_t. This change fixes the problem by deferring the abd_return_buf call to the previously unused vdev_geom_io_done that is called on a ZFS zio taskqueue thread where sleeping is allowed. A side bonus of this change is that now a vdev zio has a pointer to its corresponding bio while the zio is active. Reported by: Shawn Webb <shawn.webb@hardenedbsd.org> Tested by: Shawn Webb <shawn.webb@hardenedbsd.org> MFC after: 1 week X-MFC with: r320156
This commit is contained in:
parent
bb751fbbc7
commit
1db5f1724b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320452
@ -453,6 +453,10 @@ struct zio {
|
||||
avl_node_t io_alloc_node;
|
||||
zio_alloc_list_t io_alloc_list;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
struct bio *io_bio;
|
||||
#endif
|
||||
|
||||
/* Internal pipeline state */
|
||||
enum zio_flag io_flags;
|
||||
enum zio_stage io_stage;
|
||||
|
@ -989,13 +989,6 @@ vdev_geom_io_intr(struct bio *bp)
|
||||
break;
|
||||
}
|
||||
|
||||
if (zio->io_type == ZIO_TYPE_READ) {
|
||||
abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
|
||||
} else if (zio->io_type == ZIO_TYPE_WRITE) {
|
||||
abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
|
||||
}
|
||||
|
||||
g_destroy_bio(bp);
|
||||
zio_delay_interrupt(zio);
|
||||
}
|
||||
|
||||
@ -1087,6 +1080,7 @@ vdev_geom_io_start(zio_t *zio)
|
||||
break;
|
||||
}
|
||||
bp->bio_done = vdev_geom_io_intr;
|
||||
zio->io_bio = bp;
|
||||
|
||||
g_io_request(bp, cp);
|
||||
}
|
||||
@ -1094,6 +1088,15 @@ vdev_geom_io_start(zio_t *zio)
|
||||
static void
|
||||
vdev_geom_io_done(zio_t *zio)
|
||||
{
|
||||
struct bio *bp = zio->io_bio;
|
||||
|
||||
if (zio->io_type == ZIO_TYPE_READ) {
|
||||
abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
|
||||
} else if (zio->io_type == ZIO_TYPE_WRITE) {
|
||||
abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
|
||||
}
|
||||
|
||||
g_destroy_bio(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user