Mercurial > illumos > illumos-gate
diff usr/src/uts/common/io/lvm/mirror/mirror.c @ 7975:f7037f0cdac8
6701425 SVM: Multi-owner disksets do not work well with filesystems
author | Achim Maurer <Achim.Maurer@Sun.COM> |
---|---|
date | Thu, 30 Oct 2008 13:03:05 -0700 |
parents | 8599a7568728 |
children | 89d32dfdae6e |
line wrap: on
line diff
--- a/usr/src/uts/common/io/lvm/mirror/mirror.c Thu Oct 30 13:25:29 2008 -0600 +++ b/usr/src/uts/common/io/lvm/mirror/mirror.c Thu Oct 30 13:03:05 2008 -0700 @@ -3400,6 +3400,8 @@ flag |= MD_STR_WAR; if (ps->ps_flags & MD_MPS_ABR) flag |= MD_STR_ABR; + if (ps->ps_flags & MD_MPS_BLOCKABLE_IO) + flag |= MD_STR_BLOCK_OK; /* * If this is a resync read, ie MD_STR_DIRTY_RD not set, set @@ -3709,14 +3711,19 @@ * suspend all writes until the state change has been made. As it is * not possible to read from the target of a resync, there is no need * to suspend resync writes. + * Note that we only block here if the caller can handle a busy-wait. + * The MD_STR_BLOCK_OK flag is set for daemon_io originated i/o only. */ if (!(flag & MD_STR_WAR)) { - mutex_enter(&un->un_suspend_wr_mx); - while (un->un_suspend_wr_flag) { - cv_wait(&un->un_suspend_wr_cv, &un->un_suspend_wr_mx); + if (flag & MD_STR_BLOCK_OK) { + mutex_enter(&un->un_suspend_wr_mx); + while (un->un_suspend_wr_flag) { + cv_wait(&un->un_suspend_wr_cv, + &un->un_suspend_wr_mx); + } + mutex_exit(&un->un_suspend_wr_mx); } - mutex_exit(&un->un_suspend_wr_mx); (void) md_unit_readerlock(ui); } @@ -3765,6 +3772,25 @@ ps->ps_changecnt = un->un_changecnt; /* + * Check for suspended writes here. This is where we can defer the + * write request to the daemon_io queue which will then call us with + * the MD_STR_BLOCK_OK flag set and we'll busy-wait (if necessary) at + * the top of this routine. + */ + if (!(flag & MD_STR_WAR) && !(flag & MD_STR_BLOCK_OK)) { + mutex_enter(&un->un_suspend_wr_mx); + if (un->un_suspend_wr_flag) { + ps->ps_flags |= MD_MPS_BLOCKABLE_IO; + mutex_exit(&un->un_suspend_wr_mx); + md_unit_readerexit(ui); + daemon_request(&md_mirror_daemon, daemon_io, + (daemon_queue_t *)ps, REQ_OLD); + return; + } + mutex_exit(&un->un_suspend_wr_mx); + } + + /* * If not MN owner and this is an ABR write, make sure the current * resync region is in the overlaps tree */