linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC - PATCH] btrfs: do not write corrupted metadata blocks to disk
@ 2016-02-21 15:36 Alex Lyakas
  2016-02-22  1:05 ` Filipe Manana
  0 siblings, 1 reply; 5+ messages in thread
From: Alex Lyakas @ 2016-02-21 15:36 UTC (permalink / raw)
  To: linux-btrfs, fdmanana, jbacik

csum_dirty_buffer was issuing a warning in case the extent buffer
did not look alright, but was still returning success.
Let's return error in this case, and also add two additional sanity
checks on the extent buffer header.

We had btrfs metadata corruption, and after looking at the logs we saw
that WARN_ON(found_start != start) has been triggered. We are still 
investigating
which component trashed the cache page which belonged to btrfs. But btrfs
only issued a warning, and as a result, the corrupted metadata block went to 
disk.

I think we should return an error in such case that the extent buffer 
doesn't look alright.
The caller up the chain may BUG_ON on this, for example flush_epd_write_bio 
will,
but it is better than to have a silent metadata corruption on disk.

Note: this patch has been properly tested on 3.18 kernel only.

Signed-off-by: Alex Lyakas <alex@zadarastorage.com>
---
fs/btrfs/disk-io.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4545e2e..701e706 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -508,22 +508,32 @@ static int csum_dirty_buffer(struct btrfs_fs_info 
*fs_info, struct page *page)
{
     u64 start = page_offset(page);
     u64 found_start;
     struct extent_buffer *eb;

     eb = (struct extent_buffer *)page->private;
     if (page != eb->pages[0])
         return 0;
     found_start = btrfs_header_bytenr(eb);
     if (WARN_ON(found_start != start || !PageUptodate(page)))
-        return 0;
-    csum_tree_block(fs_info, eb, 0);
+        return -EUCLEAN;
+#ifdef CONFIG_BTRFS_ASSERT
+    if (WARN_ON(memcmp_extent_buffer(eb, fs_info->fsid,
+                    (unsigned long)btrfs_header_fsid(), BTRFS_FSID_SIZE)))
+        return -EUCLEAN;
+    if (WARN_ON(memcmp_extent_buffer(eb, fs_info->fsid,
+                    (unsigned long)btrfs_header_chunk_tree_uuid(eb),
+                    BTRFS_FSID_SIZE)))
+        return -EUCLEAN;
+#endif
+    if (csum_tree_block(fs_info, eb, 0))
+        return -EUCLEAN;
     return 0;
}

static int check_tree_block_fsid(struct btrfs_fs_info *fs_info,
                  struct extent_buffer *eb)
{
     struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
     u8 fsid[BTRFS_UUID_SIZE];
     int ret = 1;

-- 
1.9.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-03-10 11:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-21 15:36 [RFC - PATCH] btrfs: do not write corrupted metadata blocks to disk Alex Lyakas
2016-02-22  1:05 ` Filipe Manana
2016-02-22  9:46   ` Alex Lyakas
2016-02-22 10:28     ` Filipe Manana
2016-03-10 11:14       ` Alex Lyakas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).