fix memory leak in g_bio zone introduced in r320452, another ABD fallout

I overlooked the fact that that ZIO_IOCTL_PIPELINE does not include
ZIO_STAGE_VDEV_IO_DONE stage.  We do allocate a struct bio for an ioctl
zio (a disk cache flush), but we never freed it.

This change splits bio handling into two groups, one for normal
read/write i/o that passes data around and, thus, needs the abd data
tranform; the other group is for "data-less" i/o such as trim and cache
flush.

PR:		222288
Reported by:	Dan Nelson <dnelson@allantgroup.com>
Tested by:	Borja Marcos <borjam@sarenet.es>
MFC after:	10 days
This commit is contained in:
Andriy Gapon 2017-09-20 08:27:21 +00:00
parent 8c9377cde7
commit 3d5487d981
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323796

View File

@ -989,6 +989,15 @@ vdev_geom_io_intr(struct bio *bp)
break;
}
/*
* We have to split bio freeing into two parts, because the ABD code
* cannot be called in this context and vdev_op_io_done is not called
* for ZIO_TYPE_IOCTL zio-s.
*/
if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) {
g_destroy_bio(bp);
zio->io_bio = NULL;
}
zio_delay_interrupt(zio);
}
@ -1090,21 +1099,23 @@ vdev_geom_io_done(zio_t *zio)
{
struct bio *bp = zio->io_bio;
if (bp == NULL) {
ASSERT3S(zio->io_error, !=, 0);
IMPLY(zio->io_type == ZIO_TYPE_READ ||
zio->io_type == ZIO_TYPE_WRITE,
zio->io_error == ENXIO);
if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) {
ASSERT(bp == NULL);
return;
}
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);
if (bp == NULL) {
ASSERT3S(zio->io_error, ==, ENXIO);
return;
}
if (zio->io_type == ZIO_TYPE_READ)
abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
else
abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
g_destroy_bio(bp);
zio->io_bio = NULL;
}
static void