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],