Print this page
Possibility to physically reserve space without writing leaf blocks

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zio.c
          +++ new/usr/src/uts/common/fs/zfs/zio.c
↓ open down ↓ 950 lines elided ↑ open up ↑
 951  951   * ==========================================================================
 952  952   * Prepare to read and write logical blocks
 953  953   * ==========================================================================
 954  954   */
 955  955  
 956  956  static int
 957  957  zio_read_bp_init(zio_t *zio)
 958  958  {
 959  959          blkptr_t *bp = zio->io_bp;
 960  960  
      961 +        if (!BP_IS_EMBEDDED(bp) && BP_GET_PROP_RESERVATION(bp)) {
      962 +                memset(zio->io_orig_data, 0, zio->io_orig_size);
      963 +                zio->io_pipeline = ZIO_INTERLOCK_STAGES;
      964 +                return (ZIO_PIPELINE_CONTINUE);
      965 +        }
      966 +
 961  967          if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF &&
 962  968              zio->io_child_type == ZIO_CHILD_LOGICAL &&
 963  969              !(zio->io_flags & ZIO_FLAG_RAW)) {
 964  970                  uint64_t psize =
 965  971                      BP_IS_EMBEDDED(bp) ? BPE_GET_PSIZE(bp) : BP_GET_PSIZE(bp);
 966  972                  void *cbuf = zio_buf_alloc(psize);
 967  973  
 968  974                  zio_push_transform(zio, cbuf, psize, psize, zio_decompress);
 969  975          }
 970  976  
↓ open down ↓ 15 lines elided ↑ open up ↑
 986  992  
 987  993          return (ZIO_PIPELINE_CONTINUE);
 988  994  }
 989  995  
 990  996  static int
 991  997  zio_write_bp_init(zio_t *zio)
 992  998  {
 993  999          spa_t *spa = zio->io_spa;
 994 1000          zio_prop_t *zp = &zio->io_prop;
 995 1001          enum zio_compress compress = zp->zp_compress;
     1002 +        enum zio_checksum checksum = zp->zp_checksum;
     1003 +        uint8_t dedup = zp->zp_dedup;
 996 1004          blkptr_t *bp = zio->io_bp;
 997 1005          uint64_t lsize = zio->io_size;
 998 1006          uint64_t psize = lsize;
 999 1007          int pass = 1;
1000 1008  
1001 1009          /*
1002 1010           * If our children haven't all reached the ready stage,
1003 1011           * wait for them and then repeat this pipeline stage.
1004 1012           */
1005 1013          if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_READY) ||
1006 1014              zio_wait_for_children(zio, ZIO_CHILD_LOGICAL, ZIO_WAIT_READY))
1007 1015                  return (ZIO_PIPELINE_STOP);
1008 1016  
1009 1017          if (!IO_IS_ALLOCATING(zio))
1010 1018                  return (ZIO_PIPELINE_CONTINUE);
1011 1019  
1012 1020          ASSERT(zio->io_child_type != ZIO_CHILD_DDT);
1013 1021  
     1022 +        if (zp->zp_zero_write && !(zio->io_pipeline & ZIO_GANG_STAGES)) {
     1023 +                dedup = B_FALSE;
     1024 +                compress = ZIO_COMPRESS_OFF;
     1025 +                checksum = ZIO_CHECKSUM_OFF;
     1026 +        }
     1027 +
