Implement physical rewrites

Based on previous commit this implements `zfs rewrite -P` flag,
making ZFS to keep blocks logical birth times while rewriting
files.  It should exclude the rewritten blocks from incremental
sends, snapshot diffs, etc.  Snapshots space usage same time will
reflect the additional space usage from newly allocated blocks.

Since this begins to use new "rewrite" flag in the block pointers,
this commit introduces a new read-compatible per-dataset feature
physical_rewrite.  It must be enabled for the command to not fail,
it is activated on first use and deactivated on deletion of the
last affected dataset.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by:  Alexander Motin <alexander.motin@TrueNAS.com>
Closes #17565
This commit is contained in:
Alexander Motin
2025-07-23 15:51:00 -04:00
committed by Brian Behlendorf
parent 4ae8bf406b
commit 60f714e6e2
19 changed files with 270 additions and 18 deletions
+1
View File
@@ -164,6 +164,7 @@ typedef struct dbuf_dirty_record {
boolean_t dr_nopwrite;
boolean_t dr_brtwrite;
boolean_t dr_diowrite;
boolean_t dr_rewrite;
boolean_t dr_has_raw_params;
/* Override and raw params are mutually exclusive. */
+1
View File
@@ -825,6 +825,7 @@ struct blkptr *dmu_buf_get_blkptr(dmu_buf_t *db);
*/
void dmu_buf_will_dirty(dmu_buf_t *db, dmu_tx_t *tx);
void dmu_buf_will_dirty_flags(dmu_buf_t *db, dmu_tx_t *tx, dmu_flags_t flags);
void dmu_buf_will_rewrite(dmu_buf_t *db, dmu_tx_t *tx);
boolean_t dmu_buf_is_dirty(dmu_buf_t *db, dmu_tx_t *tx);
void dmu_buf_set_crypt_params(dmu_buf_t *db_fake, boolean_t byteorder,
const uint8_t *salt, const uint8_t *iv, const uint8_t *mac, dmu_tx_t *tx);
+3
View File
@@ -1627,6 +1627,9 @@ typedef struct zfs_rewrite_args {
uint64_t arg;
} zfs_rewrite_args_t;
/* zfs_rewrite_args flags */
#define ZFS_REWRITE_PHYSICAL 0x1 /* Preserve logical birth time. */
#define ZFS_IOC_REWRITE _IOW(0x83, 3, zfs_rewrite_args_t)
/*
+1
View File
@@ -374,6 +374,7 @@ typedef struct zio_prop {
boolean_t zp_encrypt;
boolean_t zp_byteorder;
boolean_t zp_direct_write;
boolean_t zp_rewrite;
uint8_t zp_salt[ZIO_DATA_SALT_LEN];
uint8_t zp_iv[ZIO_DATA_IV_LEN];
uint8_t zp_mac[ZIO_DATA_MAC_LEN];
+1
View File
@@ -89,6 +89,7 @@ typedef enum spa_feature {
SPA_FEATURE_LARGE_MICROZAP,
SPA_FEATURE_DYNAMIC_GANG_HEADER,
SPA_FEATURE_BLOCK_CLONING_ENDIAN,
SPA_FEATURE_PHYSICAL_REWRITE,
SPA_FEATURES
} spa_feature_t;