summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-11-25 16:32:07 +0000
committermm <mm@FreeBSD.org>2012-11-25 16:32:07 +0000
commit3a0bfecf052237768517963f169d0797e2978f59 (patch)
tree35856bc2042e24d142ce48d78e222231eeb62646 /cddl
parent081fe7e2837cd17182c14d95cfe3d9cf8b82e05d (diff)
downloadFreeBSD-src-3a0bfecf052237768517963f169d0797e2978f59.zip
FreeBSD-src-3a0bfecf052237768517963f169d0797e2978f59.tar.gz
MFV r243013 and r243267:
Import the zio nop-write improvement from Illumos. To reduce I/O, nop-write omits overwriting data if the checksum (cryptographically secure) of new data matches the checksum of existing data. It also saves space if snapshots are in use. It currently works only on datasets with enabled compression, disabled deduplication and sha256 checksums. IllumOS 13887:196932ec9e6a and 13888:7204b3392a58 3236 zio nop-write References: https://www.illumos.org/issues/3236 MFC after: 2 weeks
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/ztest/ztest.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
index 224c737..9c38b3f 100644
--- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c
+++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c
@@ -204,6 +204,7 @@ enum ztest_io_type {
ZTEST_IO_WRITE_ZEROES,
ZTEST_IO_TRUNCATE,
ZTEST_IO_SETATTR,
+ ZTEST_IO_REWRITE,
ZTEST_IO_TYPES
};
@@ -1867,6 +1868,12 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
DMU_READ_NO_PREFETCH);
if (error == 0) {
+ blkptr_t *obp = dmu_buf_get_blkptr(db);
+ if (obp) {
+ ASSERT(BP_IS_HOLE(bp));
+ *bp = *obp;
+ }
+
zgd->zgd_db = db;
zgd->zgd_bp = bp;
@@ -2012,6 +2019,9 @@ ztest_remove(ztest_ds_t *zd, ztest_od_t *od, int count)
continue;
}
+ /*
+ * No object was found.
+ */
if (od->od_object == 0)
continue;
@@ -2127,6 +2137,7 @@ ztest_prealloc(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
static void
ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
{
+ int err;
ztest_block_tag_t wbt;
dmu_object_info_t doi;
enum ztest_io_type io_type;
@@ -2179,6 +2190,25 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
case ZTEST_IO_SETATTR:
(void) ztest_setattr(zd, object);
break;
+
+ case ZTEST_IO_REWRITE:
+ (void) rw_rdlock(&ztest_name_lock);
+ err = ztest_dsl_prop_set_uint64(zd->zd_name,
+ ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
+ B_FALSE);
+ VERIFY(err == 0 || err == ENOSPC);
+ err = ztest_dsl_prop_set_uint64(zd->zd_name,
+ ZFS_PROP_COMPRESSION,
+ ztest_random_dsl_prop(ZFS_PROP_COMPRESSION),
+ B_FALSE);
+ VERIFY(err == 0 || err == ENOSPC);
+ (void) rw_unlock(&ztest_name_lock);
+
+ VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
+ DMU_READ_NO_PREFETCH));
+
+ (void) ztest_write(zd, object, offset, blocksize, data);
+ break;
}
(void) rw_unlock(&zd->zd_zilog_lock);
@@ -2266,7 +2296,12 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
{
objset_t *os = zd->zd_os;
- VERIFY(mutex_lock(&zd->zd_dirobj_lock) == 0);
+ /*
+ * We grab the zd_dirobj_lock to ensure that no other thread is
+ * updating the zil (i.e. adding in-memory log records) and the
+ * zd_zilog_lock to block any I/O.
+ */
+ VERIFY0(mutex_lock(&zd->zd_dirobj_lock));
(void) rw_wrlock(&zd->zd_zilog_lock);
/* zfsvfs_teardown() */
@@ -4925,8 +4960,8 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
*/
for (int i = 0; i < copies; i++) {
uint64_t offset = i * blocksize;
- VERIFY(dmu_buf_hold(os, object, offset, FTAG, &db,
- DMU_READ_NO_PREFETCH) == 0);
+ VERIFY0(dmu_buf_hold(os, object, offset, FTAG, &db,
+ DMU_READ_NO_PREFETCH));
ASSERT(db->db_offset == offset);
ASSERT(db->db_size == blocksize);
ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) ||
@@ -4942,8 +4977,8 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
/*
* Find out what block we got.
*/
- VERIFY(dmu_buf_hold(os, object, 0, FTAG, &db,
- DMU_READ_NO_PREFETCH) == 0);
+ VERIFY0(dmu_buf_hold(os, object, 0, FTAG, &db,
+ DMU_READ_NO_PREFETCH));
blk = *((dmu_buf_impl_t *)db)->db_blkptr;
dmu_buf_rele(db, FTAG);
@@ -5621,6 +5656,8 @@ ztest_freeze(void)
kernel_init(FREAD | FWRITE);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
VERIFY3U(0, ==, ztest_dataset_open(0));
+ spa->spa_debug = B_TRUE;
+ ztest_spa = spa;
/*
* Force the first log block to be transactionally allocated.
OpenPOWER on IntegriCloud