aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-04 15:40:00 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commit6bc34676c0b5836655ec1c7998e2647cabb933ec (patch)
tree5d470dbde4b209cc6e78b112d886fa704769ece6 /fs
parent611f0e00a27fe0e5a571194a12443ecdc99a43ef (diff)
Btrfs: Don't allow written blocks from this transaction to be reallocated
When a block is freed, it can be immediately reused if it is from the current transaction. But, an extra check is required to make sure the block had not been written yet. If it were reused after being written, the transid in the block header might match the transid of the next time the block was allocated. The parent node records the transaction ID of the block it is pointing to, and this is used as part of validating the block on reads. So, there can only be one version of a block per transaction. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1885ec4280c8..0c0dde6d9614 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1288,7 +1288,9 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1288 root->fs_info->running_transaction->transid; 1288 root->fs_info->running_transaction->transid;
1289 u64 header_transid = 1289 u64 header_transid =
1290 btrfs_header_generation(buf); 1290 btrfs_header_generation(buf);
1291 if (header_transid == transid) { 1291 if (header_transid == transid &&
1292 !btrfs_header_flag(buf,
1293 BTRFS_HEADER_FLAG_WRITTEN)) {
1292 clean_tree_block(NULL, root, buf); 1294 clean_tree_block(NULL, root, buf);
1293 free_extent_buffer(buf); 1295 free_extent_buffer(buf);
1294 return 1; 1296 return 1;