summaryrefslogtreecommitdiff
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-30 14:27:56 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-30 14:27:56 -0400
commitd6025579531b7ea170ba283b171ff7a6bf7d0e12 (patch)
treec3b742fda3a6ac8541c06011bb3c26635db99212 /fs/btrfs/disk-io.c
parent22b0ebda6c63a1ad66b6a9e806bd226a4a03a049 (diff)
downloadlwn-d6025579531b7ea170ba283b171ff7a6bf7d0e12.tar.gz
lwn-d6025579531b7ea170ba283b171ff7a6bf7d0e12.zip
Btrfs: corruption hunt continues
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6c010463b9db..bb133104e2e9 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -8,6 +8,17 @@
#include "disk-io.h"
#include "transaction.h"
+#define PATTERN 0xDEADBEEFUL
+static inline void check_pattern(struct buffer_head *buf)
+{
+ if (buf->b_private != (void *)PATTERN)
+ WARN_ON(1);
+}
+
+static inline void set_pattern(struct buffer_head *buf)
+{
+ buf->b_private = (void *)PATTERN;
+}
static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
{
@@ -51,8 +62,10 @@ struct buffer_head *btrfs_find_tree_block(struct btrfs_root *root, u64 blocknr)
} while (bh != head);
out_unlock:
unlock_page(page);
- if (ret)
+ if (ret) {
touch_buffer(ret);
+ check_pattern(ret);
+ }
page_cache_release(page);
return ret;
}
@@ -82,6 +95,7 @@ struct buffer_head *btrfs_find_create_tree_block(struct btrfs_root *root,
bh->b_bdev = root->fs_info->sb->s_bdev;
bh->b_blocknr = first_block;
set_buffer_mapped(bh);
+ set_pattern(bh);
}
if (bh->b_blocknr == blocknr) {
ret = bh;
@@ -225,6 +239,7 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
if (!buffer_uptodate(bh))
goto fail;
csum_tree_block(root, bh, 1);
+ set_pattern(bh);
} else {
unlock_buffer(bh);
}
@@ -240,6 +255,7 @@ fail:
int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct buffer_head *buf)
{
+ WARN_ON(atomic_read(&buf->b_count) == 0);
mark_buffer_dirty(buf);
return 0;
}
@@ -247,6 +263,7 @@ int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct buffer_head *buf)
{
+ WARN_ON(atomic_read(&buf->b_count) == 0);
clear_buffer_dirty(buf);
return 0;
}
@@ -431,6 +448,7 @@ int close_ctree(struct btrfs_root *root)
void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf)
{
+ check_pattern(buf);
brelse(buf);
}