Commit 6bc34676 authored by Chris Mason's avatar Chris Mason

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: default avatarChris Mason <chris.mason@oracle.com>
parent 611f0e00
...@@ -1288,7 +1288,9 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, ...@@ -1288,7 +1288,9 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
root->fs_info->running_transaction->transid; root->fs_info->running_transaction->transid;
u64 header_transid = u64 header_transid =
btrfs_header_generation(buf); btrfs_header_generation(buf);
if (header_transid == transid) { if (header_transid == transid &&
!btrfs_header_flag(buf,
BTRFS_HEADER_FLAG_WRITTEN)) {
clean_tree_block(NULL, root, buf); clean_tree_block(NULL, root, buf);
free_extent_buffer(buf); free_extent_buffer(buf);
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment