summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-06-06 13:19:32 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:30:17 -0400
commit8c2a1a3028d560cfb95f1c583e872c65ed2f0b3d (patch)
tree05230bf96a4c0122d672ea41426b992442e71089 /fs/btrfs/tree-log.c
parent01cd33674e95296e1647da3534b9aef1e98556b5 (diff)
Btrfs: exclude logged extents before replying when we are mixed
With non-mixed block groups we replay the logs before we're allowed to do any writes, so we get away with not pinning/removing the data extents until right when we replay them. However with mixed block groups we allocate out of the same pool, so we could easily allocate a metadata block that was logged in our tree log. To deal with this we just need to notice that we have mixed block groups and do the normal excluding/removal dance during the pin stage of the log replay and that way we don't allocate metadata blocks from areas we have logged data extents. With this patch we now pass xfstests generic/311 with mixed block groups turned on. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 831ddd4bf897..2c6791493637 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -280,11 +280,23 @@ static int process_one_buffer(struct btrfs_root *log,
280{ 280{
281 int ret = 0; 281 int ret = 0;
282 282
283 /*
284 * If this fs is mixed then we need to be able to process the leaves to
285 * pin down any logged extents, so we have to read the block.
286 */
287 if (btrfs_fs_incompat(log->fs_info, MIXED_GROUPS)) {
288 ret = btrfs_read_buffer(eb, gen);
289 if (ret)
290 return ret;
291 }
292
283 if (wc->pin) 293 if (wc->pin)
284 ret = btrfs_pin_extent_for_log_replay(log->fs_info->extent_root, 294 ret = btrfs_pin_extent_for_log_replay(log->fs_info->extent_root,
285 eb->start, eb->len); 295 eb->start, eb->len);
286 296
287 if (!ret && btrfs_buffer_uptodate(eb, gen, 0)) { 297 if (!ret && btrfs_buffer_uptodate(eb, gen, 0)) {
298 if (wc->pin && btrfs_header_level(eb) == 0)
299 ret = btrfs_exclude_logged_extents(log, eb);
288 if (wc->write) 300 if (wc->write)
289 btrfs_write_tree_block(eb); 301 btrfs_write_tree_block(eb);
290 if (wc->wait) 302 if (wc->wait)