diff options
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/zvol.c')
-rw-r--r-- | sys/contrib/openzfs/module/zfs/zvol.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c index 2b20b02e4942..7c6dae8650c7 100644 --- a/sys/contrib/openzfs/module/zfs/zvol.c +++ b/sys/contrib/openzfs/module/zfs/zvol.c @@ -772,7 +772,7 @@ zvol_setup_zv(zvol_state_t *zv) if (error) return (SET_ERROR(error)); - error = dnode_hold(os, ZVOL_OBJ, FTAG, &zv->zv_dn); + error = dnode_hold(os, ZVOL_OBJ, zv, &zv->zv_dn); if (error) return (SET_ERROR(error)); @@ -807,7 +807,7 @@ zvol_shutdown_zv(zvol_state_t *zv) zv->zv_zilog = NULL; - dnode_rele(zv->zv_dn, FTAG); + dnode_rele(zv->zv_dn, zv); zv->zv_dn = NULL; /* @@ -1376,7 +1376,9 @@ typedef struct zvol_volmode_cb_arg { static void zvol_set_volmode_impl(char *name, uint64_t volmode) { - fstrans_cookie_t cookie = spl_fstrans_mark(); + fstrans_cookie_t cookie; + uint64_t old_volmode; + zvol_state_t *zv; if (strchr(name, '@') != NULL) return; @@ -1386,9 +1388,18 @@ zvol_set_volmode_impl(char *name, uint64_t volmode) * this is necessary because our backing gendisk (zvol_state->zv_disk) * could be different when we set, for instance, volmode from "geom" * to "dev" (or vice versa). - * A possible optimization is to modify our consumers so we don't get - * called when "volmode" does not change. */ + zv = zvol_find_by_name(name, RW_NONE); + if (zv == NULL && volmode == ZFS_VOLMODE_NONE) + return; + if (zv != NULL) { + old_volmode = zv->zv_volmode; + mutex_exit(&zv->zv_state_lock); + if (old_volmode == volmode) + return; + zvol_wait_close(zv); + } + cookie = spl_fstrans_mark(); switch (volmode) { case ZFS_VOLMODE_NONE: (void) zvol_remove_minor_impl(name); @@ -1406,7 +1417,6 @@ zvol_set_volmode_impl(char *name, uint64_t volmode) (void) ops->zv_create_minor(name); break; } - spl_fstrans_unmark(cookie); } |