Skip to content

Commit 6f42692

Browse files
committed
Implement physical rewrites
Based on previous commit this implements `zfs rewrite -P` flag, making ZFS to keep block 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. Signed-off-by: Alexander Motin <[email protected]>
1 parent d576928 commit 6f42692

File tree

21 files changed

+287
-33
lines changed

21 files changed

+287
-33
lines changed

cmd/zfs/zfs_main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ get_usage(zfs_help_t idx)
440440
return (gettext("\tredact <snapshot> <bookmark> "
441441
"<redaction_snapshot> ...\n"));
442442
case HELP_REWRITE:
443-
return (gettext("\trewrite [-rvx] [-o <offset>] [-l <length>] "
443+
return (gettext("\trewrite [-Prvx] [-o <offset>] [-l <length>] "
444444
"<directory|file ...>\n"));
445445
case HELP_JAIL:
446446
return (gettext("\tjail <jailid|jailname> <filesystem>\n"));
@@ -9177,8 +9177,11 @@ zfs_do_rewrite(int argc, char **argv)
91779177
zfs_rewrite_args_t args;
91789178
memset(&args, 0, sizeof (args));
91799179

9180-
while ((c = getopt(argc, argv, "l:o:rvx")) != -1) {
9180+
while ((c = getopt(argc, argv, "Pl:o:rvx")) != -1) {
91819181
switch (c) {
9182+
case 'P':
9183+
args.flags |= ZFS_REWRITE_PHYSICAL;
9184+
break;
91829185
case 'l':
91839186
args.len = strtoll(optarg, NULL, 0);
91849187
break;

include/sys/dbuf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ typedef struct dbuf_dirty_record {
164164
boolean_t dr_nopwrite;
165165
boolean_t dr_brtwrite;
166166
boolean_t dr_diowrite;
167+
boolean_t dr_rewrite;
167168
boolean_t dr_has_raw_params;
168169

169170
/* Override and raw params are mutually exclusive. */

include/sys/dmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ struct blkptr *dmu_buf_get_blkptr(dmu_buf_t *db);
822822
*/
823823
void dmu_buf_will_dirty(dmu_buf_t *db, dmu_tx_t *tx);
824824
void dmu_buf_will_dirty_flags(dmu_buf_t *db, dmu_tx_t *tx, dmu_flags_t flags);
825+
void dmu_buf_will_rewrite(dmu_buf_t *db, dmu_tx_t *tx);
825826
boolean_t dmu_buf_is_dirty(dmu_buf_t *db, dmu_tx_t *tx);
826827
void dmu_buf_set_crypt_params(dmu_buf_t *db_fake, boolean_t byteorder,
827828
const uint8_t *salt, const uint8_t *iv, const uint8_t *mac, dmu_tx_t *tx);

include/sys/fs/zfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,9 @@ typedef struct zfs_rewrite_args {
16271627
uint64_t arg;
16281628
} zfs_rewrite_args_t;
16291629

1630+
/* zfs_rewrite_args flags */
1631+
#define ZFS_REWRITE_PHYSICAL 0x1 /* Preserve logical birth time. */
1632+
16301633
#define ZFS_IOC_REWRITE _IOW(0x83, 3, zfs_rewrite_args_t)
16311634

16321635
/*

include/sys/zio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ typedef struct zio_prop {
374374
boolean_t zp_encrypt;
375375
boolean_t zp_byteorder;
376376
boolean_t zp_direct_write;
377+
boolean_t zp_rewrite;
377378
uint8_t zp_salt[ZIO_DATA_SALT_LEN];
378379
uint8_t zp_iv[ZIO_DATA_IV_LEN];
379380
uint8_t zp_mac[ZIO_DATA_MAC_LEN];

include/zfeature_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ typedef enum spa_feature {
8888
SPA_FEATURE_LONGNAME,
8989
SPA_FEATURE_LARGE_MICROZAP,
9090
SPA_FEATURE_DYNAMIC_GANG_HEADER,
91+
SPA_FEATURE_PHYSICAL_REWRITE,
9192
SPA_FEATURES
9293
} spa_feature_t;
9394

lib/libuutil/libuutil.abi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,11 @@
14751475
<parameter type-id='80f4b756' name='name'/>
14761476
<return type-id='a27af98c'/>
14771477
</function-decl>
1478+
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1479+
<parameter type-id='d8d5f4ab' name='cb'/>
1480+
<parameter type-id='eaa32e2f' name='arg'/>
1481+
<return type-id='48b5725f'/>
1482+
</function-decl>
14781483
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
14791484
<parameter type-id='a27af98c' name='zt'/>
14801485
<parameter type-id='80f4b756' name='val'/>
@@ -1486,11 +1491,6 @@
14861491
<parameter type-id='b59d7dce' name='valsz'/>
14871492
<return type-id='95e97e5e'/>
14881493
</function-decl>
1489-
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1490-
<parameter type-id='d8d5f4ab' name='cb'/>
1491-
<parameter type-id='eaa32e2f' name='arg'/>
1492-
<return type-id='48b5725f'/>
1493-
</function-decl>
14941494
<function-type size-in-bits='64' id='92f86508'>
14951495
<parameter type-id='a27af98c'/>
14961496
<parameter type-id='eaa32e2f'/>

lib/libzfs/libzfs.abi

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@
635635
<elf-symbol name='fletcher_4_superscalar_ops' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
636636
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
637637
<elf-symbol name='sa_protocol_names' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
638-
<elf-symbol name='spa_feature_table' size='2520' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
638+
<elf-symbol name='spa_feature_table' size='2576' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
639639
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
640640
<elf-symbol name='zfs_deleg_perm_tab' size='528' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
641641
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -1655,6 +1655,11 @@
16551655
<parameter type-id='80f4b756' name='name'/>
16561656
<return type-id='a27af98c'/>
16571657
</function-decl>
1658+
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1659+
<parameter type-id='d8d5f4ab' name='cb'/>
1660+
<parameter type-id='eaa32e2f' name='arg'/>
1661+
<return type-id='48b5725f'/>
1662+
</function-decl>
16581663
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
16591664
<parameter type-id='a27af98c' name='zt'/>
16601665
<parameter type-id='80f4b756' name='val'/>
@@ -1666,11 +1671,6 @@
16661671
<parameter type-id='b59d7dce' name='valsz'/>
16671672
<return type-id='95e97e5e'/>
16681673
</function-decl>
1669-
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1670-
<parameter type-id='d8d5f4ab' name='cb'/>
1671-
<parameter type-id='eaa32e2f' name='arg'/>
1672-
<return type-id='48b5725f'/>
1673-
</function-decl>
16741674
<function-type size-in-bits='64' id='92f86508'>
16751675
<parameter type-id='a27af98c'/>
16761676
<parameter type-id='eaa32e2f'/>
@@ -6394,7 +6394,8 @@
63946394
<enumerator name='SPA_FEATURE_LONGNAME' value='42'/>
63956395
<enumerator name='SPA_FEATURE_LARGE_MICROZAP' value='43'/>
63966396
<enumerator name='SPA_FEATURE_DYNAMIC_GANG_HEADER' value='44'/>
6397-
<enumerator name='SPA_FEATURES' value='45'/>
6397+
<enumerator name='SPA_FEATURE_PHYSICAL_REWRITE' value='45'/>
6398+
<enumerator name='SPA_FEATURES' value='46'/>
63986399
</enum-decl>
63996400
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
64006401
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
@@ -9585,8 +9586,8 @@
95859586
</function-decl>
95869587
</abi-instr>
95879588
<abi-instr address-size='64' path='module/zcommon/zfeature_common.c' language='LANG_C99'>
9588-
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='20160' id='b948da70'>
9589-
<subrange length='45' type-id='7359adad' id='cb8ddca0'/>
9589+
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='20608' id='b9408bab'>
9590+
<subrange length='46' type-id='7359adad' id='8b86bc1b'/>
95909591
</array-type-def>
95919592
<enum-decl name='zfeature_flags' id='6db816a4'>
95929593
<underlying-type type-id='9cac1fee'/>
@@ -9664,7 +9665,7 @@
96649665
<pointer-type-def type-id='611586a1' size-in-bits='64' id='2e243169'/>
96659666
<qualified-type-def type-id='eaa32e2f' const='yes' id='83be723c'/>
96669667
<pointer-type-def type-id='83be723c' size-in-bits='64' id='7acd98a2'/>
9667-
<var-decl name='spa_feature_table' type-id='b948da70' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
9668+
<var-decl name='spa_feature_table' type-id='b9408bab' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
96689669
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
96699670
<function-decl name='opendir' visibility='default' binding='global' size-in-bits='64'>
96709671
<parameter type-id='80f4b756'/>

lib/libzfs_core/libzfs_core.abi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,11 @@
14261426
<parameter type-id='80f4b756' name='name'/>
14271427
<return type-id='a27af98c'/>
14281428
</function-decl>
1429+
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1430+
<parameter type-id='d8d5f4ab' name='cb'/>
1431+
<parameter type-id='eaa32e2f' name='arg'/>
1432+
<return type-id='48b5725f'/>
1433+
</function-decl>
14291434
<function-decl name='zfs_tunable_set' mangled-name='zfs_tunable_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_set'>
14301435
<parameter type-id='a27af98c' name='zt'/>
14311436
<parameter type-id='80f4b756' name='val'/>
@@ -1437,11 +1442,6 @@
14371442
<parameter type-id='b59d7dce' name='valsz'/>
14381443
<return type-id='95e97e5e'/>
14391444
</function-decl>
1440-
<function-decl name='zfs_tunable_iter' mangled-name='zfs_tunable_iter' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_tunable_iter'>
1441-
<parameter type-id='d8d5f4ab' name='cb'/>
1442-
<parameter type-id='eaa32e2f' name='arg'/>
1443-
<return type-id='48b5725f'/>
1444-
</function-decl>
14451445
<function-type size-in-bits='64' id='92f86508'>
14461446
<parameter type-id='a27af98c'/>
14471447
<parameter type-id='eaa32e2f'/>

man/man7/zpool-features.7

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,23 @@ when the
842842
command is used on a top-level vdev, and will never return to being
843843
.Sy enabled .
844844
.
845+
.feature com.truenas physical_rewrite yes extensible_dataset
846+
This feature enables physical block rewriting that preserves logical birth
847+
times, avoiding unnecessary inclusion of rewritten blocks in incremental
848+
.Nm zfs Cm send
849+
streams.
850+
When enabled, the
851+
.Nm zfs Cm rewrite Fl P
852+
command can be used.
853+
.Pp
854+
This feature becomes
855+
.Sy active
856+
the first time
857+
.Nm zfs Cm rewrite Fl P
858+
is used on any dataset, and will return to being
859+
.Sy enabled
860+
once all datasets that have ever used physical rewrite are destroyed.
861+
.
845862
.feature org.zfsonlinux project_quota yes extensible_dataset
846863
This feature allows administrators to account the spaces and objects usage
847864
information against the project identifier

0 commit comments

Comments
 (0)