diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/zfs/spa.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/io/lofi.c | 39 |
2 files changed, 23 insertions, 30 deletions
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c index 069d2cafc7..29b7bacfc8 100644 --- a/usr/src/uts/common/fs/zfs/spa.c +++ b/usr/src/uts/common/fs/zfs/spa.c @@ -4062,23 +4062,21 @@ spa_vdev_resilver_done(spa_t *spa) } /* - * Update the stored path or FRU for this vdev. Dirty the vdev configuration, - * relying on spa_vdev_enter/exit() to synchronize the labels and cache. + * Update the stored path or FRU for this vdev. */ int spa_vdev_set_common(spa_t *spa, uint64_t guid, const char *value, boolean_t ispath) { vdev_t *vd; - uint64_t txg; - txg = spa_vdev_enter(spa); + spa_vdev_state_enter(spa, SCL_ALL); if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) - return (spa_vdev_exit(spa, NULL, txg, ENOENT)); + return (spa_vdev_state_exit(spa, NULL, ENOENT)); if (!vd->vdev_ops->vdev_op_leaf) - return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); + return (spa_vdev_state_exit(spa, NULL, ENOTSUP)); if (ispath) { spa_strfree(vd->vdev_path); @@ -4089,9 +4087,7 @@ spa_vdev_set_common(spa_t *spa, uint64_t guid, const char *value, vd->vdev_fru = spa_strdup(value); } - vdev_config_dirty(vd->vdev_top); - - return (spa_vdev_exit(spa, NULL, txg, 0)); + return (spa_vdev_state_exit(spa, vd, 0)); } int diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c index b5bc646b48..b3684b66de 100644 --- a/usr/src/uts/common/io/lofi.c +++ b/usr/src/uts/common/io/lofi.c @@ -2237,28 +2237,14 @@ lofi_unmap_file(dev_t dev, struct lofi_ioctl *ulip, int byfilename, */ if (is_opened(lsp)) { if (klip->li_force) { - /* - * XXX: the section marked here should probably be - * carefully incorporated into lofi_free_handle(); - * afterward just replace this section with: - * lofi_free_handle(dev, minor, lsp, credp); - * and clean up lofi_unmap_file() a bit more - */ - lofi_free_crypto(lsp); - mutex_enter(&lsp->ls_vp_lock); lsp->ls_vp_closereq = B_TRUE; + /* wake up any threads waiting on dkiocstate */ + cv_broadcast(&lsp->ls_vp_cv); while (lsp->ls_vp_iocount > 0) cv_wait(&lsp->ls_vp_cv, &lsp->ls_vp_lock); - (void) VOP_CLOSE(lsp->ls_vp, lsp->ls_openflag, 1, 0, - credp, NULL); - VN_RELE(lsp->ls_vp); - lsp->ls_vp = NULL; - cv_broadcast(&lsp->ls_vp_cv); mutex_exit(&lsp->ls_vp_lock); - /* - * XXX: to here - */ + lofi_free_handle(dev, minor, lsp, credp); klip->li_minor = minor; mutex_exit(&lofi_lock); @@ -2425,9 +2411,13 @@ lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, } } + mutex_enter(&lofi_lock); lsp = ddi_get_soft_state(lofi_statep, minor); - if (lsp == NULL) + if (lsp == NULL || lsp->ls_vp_closereq) { + mutex_exit(&lofi_lock); return (ENXIO); + } + mutex_exit(&lofi_lock); /* * We explicitly allow DKIOCSTATE, but all other ioctls should fail with @@ -2482,20 +2472,27 @@ lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, return (EFAULT); mutex_enter(&lsp->ls_vp_lock); - while ((dkstate == DKIO_INSERTED && lsp->ls_vp != NULL) || - (dkstate == DKIO_DEV_GONE && lsp->ls_vp == NULL)) { + lsp->ls_vp_iocount++; + while (((dkstate == DKIO_INSERTED && lsp->ls_vp != NULL) || + (dkstate == DKIO_DEV_GONE && lsp->ls_vp == NULL)) && + !lsp->ls_vp_closereq) { /* * By virtue of having the device open, we know that * 'lsp' will remain valid when we return. */ if (!cv_wait_sig(&lsp->ls_vp_cv, &lsp->ls_vp_lock)) { + lsp->ls_vp_iocount--; + cv_broadcast(&lsp->ls_vp_cv); mutex_exit(&lsp->ls_vp_lock); return (EINTR); } } - dkstate = (lsp->ls_vp != NULL ? DKIO_INSERTED : DKIO_DEV_GONE); + dkstate = (!lsp->ls_vp_closereq && lsp->ls_vp != NULL ? + DKIO_INSERTED : DKIO_DEV_GONE); + lsp->ls_vp_iocount--; + cv_broadcast(&lsp->ls_vp_cv); mutex_exit(&lsp->ls_vp_lock); if (ddi_copyout(&dkstate, (void *)arg, |