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>
This commit is contained in:
parent
01cd33674e
commit
8c2a1a3028
3 changed files with 100 additions and 38 deletions
|
@ -280,11 +280,23 @@ static int process_one_buffer(struct btrfs_root *log,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* If this fs is mixed then we need to be able to process the leaves to
|
||||
* pin down any logged extents, so we have to read the block.
|
||||
*/
|
||||
if (btrfs_fs_incompat(log->fs_info, MIXED_GROUPS)) {
|
||||
ret = btrfs_read_buffer(eb, gen);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (wc->pin)
|
||||
ret = btrfs_pin_extent_for_log_replay(log->fs_info->extent_root,
|
||||
eb->start, eb->len);
|
||||
|
||||
if (!ret && btrfs_buffer_uptodate(eb, gen, 0)) {
|
||||
if (wc->pin && btrfs_header_level(eb) == 0)
|
||||
ret = btrfs_exclude_logged_extents(log, eb);
|
||||
if (wc->write)
|
||||
btrfs_write_tree_block(eb);
|
||||
if (wc->wait)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue