Skip to content

Commit

Permalink
Fix zpool on zvol deadlock
Browse files Browse the repository at this point in the history
Commit 65d5608 fixes the lock
inversion between spa_namespace_lock and bdev->bd_mutex but only
for the first user of spa_namespace_lock: dmu_objset_own().
Later spa_namespace_lock gets acquired by dsl_prop_get_integer()
though dsl_prop_get()->dsl_dataset_hold()->dsl_dir_open_spa()->
spa_open()->spa_open_common() without this "protection".  By
moving the mutex release after this second use, even this
acquisition of the lock is "protected" by the ERESTARTSYS trick.

Signed-off-by: Massimo Maggi <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #1220
  • Loading branch information
maxximino authored and behlendorf committed Jan 18, 2013
1 parent 7973e46 commit babf3f9
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,24 +920,20 @@ zvol_first_open(zvol_state_t *zv)

/* lie and say we're read-only */
error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, 1, zvol_tag, &os);

if (locked)
mutex_exit(&spa_namespace_lock);

if (error)
return (-error);
goto out_mutex;

error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
if (error) {
dmu_objset_disown(os, zvol_tag);
return (-error);
dmu_objset_disown(os, zvol_tag);
goto out_mutex;
}

zv->zv_objset = os;
error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf);
if (error) {
dmu_objset_disown(os, zvol_tag);
return (-error);
dmu_objset_disown(os, zvol_tag);
goto out_mutex;
}

set_capacity(zv->zv_disk, volsize >> 9);
Expand All @@ -946,13 +942,17 @@ zvol_first_open(zvol_state_t *zv)

VERIFY(dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL) == 0);
if (ro || dmu_objset_is_snapshot(os)) {
set_disk_ro(zv->zv_disk, 1);
zv->zv_flags |= ZVOL_RDONLY;
set_disk_ro(zv->zv_disk, 1);
zv->zv_flags |= ZVOL_RDONLY;
} else {
set_disk_ro(zv->zv_disk, 0);
zv->zv_flags &= ~ZVOL_RDONLY;
set_disk_ro(zv->zv_disk, 0);
zv->zv_flags &= ~ZVOL_RDONLY;
}

out_mutex:
if (locked)
mutex_exit(&spa_namespace_lock);

return (-error);
}

Expand Down

0 comments on commit babf3f9

Please sign in to comment.