Print this page
Possibility to physically reserve space without writing leaf blocks
@@ -956,10 +956,16 @@
static int
zio_read_bp_init(zio_t *zio)
{
blkptr_t *bp = zio->io_bp;
+ if (!BP_IS_EMBEDDED(bp) && BP_GET_PROP_RESERVATION(bp)) {
+ memset(zio->io_orig_data, 0, zio->io_orig_size);
+ zio->io_pipeline = ZIO_INTERLOCK_STAGES;
+ return (ZIO_PIPELINE_CONTINUE);
+ }
+
if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF &&
zio->io_child_type == ZIO_CHILD_LOGICAL &&
!(zio->io_flags & ZIO_FLAG_RAW)) {
uint64_t psize =
BP_IS_EMBEDDED(bp) ? BPE_GET_PSIZE(bp) : BP_GET_PSIZE(bp);
@@ -991,10 +997,12 @@
zio_write_bp_init(zio_t *zio)
{
spa_t *spa = zio->io_spa;
zio_prop_t *zp = &zio->io_prop;
enum zio_compress compress = zp->zp_compress;
+ enum zio_checksum checksum = zp->zp_checksum;
+ uint8_t dedup = zp->zp_dedup;
blkptr_t *bp = zio->io_bp;
uint64_t lsize = zio->io_size;
uint64_t psize = lsize;
int pass = 1;
@@ -1009,10 +1017,16 @@
if (!IO_IS_ALLOCATING(zio))
return (ZIO_PIPELINE_CONTINUE);
ASSERT(zio->io_child_type != ZIO_CHILD_DDT);
+ if (zp->zp_zero_write && !(zio->io_pipeline & ZIO_GANG_STAGES)) {
+ dedup = B_FALSE;
+ compress = ZIO_COMPRESS_OFF;
+ checksum = ZIO_CHECKSUM_OFF;
+ }
+
if (zio->io_bp_override) {
ASSERT(bp->blk_birth != zio->io_txg);
ASSERT(BP_GET_DEDUP(zio->io_bp_override) == 0);
*bp = *zio->io_bp_override;
@@ -1032,17 +1046,17 @@
return (ZIO_PIPELINE_CONTINUE);
}
ASSERT(!zp->zp_nopwrite);
- if (BP_IS_HOLE(bp) || !zp->zp_dedup)
+ if (BP_IS_HOLE(bp) || !dedup)
return (ZIO_PIPELINE_CONTINUE);
- ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup ||
+ ASSERT(zio_checksum_table[checksum].ci_dedup ||
zp->zp_dedup_verify);
- if (BP_GET_CHECKSUM(bp) == zp->zp_checksum) {
+ if (BP_GET_CHECKSUM(bp) == checksum) {
BP_SET_DEDUP(bp, 1);
zio->io_pipeline |= ZIO_STAGE_DDT_WRITE;
return (ZIO_PIPELINE_CONTINUE);
}
zio->io_bp_override = NULL;
@@ -1151,10 +1165,21 @@
BP_SET_PSIZE(bp, psize);
BP_SET_COMPRESS(bp, compress);
BP_SET_CHECKSUM(bp, zp->zp_checksum);
BP_SET_DEDUP(bp, zp->zp_dedup);
BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
+ if (zp->zp_zero_write && !(zio->io_pipeline & ZIO_GANG_STAGES)) {
+ boolean_t need_allocate = B_FALSE;
+ if (zio->io_pipeline & ZIO_STAGE_DVA_ALLOCATE)
+ need_allocate = B_TRUE;
+ zio->io_pipeline = ZIO_INTERLOCK_STAGES;
+ if (need_allocate)
+ zio->io_pipeline |= ZIO_STAGE_DVA_ALLOCATE;
+ BP_SET_PROP_RESERVATION(bp, 1);
+ } else {
+ BP_SET_PROP_RESERVATION(bp, 0);
+ }
if (zp->zp_dedup) {
ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
zio->io_pipeline = ZIO_DDT_WRITE_PIPELINE;
}
@@ -1869,10 +1894,11 @@
zp.zp_type = DMU_OT_NONE;
zp.zp_level = 0;
zp.zp_copies = gio->io_prop.zp_copies;
zp.zp_dedup = B_FALSE;
zp.zp_dedup_verify = B_FALSE;
+ zp.zp_zero_write = B_FALSE;
zp.zp_nopwrite = B_FALSE;
zio_nowait(zio_write(zio, spa, txg, &gbh->zg_blkptr[g],
(char *)pio->io_data + (pio->io_size - resid), lsize, &zp,
zio_write_gang_member_ready, NULL, NULL, &gn->gn_child[g],