diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 10 |
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); |