summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2017-03-17 11:45:16 +0000
committermav <mav@FreeBSD.org>2017-03-17 11:45:16 +0000
commitd4eaf4dc21922349befba86e51d55edae9355763 (patch)
tree278cf3f72e7b4e5de5be332cbad0f7f3b66ed5dd /sys/cddl
parent9cf7da102c1f167d3008b79e26803aa3b9c3726c (diff)
downloadFreeBSD-src-d4eaf4dc21922349befba86e51d55edae9355763.zip
FreeBSD-src-d4eaf4dc21922349befba86e51d55edae9355763.tar.gz
MFC r309856: Postpone ZVOL media/block size caching till first open.
At least on FreeBSD there are no legal way to access media or get its size without opening device/provider first. Postponing this caching allows to skip several disk seeks per ZVOL/snapshot during import. For HDD pool with 1 ZVOL in dev mode with 1000 snapshots this reduces pool import time from 40 to 10 seconds.
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index f565681..ef07bad 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -594,14 +594,14 @@ zvol_create_minor(const char *name)
zfs_soft_state_t *zs;
zvol_state_t *zv;
objset_t *os;
- dmu_object_info_t doi;
#ifdef illumos
+ dmu_object_info_t doi;
minor_t minor = 0;
char chrbuf[30], blkbuf[30];
#else
struct g_provider *pp;
struct g_geom *gp;
- uint64_t volsize, mode;
+ uint64_t mode;
#endif
int error;
@@ -667,20 +667,12 @@ zvol_create_minor(const char *name)
zv = kmem_zalloc(sizeof(*zv), KM_SLEEP);
zv->zv_state = 0;
- error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
- if (error) {
- kmem_free(zv, sizeof(*zv));
- dmu_objset_disown(os, zvol_tag);
- mutex_exit(&zfsdev_state_lock);
- return (error);
- }
error = dsl_prop_get_integer(name,
zfs_prop_to_name(ZFS_PROP_VOLMODE), &mode, NULL);
if (error != 0 || mode == ZFS_VOLMODE_DEFAULT)
mode = volmode;
DROP_GIANT();
- zv->zv_volsize = volsize;
zv->zv_volmode = mode;
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
g_topology_lock();
@@ -690,7 +682,7 @@ zvol_create_minor(const char *name)
pp = g_new_providerf(gp, "%s/%s", ZVOL_DRIVER, name);
pp->flags |= G_PF_DIRECT_RECEIVE | G_PF_DIRECT_SEND;
pp->sectorsize = DEV_BSIZE;
- pp->mediasize = zv->zv_volsize;
+ pp->mediasize = 0;
pp->private = zv;
zv->zv_provider = pp;
@@ -733,10 +725,12 @@ zvol_create_minor(const char *name)
sizeof (rl_t), offsetof(rl_t, r_node));
list_create(&zv->zv_extents, sizeof (zvol_extent_t),
offsetof(zvol_extent_t, ze_node));
+#ifdef illumos
/* get and cache the blocksize */
error = dmu_object_info(os, ZVOL_OBJ, &doi);
ASSERT(error == 0);
zv->zv_volblocksize = doi.doi_data_block_size;
+#endif
if (spa_writeable(dmu_objset_spa(os))) {
if (zil_replay_disable)
@@ -828,6 +822,7 @@ zvol_remove_minor(const char *name)
int
zvol_first_open(zvol_state_t *zv)
{
+ dmu_object_info_t doi;
objset_t *os;
uint64_t volsize;
int error;
@@ -847,6 +842,15 @@ zvol_first_open(zvol_state_t *zv)
return (error);
}
+ /* get and cache the blocksize */
+ error = dmu_object_info(os, ZVOL_OBJ, &doi);
+ if (error) {
+ ASSERT(error == 0);
+ dmu_objset_disown(os, zvol_tag);
+ return (error);
+ }
+ zv->zv_volblocksize = doi.doi_data_block_size;
+
error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf);
if (error) {
dmu_objset_disown(os, zvol_tag);
OpenPOWER on IntegriCloud