Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/mason/linux-btrfs

Pull more btrfs updates from Chris Mason:
 "This is part two of our merge window patches.

  These are all from Filipe, and fix some really hard to find races that
  can cause corruptions.  Most of them involved block group removal
  (balance) or discard"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: remove non-sense btrfs_error_discard_extent() function
  Btrfs: fix fs corruption on transaction abort if device supports discard
  Btrfs: always clear a block group node when removing it from the tree
  Btrfs: ensure deletion from pinned_chunks list is protected
  • Loading branch information
torvalds committed Dec 20, 2014
2 parents 20e471f + 1edb647 commit 5c68eac
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 25 deletions.
4 changes: 2 additions & 2 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3481,8 +3481,8 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info);
u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
int btrfs_error_unpin_extent_range(struct btrfs_root *root,
u64 start, u64 end);
int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes, u64 *actual_bytes);
int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes, u64 *actual_bytes);
int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 type);
int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range);
Expand Down
6 changes: 0 additions & 6 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -4121,12 +4121,6 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
if (ret)
break;

/* opt_discard */
if (btrfs_test_opt(root, DISCARD))
ret = btrfs_error_discard_extent(root, start,
end + 1 - start,
NULL);

clear_extent_dirty(unpin, start, end, GFP_NOFS);
btrfs_error_unpin_extent_range(root, start, end);
cond_resched();
Expand Down
23 changes: 11 additions & 12 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1889,8 +1889,8 @@ static int btrfs_issue_discard(struct block_device *bdev,
return blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_NOFS, 0);
}

static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes, u64 *actual_bytes)
int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes, u64 *actual_bytes)
{
int ret;
u64 discarded_bytes = 0;
Expand Down Expand Up @@ -5727,7 +5727,8 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
update_global_block_rsv(fs_info);
}

static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end,
const bool return_free_space)
{
struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_block_group_cache *cache = NULL;
Expand All @@ -5751,7 +5752,8 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)

if (start < cache->last_byte_to_unpin) {
len = min(len, cache->last_byte_to_unpin - start);
btrfs_add_free_space(cache, start, len);
if (return_free_space)
btrfs_add_free_space(cache, start, len);
}

start += len;
Expand Down Expand Up @@ -5815,7 +5817,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
end + 1 - start, NULL);

clear_extent_dirty(unpin, start, end, GFP_NOFS);
unpin_extent_range(root, start, end);
unpin_extent_range(root, start, end, true);
cond_resched();
}

Expand Down Expand Up @@ -8872,6 +8874,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
cache_node);
rb_erase(&block_group->cache_node,
&info->block_group_cache_tree);
RB_CLEAR_NODE(&block_group->cache_node);
spin_unlock(&info->block_group_cache_lock);

down_write(&block_group->space_info->groups_sem);
Expand Down Expand Up @@ -9130,6 +9133,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
spin_lock(&info->block_group_cache_lock);
rb_erase(&cache->cache_node,
&info->block_group_cache_tree);
RB_CLEAR_NODE(&cache->cache_node);
spin_unlock(&info->block_group_cache_lock);
btrfs_put_block_group(cache);
goto error;
Expand Down Expand Up @@ -9271,6 +9275,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
spin_lock(&root->fs_info->block_group_cache_lock);
rb_erase(&cache->cache_node,
&root->fs_info->block_group_cache_tree);
RB_CLEAR_NODE(&cache->cache_node);
spin_unlock(&root->fs_info->block_group_cache_lock);
btrfs_put_block_group(cache);
return ret;
Expand Down Expand Up @@ -9690,13 +9695,7 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info)

int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
{
return unpin_extent_range(root, start, end);
}

int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
u64 num_bytes, u64 *actual_bytes)
{
return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes);
return unpin_extent_range(root, start, end, false);
}

int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
Expand Down
12 changes: 7 additions & 5 deletions fs/btrfs/free-space-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -2966,8 +2966,8 @@ static int do_trimming(struct btrfs_block_group_cache *block_group,
spin_unlock(&block_group->lock);
spin_unlock(&space_info->lock);

ret = btrfs_error_discard_extent(fs_info->extent_root,
start, bytes, &trimmed);
ret = btrfs_discard_extent(fs_info->extent_root,
start, bytes, &trimmed);
if (!ret)
*total_trimmed += trimmed;

Expand Down Expand Up @@ -3185,16 +3185,18 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,

spin_unlock(&block_group->lock);

lock_chunks(block_group->fs_info->chunk_root);
em_tree = &block_group->fs_info->mapping_tree.map_tree;
write_lock(&em_tree->lock);
em = lookup_extent_mapping(em_tree, block_group->key.objectid,
1);
BUG_ON(!em); /* logic error, can't happen */
/*
* remove_extent_mapping() will delete us from the pinned_chunks
* list, which is protected by the chunk mutex.
*/
remove_extent_mapping(em_tree, em);
write_unlock(&em_tree->lock);

lock_chunks(block_group->fs_info->chunk_root);
list_del_init(&em->list);
unlock_chunks(block_group->fs_info->chunk_root);

/* once for us and once for the tree */
Expand Down

0 comments on commit 5c68eac

Please sign in to comment.