Change 663745 by justing@justing_ns1_spectrabsd_integration on 2013/04/05 17:55:49 Large sector device support. Calculate the minimum blocksize of each metaslab class. Use the calculated value instead of SPA_MINBLOCKSIZE (512b) when determining the likelyhood of compression yeilding a reduction in physical space usage. sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h: When the group membership of a metaslab class changes (i.e. when a vdev is added or removed from a pool), walk the group list to determine the smallest block size currently available and record this in the metaslab class. sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c: Add the metaslab_class_get_minblocksize() accessor. sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c: In zio_compress_data(), take the minimum blocksize as an input parameter instead of assuming SPA_MINBLOCKSIZE. sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c: In zio_write_bp_init(), use the minimum blocksize of the normal metaslab class when compressing data. Affected files ... ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c#4 edit ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h#2 edit ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h#3 edit ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h#4 edit ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c#6 edit ... //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c#4 edit Differences ... ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c#4 (text) ==== @@ -165,6 +165,27 @@ atomic_add_64(&mc->mc_dspace, dspace_delta); } +void +metaslab_class_minblocksize_update(metaslab_class_t *mc) +{ + metaslab_group_t *mg; + vdev_t *vd; + uint64_t minashift = UINT64_MAX; + + if ((mg = mc->mc_rotor) == NULL) { + mc->mc_minblocksize = SPA_MINBLOCKSIZE; + return; + } + + do { + vd = mg->mg_vd; + if (vd->vdev_ashift < minashift) + minashift = vd->vdev_ashift; + } while ((mg = mg->mg_next) != mc->mc_rotor); + + mc->mc_minblocksize = 1ULL << minashift; +} + uint64_t metaslab_class_get_alloc(metaslab_class_t *mc) { @@ -189,6 +210,12 @@ return (spa_deflate(mc->mc_spa) ? mc->mc_dspace : mc->mc_space); } +uint64_t +metaslab_class_get_minblocksize(metaslab_class_t *mc) +{ + return (mc->mc_minblocksize); +} + /* * ========================================================================== * Metaslab groups @@ -280,6 +307,7 @@ mgnext->mg_prev = mg; } mc->mc_rotor = mg; + metaslab_class_minblocksize_update(mc); } void @@ -311,6 +339,7 @@ mg->mg_prev = NULL; mg->mg_next = NULL; + metaslab_class_minblocksize_update(mc); } static void ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h#2 (text) ==== @@ -69,6 +69,7 @@ extern uint64_t metaslab_class_get_space(metaslab_class_t *mc); extern uint64_t metaslab_class_get_dspace(metaslab_class_t *mc); extern uint64_t metaslab_class_get_deferred(metaslab_class_t *mc); +extern uint64_t metaslab_class_get_minblocksize(metaslab_class_t *mc); extern metaslab_group_t *metaslab_group_create(metaslab_class_t *mc, vdev_t *vd); ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab_impl.h#3 (text) ==== @@ -49,6 +49,7 @@ uint64_t mc_deferred; /**< total deferred frees */ uint64_t mc_space; /**< total space (alloc + free) */ uint64_t mc_dspace; /**< total deflated space */ + uint64_t mc_minblocksize; }; struct metaslab_group { ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h#4 (text) ==== @@ -76,7 +76,7 @@ * Compress and decompress data if necessary. */ extern size_t zio_compress_data(enum zio_compress c, void *src, void *dst, - size_t s_len); + size_t s_len, size_t minblocksize); extern int zio_decompress_data(enum zio_compress c, void *src, void *dst, size_t s_len, size_t d_len); ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c#6 (text) ==== @@ -1062,8 +1062,10 @@ } if (compress != ZIO_COMPRESS_OFF) { + metaslab_class_t *mc = spa_normal_class(spa); void *cbuf = zio_buf_alloc(lsize); - psize = zio_compress_data(compress, zio->io_data, cbuf, lsize); + psize = zio_compress_data(compress, zio->io_data, cbuf, lsize, + (size_t)metaslab_class_get_minblocksize(mc)); if (psize == 0 || psize == lsize) { compress = ZIO_COMPRESS_OFF; zio_buf_free(cbuf, lsize); ==== //SpectraBSD/stable/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c#4 (text) ==== @@ -91,7 +91,8 @@ } size_t -zio_compress_data(enum zio_compress c, void *src, void *dst, size_t s_len) +zio_compress_data(enum zio_compress c, void *src, void *dst, size_t s_len, + size_t minblocksize) { uint64_t *word, *word_end; size_t c_len, d_len, r_len; @@ -120,7 +121,7 @@ return (s_len); /* Compress at least 12.5% */ - d_len = P2ALIGN(s_len - (s_len >> 3), (size_t)SPA_MINBLOCKSIZE); + d_len = P2ALIGN(s_len - (s_len >> 3), minblocksize); if (d_len == 0) { ZCOMPSTAT_BUMP(zcompstat_skipped_minblocksize); return (s_len); @@ -137,14 +138,14 @@ * Cool. We compressed at least as much as we were hoping to. * For both security and repeatability, pad out the last sector. */ - r_len = P2ROUNDUP(c_len, (size_t)SPA_MINBLOCKSIZE); + r_len = P2ROUNDUP(c_len, minblocksize); if (r_len > c_len) { bzero((char *)dst + c_len, r_len - c_len); c_len = r_len; } ASSERT3U(c_len, <=, d_len); - ASSERT(P2PHASE(c_len, (size_t)SPA_MINBLOCKSIZE) == 0); + ASSERT(P2PHASE(c_len, minblocksize) == 0); return (c_len); }