zio_add_child: collapse into a single function

The child locking difference is simple enough to handle with a boolean.
The actual work is more involved, and it's easy to forget to change
things in both places when experimenting. Just collapse them.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17382
This commit is contained in:
Rob Norris 2025-05-31 11:18:10 +10:00 committed by GitHub
parent 90011644ce
commit e8e602d987
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 36 deletions

View File

@ -621,7 +621,6 @@ extern zio_t *zio_walk_parents(zio_t *cio, zio_link_t **);
extern zio_t *zio_walk_children(zio_t *pio, zio_link_t **); extern zio_t *zio_walk_children(zio_t *pio, zio_link_t **);
extern zio_t *zio_unique_parent(zio_t *cio); extern zio_t *zio_unique_parent(zio_t *cio);
extern void zio_add_child(zio_t *pio, zio_t *cio); extern void zio_add_child(zio_t *pio, zio_t *cio);
extern void zio_add_child_first(zio_t *pio, zio_t *cio);
extern void *zio_buf_alloc(size_t size); extern void *zio_buf_alloc(size_t size);
extern void zio_buf_free(void *buf, size_t size); extern void zio_buf_free(void *buf, size_t size);

View File

@ -744,8 +744,8 @@ zio_unique_parent(zio_t *cio)
return (pio); return (pio);
} }
void static void
zio_add_child(zio_t *pio, zio_t *cio) zio_add_child_impl(zio_t *pio, zio_t *cio, boolean_t first)
{ {
/* /*
* Logical I/Os can have logical, gang, or vdev children. * Logical I/Os can have logical, gang, or vdev children.
@ -765,6 +765,10 @@ zio_add_child(zio_t *pio, zio_t *cio)
zl->zl_child = cio; zl->zl_child = cio;
mutex_enter(&pio->io_lock); mutex_enter(&pio->io_lock);
if (first)
ASSERT(list_is_empty(&cio->io_parent_list));
else
mutex_enter(&cio->io_lock); mutex_enter(&cio->io_lock);
ASSERT(pio->io_state[ZIO_WAIT_DONE] == 0); ASSERT(pio->io_state[ZIO_WAIT_DONE] == 0);
@ -776,44 +780,22 @@ zio_add_child(zio_t *pio, zio_t *cio)
list_insert_head(&pio->io_child_list, zl); list_insert_head(&pio->io_child_list, zl);
list_insert_head(&cio->io_parent_list, zl); list_insert_head(&cio->io_parent_list, zl);
if (!first)
mutex_exit(&cio->io_lock); mutex_exit(&cio->io_lock);
mutex_exit(&pio->io_lock); mutex_exit(&pio->io_lock);
} }
void void
zio_add_child(zio_t *pio, zio_t *cio)
{
zio_add_child_impl(pio, cio, B_FALSE);
}
static void
zio_add_child_first(zio_t *pio, zio_t *cio) zio_add_child_first(zio_t *pio, zio_t *cio)
{ {
/* zio_add_child_impl(pio, cio, B_TRUE);
* Logical I/Os can have logical, gang, or vdev children.
* Gang I/Os can have gang or vdev children.
* Vdev I/Os can only have vdev children.
* The following ASSERT captures all of these constraints.
*/
ASSERT3S(cio->io_child_type, <=, pio->io_child_type);
/* Parent should not have READY stage if child doesn't have it. */
IMPLY((cio->io_pipeline & ZIO_STAGE_READY) == 0 &&
(cio->io_child_type != ZIO_CHILD_VDEV),
(pio->io_pipeline & ZIO_STAGE_READY) == 0);
zio_link_t *zl = kmem_cache_alloc(zio_link_cache, KM_SLEEP);
zl->zl_parent = pio;
zl->zl_child = cio;
ASSERT(list_is_empty(&cio->io_parent_list));
list_insert_head(&cio->io_parent_list, zl);
mutex_enter(&pio->io_lock);
ASSERT(pio->io_state[ZIO_WAIT_DONE] == 0);
uint64_t *countp = pio->io_children[cio->io_child_type];
for (int w = 0; w < ZIO_WAIT_TYPES; w++)
countp[w] += !cio->io_state[w];
list_insert_head(&pio->io_child_list, zl);
mutex_exit(&pio->io_lock);
} }
static void static void