Btrfs: Change tree block csum tagging to avoid false error messages
authorChris Mason <chris.mason@oracle.com>
Tue, 8 Jan 2008 20:46:27 +0000 (15:46 -0500)
committerChris Mason <chris.mason@oracle.com>
Thu, 25 Sep 2008 15:03:59 +0000 (11:03 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/disk-io.c

index 67d9fd728868c9089f28f3921ffdfa75a3b1d704..a6170ff19e7fe6eaaa9df2e2a477d155ba48f328 100644 (file)
@@ -145,10 +145,25 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
        btrfs_csum_final(crc, result);
 
        if (verify) {
-               if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
-                       printk("btrfs: %s checksum verify failed on %llu\n",
+               int from_this_trans = 0;
+
+               if (root->fs_info->running_transaction &&
+                   btrfs_header_generation(buf) ==
+                   root->fs_info->running_transaction->transid)
+                       from_this_trans = 1;
+
+               /* FIXME, this is not good */
+               if (from_this_trans == 0 &&
+                   memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
+                       u32 val;
+                       u32 found = 0;
+                       memcpy(&found, result, BTRFS_CRC32_SIZE);
+
+                       read_extent_buffer(buf, &val, 0, BTRFS_CRC32_SIZE);
+                       printk("btrfs: %s checksum verify failed on %llu "
+                              "wanted %X found %X from_this_trans %d\n",
                               root->fs_info->sb->s_id,
-                              buf->start);
+                              buf->start, val, found, from_this_trans);
                        return 1;
                }
        } else {
@@ -313,6 +328,7 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
        struct extent_buffer *buf = NULL;
        struct inode *btree_inode = root->fs_info->btree_inode;
        struct extent_map_tree *extent_tree;
+       u64 end;
        int ret;
 
        extent_tree = &BTRFS_I(btree_inode)->extent_tree;
@@ -322,19 +338,29 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
                return NULL;
        read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
                                 buf, 0, 1);
-       if (buf->flags & EXTENT_CSUM) {
+
+       if (buf->flags & EXTENT_CSUM)
                return buf;
-       }
-       if (test_range_bit(extent_tree, buf->start, buf->start + buf->len - 1,
-                          EXTENT_CSUM, 1)) {
+
+       end = buf->start + PAGE_CACHE_SIZE - 1;
+       if (test_range_bit(extent_tree, buf->start, end, EXTENT_CSUM, 1)) {
                buf->flags |= EXTENT_CSUM;
                return buf;
        }
+
+       lock_extent(extent_tree, buf->start, end, GFP_NOFS);
+
+       if (test_range_bit(extent_tree, buf->start, end, EXTENT_CSUM, 1)) {
+               buf->flags |= EXTENT_CSUM;
+               goto out_unlock;
+       }
+
        ret = csum_tree_block(root, buf, 1);
-       set_extent_bits(extent_tree, buf->start,
-                       buf->start + buf->len - 1,
-                       EXTENT_CSUM, GFP_NOFS);
+       set_extent_bits(extent_tree, buf->start, end, EXTENT_CSUM, GFP_NOFS);
        buf->flags |= EXTENT_CSUM;
+
+out_unlock:
+       unlock_extent(extent_tree, buf->start, end, GFP_NOFS);
        return buf;
 }