aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-01 11:21:32 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commit63b10fc4874a014e22bc4c64e3d92b71180661fe (patch)
tree683a7b414f269f8b999b666d5f2d6c9fb74a1ee8 /fs/btrfs/ctree.c
parent2d2ae547979854d10b75d557b3abdb3eb7511bbc (diff)
Reorder the flags field in struct btrfs_header and record a flag on writeout
This allows detection of blocks that have already been written in the running transaction so they can be recowed instead of modified again. It is step one in trusting the transid field of the block pointers. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 70b6ddfe15a1..6ba5394834be 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -124,6 +124,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
124 btrfs_set_header_bytenr(cow, cow->start); 124 btrfs_set_header_bytenr(cow, cow->start);
125 btrfs_set_header_generation(cow, trans->transid); 125 btrfs_set_header_generation(cow, trans->transid);
126 btrfs_set_header_owner(cow, new_root_objectid); 126 btrfs_set_header_owner(cow, new_root_objectid);
127 btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN);
127 128
128 WARN_ON(btrfs_header_generation(buf) > trans->transid); 129 WARN_ON(btrfs_header_generation(buf) > trans->transid);
129 ret = btrfs_inc_ref(trans, new_root, buf); 130 ret = btrfs_inc_ref(trans, new_root, buf);
@@ -183,6 +184,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
183 btrfs_set_header_bytenr(cow, cow->start); 184 btrfs_set_header_bytenr(cow, cow->start);
184 btrfs_set_header_generation(cow, trans->transid); 185 btrfs_set_header_generation(cow, trans->transid);
185 btrfs_set_header_owner(cow, root->root_key.objectid); 186 btrfs_set_header_owner(cow, root->root_key.objectid);
187 btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN);
186 188
187 WARN_ON(btrfs_header_generation(buf) > trans->transid); 189 WARN_ON(btrfs_header_generation(buf) > trans->transid);
188 if (btrfs_header_generation(buf) != trans->transid) { 190 if (btrfs_header_generation(buf) != trans->transid) {
@@ -245,11 +247,14 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
245 } 247 }
246 248
247 header_trans = btrfs_header_generation(buf); 249 header_trans = btrfs_header_generation(buf);
248 if (header_trans == trans->transid) { 250 spin_lock(&root->fs_info->hash_lock);
251 if (header_trans == trans->transid &&
252 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
249 *cow_ret = buf; 253 *cow_ret = buf;
254 spin_unlock(&root->fs_info->hash_lock);
250 return 0; 255 return 0;
251 } 256 }
252 257 spin_unlock(&root->fs_info->hash_lock);
253 search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); 258 search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1);
254 ret = __btrfs_cow_block(trans, root, buf, parent, 259 ret = __btrfs_cow_block(trans, root, buf, parent,
255 parent_slot, cow_ret, search_start, 0); 260 parent_slot, cow_ret, search_start, 0);
@@ -1494,6 +1499,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
1494 btrfs_set_header_bytenr(split, split->start); 1499 btrfs_set_header_bytenr(split, split->start);
1495 btrfs_set_header_generation(split, trans->transid); 1500 btrfs_set_header_generation(split, trans->transid);
1496 btrfs_set_header_owner(split, root->root_key.objectid); 1501 btrfs_set_header_owner(split, root->root_key.objectid);
1502 btrfs_set_header_flags(split, 0);
1497 write_extent_buffer(split, root->fs_info->fsid, 1503 write_extent_buffer(split, root->fs_info->fsid,
1498 (unsigned long)btrfs_header_fsid(split), 1504 (unsigned long)btrfs_header_fsid(split),
1499 BTRFS_FSID_SIZE); 1505 BTRFS_FSID_SIZE);