]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/dmu.c
BRT: Fix holes cloning.
[mirror_zfs.git] / module / zfs / dmu.c
index b88cf447d2967f4f07686b18d3336ddc7104d436..753dde6d520599ddd23c6c17298e40f3fdf1118b 100644 (file)
@@ -2265,11 +2265,13 @@ dmu_read_l0_bps(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
 
                if (bp == NULL) {
                        /*
-                        * The block was created in this transaction group,
-                        * so it has no BP yet.
+                        * The file size was increased, but the block was never
+                        * written, otherwise we would either have the block
+                        * pointer or the dirty record and would not get here.
+                        * It is effectively a hole, so report it as such.
                         */
-                       error = SET_ERROR(EAGAIN);
-                       goto out;
+                       BP_ZERO(&bps[i]);
+                       continue;
                }
                /*
                 * Make sure we clone only data blocks.
@@ -2361,19 +2363,17 @@ dmu_brt_clone(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
                ASSERT3U(dr->dr_txg, ==, tx->tx_txg);
                dl = &dr->dt.dl;
                dl->dr_overridden_by = *bp;
-               dl->dr_brtwrite = B_TRUE;
-               dl->dr_override_state = DR_OVERRIDDEN;
-               if (BP_IS_HOLE(bp)) {
-                       BP_SET_LOGICAL_BIRTH(&dl->dr_overridden_by, 0);
-                       BP_SET_PHYSICAL_BIRTH(&dl->dr_overridden_by, 0);
-               } else {
-                       BP_SET_LOGICAL_BIRTH(&dl->dr_overridden_by,
-                           dr->dr_txg);
+               if (!BP_IS_HOLE(bp) || BP_GET_LOGICAL_BIRTH(bp) != 0) {
                        if (!BP_IS_EMBEDDED(bp)) {
-                               BP_SET_PHYSICAL_BIRTH(&dl->dr_overridden_by,
+                               BP_SET_BIRTH(&dl->dr_overridden_by, dr->dr_txg,
                                    BP_GET_BIRTH(bp));
+                       } else {
+                               BP_SET_LOGICAL_BIRTH(&dl->dr_overridden_by,
+                                   dr->dr_txg);
                        }
                }
+               dl->dr_brtwrite = B_TRUE;
+               dl->dr_override_state = DR_OVERRIDDEN;
 
                mutex_exit(&db->db_mtx);