zvol_os: Keep better track of open count in close
zvol_geom_close gets a count of the number of close operations to do. Make sure we're always using this count to check if this will be the last close operation performed on the zvol. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Matt Macy <mmacy@FreeBSD.org> Signed-off-by: Ryan Moeller <ryan@iXsystems.com> Closes #11117
This commit is contained in:
parent
00a27515f0
commit
ef525e0841
|
@ -332,6 +332,7 @@ zvol_geom_close(struct g_provider *pp, int flag, int count)
|
|||
{
|
||||
zvol_state_t *zv;
|
||||
boolean_t drop_suspend = B_TRUE;
|
||||
int new_open_count;
|
||||
|
||||
rw_enter(&zvol_state_lock, ZVOL_RW_READER);
|
||||
zv = pp->private;
|
||||
|
@ -359,13 +360,15 @@ zvol_geom_close(struct g_provider *pp, int flag, int count)
|
|||
* (hold zv_suspend_lock) and respect proper lock acquisition
|
||||
* ordering - zv_suspend_lock before zv_state_lock
|
||||
*/
|
||||
if ((zv->zv_open_count - count) == 0) {
|
||||
new_open_count = zv->zv_open_count - count;
|
||||
if (new_open_count == 0) {
|
||||
if (!rw_tryenter(&zv->zv_suspend_lock, ZVOL_RW_READER)) {
|
||||
mutex_exit(&zv->zv_state_lock);
|
||||
rw_enter(&zv->zv_suspend_lock, ZVOL_RW_READER);
|
||||
mutex_enter(&zv->zv_state_lock);
|
||||
/* check to see if zv_suspend_lock is needed */
|
||||
if (zv->zv_open_count != 1) {
|
||||
new_open_count = zv->zv_open_count - count;
|
||||
if (new_open_count != 0) {
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
drop_suspend = B_FALSE;
|
||||
}
|
||||
|
@ -380,8 +383,7 @@ zvol_geom_close(struct g_provider *pp, int flag, int count)
|
|||
/*
|
||||
* You may get multiple opens, but only one close.
|
||||
*/
|
||||
zv->zv_open_count -= count;
|
||||
|
||||
zv->zv_open_count = new_open_count;
|
||||
if (zv->zv_open_count == 0) {
|
||||
ASSERT(ZVOL_RW_READ_HELD(&zv->zv_suspend_lock));
|
||||
zvol_last_close(zv);
|
||||
|
|
Loading…
Reference in New Issue