1014 1028          if (zio->io_bp_override) {
1015 1029                  ASSERT(bp->blk_birth != zio->io_txg);
1016 1030                  ASSERT(BP_GET_DEDUP(zio->io_bp_override) == 0);
1017 1031  
1018 1032                  *bp = *zio->io_bp_override;
1019 1033                  zio->io_pipeline = ZIO_INTERLOCK_PIPELINE;
1020 1034  
1021 1035                  if (BP_IS_EMBEDDED(bp))
1022 1036                          return (ZIO_PIPELINE_CONTINUE);
1023 1037  
↓ open down ↓ 3 lines elided ↑ open up ↑
1027 1041                   * has already occurred.
1028 1042                   */
1029 1043                  if (!BP_IS_HOLE(bp) && zp->zp_nopwrite) {
1030 1044                          ASSERT(!zp->zp_dedup);
1031 1045                          zio->io_flags |= ZIO_FLAG_NOPWRITE;
1032 1046                          return (ZIO_PIPELINE_CONTINUE);
1033 1047                  }
1034 1048  
1035 1049                  ASSERT(!zp->zp_nopwrite);
1036 1050  
1037      -                if (BP_IS_HOLE(bp) || !zp->zp_dedup)
     1051 +                if (BP_IS_HOLE(bp) || !dedup)
1038 1052                          return (ZIO_PIPELINE_CONTINUE);
1039 1053  
1040      -                ASSERT(zio_checksum_table[zp->zp_checksum].ci_dedup ||
     1054 +                ASSERT(zio_checksum_table[checksum].ci_dedup ||
1041 1055                      zp->zp_dedup_verify);
1042 1056  
1043      -                if (BP_GET_CHECKSUM(bp) == zp->zp_checksum) {
     1057 +                if (BP_GET_CHECKSUM(bp) == checksum) {
1044 1058                          BP_SET_DEDUP(bp, 1);
1045 1059                          zio->io_pipeline |= ZIO_STAGE_DDT_WRITE;
1046 1060                          return (ZIO_PIPELINE_CONTINUE);
1047 1061                  }
1048 1062                  zio->io_bp_override = NULL;
1049 1063                  BP_ZERO(bp);
1050 1064          }
1051 1065  
1052 1066          if (!BP_IS_HOLE(bp) && bp->blk_birth == zio->io_txg) {
1053 1067                  /*
↓ open down ↓ 92 lines elided ↑ open up ↑
1146 1160          } else {
1147 1161                  ASSERT(zp->zp_checksum != ZIO_CHECKSUM_GANG_HEADER);
1148 1162                  BP_SET_LSIZE(bp, lsize);
1149 1163                  BP_SET_TYPE(bp, zp->zp_type);
1150 1164                  BP_SET_LEVEL(bp, zp->zp_level);
1151 1165                  BP_SET_PSIZE(bp, psize);
1152 1166                  BP_SET_COMPRESS(bp, compress);
1153 1167                  BP_SET_CHECKSUM(bp, zp->zp_checksum);
1154 1168                  BP_SET_DEDUP(bp, zp->zp_dedup);
1155 1169                  BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
     1170 +                if (zp->zp_zero_write  && !(zio->io_pipeline & ZIO_GANG_STAGES)) {
     1171 +                        boolean_t need_allocate = B_FALSE;
     1172 +                        if (zio->io_pipeline & ZIO_STAGE_DVA_ALLOCATE)
     1173 +                                need_allocate = B_TRUE;
     1174 +                        zio->io_pipeline = ZIO_INTERLOCK_STAGES;
     1175 +                        if (need_allocate)
     1176 +                                zio->io_pipeline |= ZIO_STAGE_DVA_ALLOCATE;
     1177 +                        BP_SET_PROP_RESERVATION(bp, 1);
     1178 +                } else {
     1179 +                        BP_SET_PROP_RESERVATION(bp, 0);
     1180 +                }
1156 1181                  if (zp->zp_dedup) {
1157 1182                          ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
1158 1183                          ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
1159 1184                          zio->io_pipeline = ZIO_DDT_WRITE_PIPELINE;
1160 1185                  }
1161 1186                  if (zp->zp_nopwrite) {
1162 1187                          ASSERT(zio->io_child_type == ZIO_CHILD_LOGICAL);
1163 1188                          ASSERT(!(zio->io_flags & ZIO_FLAG_IO_REWRITE));
1164 1189                          zio->io_pipeline |= ZIO_STAGE_NOP_WRITE;
1165 1190                  }
↓ open down ↓ 698 lines elided ↑ open up ↑
1864 1889                      SPA_MINBLOCKSIZE);
1865 1890                  ASSERT(lsize >= SPA_MINBLOCKSIZE && lsize <= resid);
1866 1891  
1867 1892                  zp.zp_checksum = gio->io_prop.zp_checksum;
1868 1893                  zp.zp_compress = ZIO_COMPRESS_OFF;
1869 1894                  zp.zp_type = DMU_OT_NONE;
1870 1895                  zp.zp_level = 0;
1871 1896                  zp.zp_copies = gio->io_prop.zp_copies;
1872 1897                  zp.zp_dedup = B_FALSE;
1873 1898                  zp.zp_dedup_verify = B_FALSE;
     1899 +                zp.zp_zero_write = B_FALSE;
1874 1900                  zp.zp_nopwrite = B_FALSE;
1875 1901  
1876 1902                  zio_nowait(zio_write(zio, spa, txg, &gbh->zg_blkptr[g],
1877 1903                      (char *)pio->io_data + (pio->io_size - resid), lsize, &zp,
1878 1904                      zio_write_gang_member_ready, NULL, NULL, &gn->gn_child[g],
1879 1905                      pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio),
1880 1906                      &pio->io_bookmark));
1881 1907          }
1882 1908  
1883 1909          /*
↓ open down ↓ 1367 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX