There are at least 2 reports about memory bit flip sneaking into on-disk
data.

Currently we only have a relaxed check triggered at
btrfs_mark_buffer_dirty() time, as it's not mandatory, only for
CONFIG_BTRFS_FS_CHECK_INTEGRITY enabled build.

This patch will address the hole by triggering comprehensive check on
tree blocks before writing it back to disk.

The timing is set to csum_tree_block() where @verify == 0.
At that timing, we're generation csum for tree blocks before submitting
the metadata bio, so we could avoid all the unnecessary calls at
btrfs_mark_buffer_dirty(), but still catch enough error.

Reported-by: Leonard Lausen <[email protected]>
Signed-off-by: Qu Wenruo <[email protected]>
---
 fs/btrfs/disk-io.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8da2f380d3c0..45bf6be9e751 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -313,6 +313,16 @@ static int csum_tree_block(struct btrfs_fs_info *fs_info,
                        return -EUCLEAN;
                }
        } else {
+               /*
+                * Here we're calculating csum before writing it to disk,
+                * do comprenhensive check here to catch memory corruption
+                */
+               if (btrfs_header_level(buf))
+                       err = btrfs_check_node(fs_info, buf);
+               else
+                       err = btrfs_check_leaf_full(fs_info, buf);
+               if (err < 0)
+                       return err;
                write_extent_buffer(buf, result, 0, csum_size);
        }
 
-- 
2.20.1

Reply via email to