Btrfs: Change tree block csum tagging to avoid false error messages

Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 67d9fd7..a6170ff1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -145,10 +145,25 @@
 	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 *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 @@
 		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;
 }