diff options
author | Brian Behlendorf <[email protected]> | 2017-01-28 12:13:34 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2017-01-28 12:13:34 -0800 |
commit | a32494d22ac25c35c5d26eb0b2607ea68adb93cd (patch) | |
tree | 6aea4fc77bc90bc0ac3bcb542af2589bfbd37b88 /module/zfs/zio.c | |
parent | 3130b84e94717fe9aad67a14defe79bb7f10fa9f (diff) |
Fix suspend Godfather I/Os io_reexecute bits
After resuming a pool the godfather zio could have both the
ZIO_REEXECUTE_NOW and ZIO_REEXECUTE_SUSPEND bits set. This
can occur if some child zios set ZIO_REEXECUTE_NOW while
other set ZIO_REEXECUTE_SUSPEND. The godfather zio can
inherit both flags in zio_notify_parent().
The child zios which assigned the ZIO_REEXECUTE_SUSPEND flag
will be removed from the godfather's child list and added to
the spa->spa_suspend_zio_root child list. While child zios
with the ZIO_REEXECUTE_NOW bit set remain being monitored
by the godfather zio.
When the godfather zio executes zio_done() the presence of
the ZIO_REEXECUTE_SUSPEND bit results in all io_reexecute
being cleared. These child zios will then not be re-executed
and instead will be destroyed and lost.
The most straight forward way to address this situation is
to only clear the ZIO_REEXECUTE_SUSPEND bit and leave the
ZIO_REEXECUTE_NOW bit set.
Reviewed-by: George Melikov <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: yuxiang <[email protected]>
Diffstat (limited to 'module/zfs/zio.c')
-rw-r--r-- | module/zfs/zio.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/module/zfs/zio.c b/module/zfs/zio.c index b4f9b0b50..577ee7694 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -3885,7 +3885,7 @@ zio_done(zio_t *zio) */ if ((zio->io_flags & ZIO_FLAG_GODFATHER) && (zio->io_reexecute & ZIO_REEXECUTE_SUSPEND)) - zio->io_reexecute = 0; + zio->io_reexecute &= ~ZIO_REEXECUTE_SUSPEND; if (zio->io_reexecute) { /* |