FreeBSD: Simplify zvol_geom_open and zvol_cdev_open
We can consolidate the unlocking procedure into one place by starting with drop_suspend set to B_FALSE and moving the open count check up. While here, a little code cleanup. Match the out labels between zvol_geom_open and zvol_cdev_open, and add a missing period in some comments. Reviewed-by: Matt Macy <mmacy@FreeBSD.org> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Signed-off-by: Ryan Moeller <ryan@iXsystems.com> Closes #11175
This commit is contained in:
parent
2186ed33f1
commit
7b42f09049
|
@ -209,7 +209,7 @@ zvol_geom_open(struct g_provider *pp, int flag, int count)
|
||||||
{
|
{
|
||||||
zvol_state_t *zv;
|
zvol_state_t *zv;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
boolean_t drop_suspend = B_TRUE;
|
boolean_t drop_suspend = B_FALSE;
|
||||||
boolean_t drop_namespace = B_FALSE;
|
boolean_t drop_namespace = B_FALSE;
|
||||||
|
|
||||||
if (!zpool_on_zvol && tsd_get(zfs_geom_probe_vdev_key) != NULL) {
|
if (!zpool_on_zvol && tsd_get(zfs_geom_probe_vdev_key) != NULL) {
|
||||||
|
@ -228,16 +228,14 @@ retry:
|
||||||
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
||||||
zv = pp->private;
|
zv = pp->private;
|
||||||
if (zv == NULL) {
|
if (zv == NULL) {
|
||||||
if (drop_namespace)
|
err = SET_ERROR(ENXIO);
|
||||||
mutex_exit(&spa_namespace_lock);
|
goto out_locked;
|
||||||
rw_exit(&zvol_state_lock);
|
|
||||||
return (SET_ERROR(ENXIO));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
|
if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
|
||||||
/*
|
/*
|
||||||
* We need to guarantee that the namespace lock is held
|
* We need to guarantee that the namespace lock is held
|
||||||
* to avoid spurious failures in zvol_first_open
|
* to avoid spurious failures in zvol_first_open.
|
||||||
*/
|
*/
|
||||||
drop_namespace = B_TRUE;
|
drop_namespace = B_TRUE;
|
||||||
if (!mutex_tryenter(&spa_namespace_lock)) {
|
if (!mutex_tryenter(&spa_namespace_lock)) {
|
||||||
|
@ -256,6 +254,7 @@ retry:
|
||||||
* ordering - zv_suspend_lock before zv_state_lock
|
* ordering - zv_suspend_lock before zv_state_lock
|
||||||
*/
|
*/
|
||||||
if (zv->zv_open_count == 0) {
|
if (zv->zv_open_count == 0) {
|
||||||
|
drop_suspend = B_TRUE;
|
||||||
if (!rw_tryenter(&zv->zv_suspend_lock, ZVOL_RW_READER)) {
|
if (!rw_tryenter(&zv->zv_suspend_lock, ZVOL_RW_READER)) {
|
||||||
mutex_exit(&zv->zv_state_lock);
|
mutex_exit(&zv->zv_state_lock);
|
||||||
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
|
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
|
||||||
|
@ -266,8 +265,6 @@ retry:
|
||||||
drop_suspend = B_FALSE;
|
drop_suspend = B_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
drop_suspend = B_FALSE;
|
|
||||||
}
|
}
|
||||||
rw_exit(&zvol_state_lock);
|
rw_exit(&zvol_state_lock);
|
||||||
|
|
||||||
|
@ -277,7 +274,7 @@ retry:
|
||||||
ASSERT(ZVOL_RW_READ_HELD(&zv->zv_suspend_lock));
|
ASSERT(ZVOL_RW_READ_HELD(&zv->zv_suspend_lock));
|
||||||
err = zvol_first_open(zv, !(flag & FWRITE));
|
err = zvol_first_open(zv, !(flag & FWRITE));
|
||||||
if (err)
|
if (err)
|
||||||
goto out_mutex;
|
goto out_locked;
|
||||||
pp->mediasize = zv->zv_volsize;
|
pp->mediasize = zv->zv_volsize;
|
||||||
pp->stripeoffset = 0;
|
pp->stripeoffset = 0;
|
||||||
pp->stripesize = zv->zv_volblocksize;
|
pp->stripesize = zv->zv_volblocksize;
|
||||||
|
@ -290,34 +287,27 @@ retry:
|
||||||
if ((flag & FWRITE) && ((zv->zv_flags & ZVOL_RDONLY) ||
|
if ((flag & FWRITE) && ((zv->zv_flags & ZVOL_RDONLY) ||
|
||||||
dmu_objset_incompatible_encryption_version(zv->zv_objset))) {
|
dmu_objset_incompatible_encryption_version(zv->zv_objset))) {
|
||||||
err = SET_ERROR(EROFS);
|
err = SET_ERROR(EROFS);
|
||||||
goto out_open_count;
|
goto out_opened;
|
||||||
}
|
}
|
||||||
if (zv->zv_flags & ZVOL_EXCL) {
|
if (zv->zv_flags & ZVOL_EXCL) {
|
||||||
err = SET_ERROR(EBUSY);
|
err = SET_ERROR(EBUSY);
|
||||||
goto out_open_count;
|
goto out_opened;
|
||||||
}
|
}
|
||||||
#ifdef FEXCL
|
#ifdef FEXCL
|
||||||
if (flag & FEXCL) {
|
if (flag & FEXCL) {
|
||||||
if (zv->zv_open_count != 0) {
|
if (zv->zv_open_count != 0) {
|
||||||
err = SET_ERROR(EBUSY);
|
err = SET_ERROR(EBUSY);
|
||||||
goto out_open_count;
|
goto out_opened;
|
||||||
}
|
}
|
||||||
zv->zv_flags |= ZVOL_EXCL;
|
zv->zv_flags |= ZVOL_EXCL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
zv->zv_open_count += count;
|
zv->zv_open_count += count;
|
||||||
if (drop_namespace)
|
out_opened:
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
mutex_exit(&zv->zv_state_lock);
|
|
||||||
if (drop_suspend)
|
|
||||||
rw_exit(&zv->zv_suspend_lock);
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
out_open_count:
|
|
||||||
if (zv->zv_open_count == 0)
|
if (zv->zv_open_count == 0)
|
||||||
zvol_last_close(zv);
|
zvol_last_close(zv);
|
||||||
out_mutex:
|
out_locked:
|
||||||
if (drop_namespace)
|
if (drop_namespace)
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
mutex_exit(&zv->zv_state_lock);
|
mutex_exit(&zv->zv_state_lock);
|
||||||
|
@ -826,23 +816,21 @@ zvol_cdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
||||||
zvol_state_t *zv;
|
zvol_state_t *zv;
|
||||||
struct zvol_state_dev *zsd;
|
struct zvol_state_dev *zsd;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
boolean_t drop_suspend = B_TRUE;
|
boolean_t drop_suspend = B_FALSE;
|
||||||
boolean_t drop_namespace = B_FALSE;
|
boolean_t drop_namespace = B_FALSE;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
||||||
zv = dev->si_drv2;
|
zv = dev->si_drv2;
|
||||||
if (zv == NULL) {
|
if (zv == NULL) {
|
||||||
if (drop_namespace)
|
err = SET_ERROR(ENXIO);
|
||||||
mutex_exit(&spa_namespace_lock);
|
goto out_locked;
|
||||||
rw_exit(&zvol_state_lock);
|
|
||||||
return (SET_ERROR(ENXIO));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
|
if (zv->zv_open_count == 0 && !mutex_owned(&spa_namespace_lock)) {
|
||||||
/*
|
/*
|
||||||
* We need to guarantee that the namespace lock is held
|
* We need to guarantee that the namespace lock is held
|
||||||
* to avoid spurious failures in zvol_first_open
|
* to avoid spurious failures in zvol_first_open.
|
||||||
*/
|
*/
|
||||||
drop_namespace = B_TRUE;
|
drop_namespace = B_TRUE;
|
||||||
if (!mutex_tryenter(&spa_namespace_lock)) {
|
if (!mutex_tryenter(&spa_namespace_lock)) {
|
||||||
|
@ -861,6 +849,7 @@ retry:
|
||||||
* ordering - zv_suspend_lock before zv_state_lock
|
* ordering - zv_suspend_lock before zv_state_lock
|
||||||
*/
|
*/
|
||||||
if (zv->zv_open_count == 0) {
|
if (zv->zv_open_count == 0) {
|
||||||
|
drop_suspend = B_TRUE;
|
||||||
if (!rw_tryenter(&zv->zv_suspend_lock, ZVOL_RW_READER)) {
|
if (!rw_tryenter(&zv->zv_suspend_lock, ZVOL_RW_READER)) {
|
||||||
mutex_exit(&zv->zv_state_lock);
|
mutex_exit(&zv->zv_state_lock);
|
||||||
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
|
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
|
||||||
|
@ -871,8 +860,6 @@ retry:
|
||||||
drop_suspend = B_FALSE;
|
drop_suspend = B_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
drop_suspend = B_FALSE;
|
|
||||||
}
|
}
|
||||||
rw_exit(&zvol_state_lock);
|
rw_exit(&zvol_state_lock);
|
||||||
|
|
||||||
|
@ -911,13 +898,6 @@ retry:
|
||||||
(zv->zv_flags & ZVOL_WRITTEN_TO) != 0)
|
(zv->zv_flags & ZVOL_WRITTEN_TO) != 0)
|
||||||
zil_async_to_sync(zv->zv_zilog, ZVOL_OBJ);
|
zil_async_to_sync(zv->zv_zilog, ZVOL_OBJ);
|
||||||
}
|
}
|
||||||
if (drop_namespace)
|
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
mutex_exit(&zv->zv_state_lock);
|
|
||||||
if (drop_suspend)
|
|
||||||
rw_exit(&zv->zv_suspend_lock);
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
out_opened:
|
out_opened:
|
||||||
if (zv->zv_open_count == 0)
|
if (zv->zv_open_count == 0)
|
||||||
zvol_last_close(zv);
|
zvol_last_close(zv);
|
||||||
|
|
Loading…
Reference in New Issue