Author: mav
Date: Sun Dec 11 19:50:39 2016
New Revision: 309856
URL: https://svnweb.freebsd.org/changeset/base/309856

Log:
  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.
  
  MFC after:    2 weeks
  Sponsored by: iXsystems, Inc.

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c  Sun Dec 11 
19:24:41 2016        (r309855)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c  Sun Dec 11 
19:50:39 2016        (r309856)
@@ -585,14 +585,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;
 
@@ -658,20 +658,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();
@@ -681,7 +673,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;
@@ -724,10 +716,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)
@@ -819,6 +813,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;
@@ -838,6 +833,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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to