@@ -3729,6 +3729,13 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
ret);
goto fail_block_groups;
}
+
+ ret = btrfs_write_intent_recover(fs_info);
+ if (ret < 0) {
+ btrfs_err(fs_info, "failed to recover write-intent bitmap: %d",
+ ret);
+ goto fail_block_groups;
+ }
ret = btrfs_recover_balance(fs_info);
if (ret) {
btrfs_err(fs_info, "failed to recover balance: %d", ret);
@@ -704,6 +704,41 @@ void btrfs_write_intent_clear_dirty(struct btrfs_fs_info *fs_info, u64 logical,
spin_unlock_irqrestore(&ctrl->lock, flags);
}
+int btrfs_write_intent_recover(struct btrfs_fs_info *fs_info)
+{
+ struct write_intent_ctrl *ctrl = fs_info->wi_ctrl;
+ struct write_intent_super *wis;
+ int ret = 0;
+
+ if (!btrfs_fs_compat_ro(fs_info, WRITE_INTENT_BITMAP))
+ return ret;
+
+ ASSERT(ctrl);
+ wis = page_address(ctrl->page);
+
+ if (wi_super_nr_entries(wis) != 0) {
+ int i;
+
+ btrfs_warn(fs_info, "dirty write intent bitmap found:");
+ for (i = 0; i < wi_super_nr_entries(wis); i++) {
+ struct write_intent_entry *entry =
+ write_intent_entry_nr(ctrl, i);
+
+ btrfs_warn(fs_info,
+ " entry=%u bytenr=%llu bitmap=0x%016llx\n", i,
+ wi_entry_bytenr(entry),
+ wi_entry_raw_bitmap(entry));
+ }
+ /* For now, we just clear the whole bitmap. */
+ memzero_page(ctrl->page, sizeof(struct write_intent_super),
+ WRITE_INTENT_BITMAPS_SIZE -
+ sizeof(struct write_intent_super));
+ wi_set_super_nr_entries(wis, 0);
+ ret = write_intent_writeback(fs_info);
+ }
+ return ret;
+}
+
int btrfs_write_intent_writeback(struct btrfs_fs_info *fs_info, u64 event)
{
struct write_intent_ctrl *ctrl = fs_info->wi_ctrl;
@@ -292,4 +292,12 @@ void btrfs_write_intent_mark_dirty(struct btrfs_fs_info *fs_info, u64 logical,
*/
void btrfs_write_intent_clear_dirty(struct btrfs_fs_info *fs_info, u64 logical,
u32 len);
+
+/*
+ * Rebuild the range in the write-intent bitmaps.
+ *
+ * Currently not working, it will just output a warning and clear the bitmap.
+ */
+int btrfs_write_intent_recover(struct btrfs_fs_info *fs_info);
+
#endif
To properly cleanup the bitmaps, we need to scrub the logical ranges in the bitmaps. Unfortunately there is no such convient interface at all (scrub only works at device offset for now). So just introduce a place holder to warn and clear the bitmap. Signed-off-by: Qu Wenruo <wqu@suse.com> --- fs/btrfs/disk-io.c | 7 +++++++ fs/btrfs/write-intent.c | 35 +++++++++++++++++++++++++++++++++++ fs/btrfs/write-intent.h | 8 ++++++++ 3 files changed, 50 insertions(+)