Skip to content

Commit

Permalink
Fix vdev_probe() call outside SCL_STATE_ALL lock
Browse files Browse the repository at this point in the history
When an IO fails then zio_vdev_io_done() can call vdev_probe()
to determine the health of the vdev.  This is safe as long as
the original zio was submitted with zio_wait() and holds the
SCL_STATE_ALL lock over the operation.

If zio_no_wait() was used then the done callback will submit
the probe IO outside the SCL_STATE_ALL lock and hit this
ASSERT in zio_create()

  ASSERT(!vd || spa_config_held(spa, SCL_STATE_ALL, RW_READER));

Resolve the issue by only allowing vdev_probe() to be called
when there's a waiter indicating the caller is using zio_wait().
This assumes that caller is still holding SCL_STATE_ALL.

This issue isn't MMP specific but was surfaced when testing.
Without this patch it can be reproduced by running:

  zpool set multihost on <pool>
  zinject -d <vdev> -e io -T write -f 50 <pool> -L uber

Reviewed-by: Olaf Faaland <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Don Brady <[email protected]>
Closes openzfs#745
Closes openzfs#6279
  • Loading branch information
behlendorf authored and ofaaland committed Jul 18, 2017
1 parent 12fa046 commit fb8d164
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3325,7 +3325,7 @@ zio_vdev_io_done(zio_t *zio)

ops->vdev_op_io_done(zio);

if (unexpected_error)
if (unexpected_error && zio->io_waiter != NULL)
VERIFY(vdev_probe(vd, zio) == NULL);

return (ZIO_PIPELINE_CONTINUE);
Expand Down

0 comments on commit fb8d164

Please sign in to comment.