summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c14
-rw-r--r--usr/src/uts/common/io/lofi.c39
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,