@@ -181,6 +181,17 @@ static const struct btrfs_feature runtime_features[] = {
VERSION_NULL(default),
.desc = "extra super block reserved space for each device"
},
+#if EXPERIMENTAL
+ {
+ .name = "write-intent-bitmap",
+ .flag = BTRFS_RUNTIME_FEATURE_WRITE_INTENT_BITMAP,
+ .sysfs_name = "write_intent_bitmap",
+ VERSION_NULL(compat),
+ VERSION_NULL(safe),
+ VERSION_NULL(default),
+ .desc = "write intent bitmap"
+ },
+#endif
/* Keep this one last */
{
.name = "list-all",
@@ -46,6 +46,7 @@
#define BTRFS_RUNTIME_FEATURE_QUOTA (1ULL << 0)
#define BTRFS_RUNTIME_FEATURE_FREE_SPACE_TREE (1ULL << 1)
#define BTRFS_RUNTIME_FEATURE_EXTRA_SUPER_RESERVED (1ULL << 2)
+#define BTRFS_RUNTIME_FEATURE_WRITE_INTENT_BITMAP (1ULL << 3)
void btrfs_list_all_fs_features(u64 mask_disallowed);
void btrfs_list_all_runtime_features(u64 mask_disallowed);
@@ -502,6 +502,13 @@ BUILD_ASSERT(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
*/
#define BTRFS_FEATURE_COMPAT_RO_EXTRA_SUPER_RESERVED (1ULL << 3)
+/*
+ * Allow btrfs to have per-device write-intent bitmap.
+ * Will be utilized to close the RAID56 write-hole (by forced scrub for dirty
+ * partial written stripes at mount time).
+ */
+#define BTRFS_FEATURE_COMPAT_RO_WRITE_INTENT_BITMAP (1ULL << 4)
+
#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
@@ -524,6 +531,13 @@ BUILD_ASSERT(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
+#if EXPERIMENTAL
+#define BTRFS_FEATURE_COMPAT_RO_SUPP \
+ (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \
+ BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID |\
+ BTRFS_FEATURE_COMPAT_RO_EXTRA_SUPER_RESERVED | \
+ BTRFS_FEATURE_COMPAT_RO_WRITE_INTENT_BITMAP)
+#else
/*
* The FREE_SPACE_TREE and FREE_SPACE_TREE_VALID compat_ro bits must not be
* added here until read-write support for the free space tree is implemented in
@@ -533,6 +547,7 @@ BUILD_ASSERT(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \
BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID |\
BTRFS_FEATURE_COMPAT_RO_EXTRA_SUPER_RESERVED)
+#endif
#if EXPERIMENTAL
#define BTRFS_FEATURE_INCOMPAT_SUPP \
@@ -1848,6 +1848,15 @@ int btrfs_check_super(struct btrfs_super_block *sb, unsigned sbflags)
}
}
+ if (btrfs_super_compat_ro_flags(sb) &
+ BTRFS_FEATURE_COMPAT_RO_WRITE_INTENT_BITMAP &&
+ !(btrfs_super_compat_ro_flags(sb) &
+ BTRFS_FEATURE_COMPAT_RO_EXTRA_SUPER_RESERVED)) {
+ error(
+"write intent bitmap feature enabled without extra super reserved feature");
+ goto error_out;
+ }
+
if (btrfs_super_compat_ro_flags(sb) &
BTRFS_FEATURE_COMPAT_RO_EXTRA_SUPER_RESERVED &&
btrfs_super_reserved_bytes(sb) < BTRFS_BLOCK_RESERVED_1M_FOR_SUPER) {
@@ -1669,6 +1669,7 @@ static struct readable_flag_entry compat_ro_flags_array[] = {
DEF_COMPAT_RO_FLAG_ENTRY(FREE_SPACE_TREE),
DEF_COMPAT_RO_FLAG_ENTRY(FREE_SPACE_TREE_VALID),
DEF_COMPAT_RO_FLAG_ENTRY(EXTRA_SUPER_RESERVED),
+ DEF_COMPAT_RO_FLAG_ENTRY(WRITE_INTENT_BITMAP),
};
static const int compat_ro_flags_num = sizeof(compat_ro_flags_array) /
sizeof(struct readable_flag_entry);
@@ -316,6 +316,8 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2);
bool extra_super_reserved = !!(cfg->runtime_features &
BTRFS_RUNTIME_FEATURE_EXTRA_SUPER_RESERVED);
+ bool write_intent_bitmap = !!(cfg->runtime_features &
+ BTRFS_RUNTIME_FEATURE_WRITE_INTENT_BITMAP);
/* Don't include the free space tree in the blocks to process. */
if (!free_space_tree)
@@ -657,6 +659,13 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
btrfs_set_super_reserved_bytes(&super, system_group_offset);
}
+ if (write_intent_bitmap) {
+ u64 ro_flags = btrfs_super_compat_ro_flags(&super) |
+ BTRFS_FEATURE_COMPAT_RO_WRITE_INTENT_BITMAP;
+
+ btrfs_set_super_compat_ro_flags(&super, ro_flags);
+ }
+
if (extent_tree_v2) {
ret = create_block_group_tree(fd, cfg, buf,
system_group_offset,
@@ -1248,6 +1248,11 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
error("extra-super-reserved runtime feature conflicts with zoned devices");
exit(1);
}
+
+ /* Write intent bitmap must has extra reserved space. */
+ if (runtime_features & BTRFS_RUNTIME_FEATURE_WRITE_INTENT_BITMAP)
+ runtime_features |= BTRFS_RUNTIME_FEATURE_EXTRA_SUPER_RESERVED;
+
/*
* Set default profiles according to number of added devices.
* For mixed groups defaults are single/single.
This new compat RO flag will only be enabled through experimental features. Since this feature has no real code implementation yet, only the following code changes are added: - New super block check To ensure WRITE_INTENT_BITMAP is enabled along with EXTRA_SUPER_RESERVED - New compat RO flag readable string output - New mkfs runtime features Signed-off-by: Qu Wenruo <wqu@suse.com> --- common/fsfeatures.c | 11 +++++++++++ common/fsfeatures.h | 1 + kernel-shared/ctree.h | 15 +++++++++++++++ kernel-shared/disk-io.c | 9 +++++++++ kernel-shared/print-tree.c | 1 + mkfs/common.c | 9 +++++++++ mkfs/main.c | 5 +++++ 7 files changed, 51 insertions(+)