mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Merge branch 'for-linus-min' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull the minimal btrfs branch from Chris Mason: "We have a use-after-free in there, along with errors when mount -o discard is enabled, and a BUG_ON(we should compile with UP more often)." * 'for-linus-min' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs: use commit root when loading free space cache Btrfs: fix use-after-free in __btrfs_end_transaction Btrfs: check return value of bio_alloc() properly Btrfs: remove lock assert from get_restripe_target() Btrfs: fix eof while discarding extents Btrfs: fix uninit variable in repair_eb_io_failure Revert "Btrfs: increase the global block reserve estimates"
This commit is contained in:
commit
659e45d8a0
@ -405,6 +405,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
|
||||
bio_put(bio);
|
||||
|
||||
bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
|
||||
BUG_ON(!bio);
|
||||
bio->bi_private = cb;
|
||||
bio->bi_end_io = end_compressed_bio_write;
|
||||
bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
|
||||
@ -687,6 +688,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
|
||||
|
||||
comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
|
||||
GFP_NOFS);
|
||||
BUG_ON(!comp_bio);
|
||||
comp_bio->bi_private = cb;
|
||||
comp_bio->bi_end_io = end_compressed_bio_read;
|
||||
|
||||
|
@ -529,9 +529,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
|
||||
* allocate blocks for the tree root we can't do the fast caching since
|
||||
* we likely hold important locks.
|
||||
*/
|
||||
if (trans && (!trans->transaction->in_commit) &&
|
||||
(root && root != root->fs_info->tree_root) &&
|
||||
btrfs_test_opt(root, SPACE_CACHE)) {
|
||||
if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) {
|
||||
ret = load_free_space_cache(fs_info, cache);
|
||||
|
||||
spin_lock(&cache->lock);
|
||||
@ -3152,15 +3150,14 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
|
||||
/*
|
||||
* returns target flags in extended format or 0 if restripe for this
|
||||
* chunk_type is not in progress
|
||||
*
|
||||
* should be called with either volume_mutex or balance_lock held
|
||||
*/
|
||||
static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags)
|
||||
{
|
||||
struct btrfs_balance_control *bctl = fs_info->balance_ctl;
|
||||
u64 target = 0;
|
||||
|
||||
BUG_ON(!mutex_is_locked(&fs_info->volume_mutex) &&
|
||||
!spin_is_locked(&fs_info->balance_lock));
|
||||
|
||||
if (!bctl)
|
||||
return 0;
|
||||
|
||||
@ -4205,7 +4202,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
|
||||
num_bytes += div64_u64(data_used + meta_used, 50);
|
||||
|
||||
if (num_bytes * 3 > meta_used)
|
||||
num_bytes = div64_u64(meta_used, 3) * 2;
|
||||
num_bytes = div64_u64(meta_used, 3);
|
||||
|
||||
return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10);
|
||||
}
|
||||
|
@ -1937,7 +1937,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
|
||||
struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
|
||||
u64 start = eb->start;
|
||||
unsigned long i, num_pages = num_extent_pages(eb->start, eb->len);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
struct page *p = extent_buffer_page(eb, i);
|
||||
@ -2180,6 +2180,10 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
|
||||
}
|
||||
|
||||
bio = bio_alloc(GFP_NOFS, 1);
|
||||
if (!bio) {
|
||||
free_io_failure(inode, failrec, 0);
|
||||
return -EIO;
|
||||
}
|
||||
bio->bi_private = state;
|
||||
bio->bi_end_io = failed_bio->bi_end_io;
|
||||
bio->bi_sector = failrec->logical >> 9;
|
||||
|
@ -747,13 +747,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
|
||||
bool matched;
|
||||
u64 used = btrfs_block_group_used(&block_group->item);
|
||||
|
||||
/*
|
||||
* If we're unmounting then just return, since this does a search on the
|
||||
* normal root and not the commit root and we could deadlock.
|
||||
*/
|
||||
if (btrfs_fs_closing(fs_info))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this block group has been marked to be cleared for one reason or
|
||||
* another then we can't trust the on disk cache, so just return.
|
||||
@ -768,6 +761,8 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return 0;
|
||||
path->search_commit_root = 1;
|
||||
path->skip_locking = 1;
|
||||
|
||||
inode = lookup_free_space_inode(root, block_group, path);
|
||||
if (IS_ERR(inode)) {
|
||||
|
@ -1044,6 +1044,8 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
|
||||
|
||||
BUG_ON(!page->page);
|
||||
bio = bio_alloc(GFP_NOFS, 1);
|
||||
if (!bio)
|
||||
return -EIO;
|
||||
bio->bi_bdev = page->bdev;
|
||||
bio->bi_sector = page->physical >> 9;
|
||||
bio->bi_end_io = scrub_complete_bio_end_io;
|
||||
@ -1171,6 +1173,8 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad,
|
||||
DECLARE_COMPLETION_ONSTACK(complete);
|
||||
|
||||
bio = bio_alloc(GFP_NOFS, 1);
|
||||
if (!bio)
|
||||
return -EIO;
|
||||
bio->bi_bdev = page_bad->bdev;
|
||||
bio->bi_sector = page_bad->physical >> 9;
|
||||
bio->bi_end_io = scrub_complete_bio_end_io;
|
||||
|
@ -480,6 +480,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_transaction *cur_trans = trans->transaction;
|
||||
struct btrfs_fs_info *info = root->fs_info;
|
||||
int count = 0;
|
||||
int err = 0;
|
||||
|
||||
if (--trans->use_count) {
|
||||
trans->block_rsv = trans->orig_rsv;
|
||||
@ -532,18 +533,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (current->journal_info == trans)
|
||||
current->journal_info = NULL;
|
||||
memset(trans, 0, sizeof(*trans));
|
||||
kmem_cache_free(btrfs_trans_handle_cachep, trans);
|
||||
|
||||
if (throttle)
|
||||
btrfs_run_delayed_iputs(root);
|
||||
|
||||
if (trans->aborted ||
|
||||
root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
|
||||
return -EIO;
|
||||
err = -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
memset(trans, 0, sizeof(*trans));
|
||||
kmem_cache_free(btrfs_trans_handle_cachep, trans);
|
||||
return err;
|
||||
}
|
||||
|
||||
int btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
||||
|
@ -3833,6 +3833,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
|
||||
int sub_stripes = 0;
|
||||
u64 stripes_per_dev = 0;
|
||||
u32 remaining_stripes = 0;
|
||||
u32 last_stripe = 0;
|
||||
|
||||
if (map->type &
|
||||
(BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
|
||||
@ -3846,6 +3847,8 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
|
||||
stripe_nr_orig,
|
||||
factor,
|
||||
&remaining_stripes);
|
||||
div_u64_rem(stripe_nr_end - 1, factor, &last_stripe);
|
||||
last_stripe *= sub_stripes;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_stripes; i++) {
|
||||
@ -3858,16 +3861,29 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
|
||||
BTRFS_BLOCK_GROUP_RAID10)) {
|
||||
bbio->stripes[i].length = stripes_per_dev *
|
||||
map->stripe_len;
|
||||
|
||||
if (i / sub_stripes < remaining_stripes)
|
||||
bbio->stripes[i].length +=
|
||||
map->stripe_len;
|
||||
|
||||
/*
|
||||
* Special for the first stripe and
|
||||
* the last stripe:
|
||||
*
|
||||
* |-------|...|-------|
|
||||
* |----------|
|
||||
* off end_off
|
||||
*/
|
||||
if (i < sub_stripes)
|
||||
bbio->stripes[i].length -=
|
||||
stripe_offset;
|
||||
if ((i / sub_stripes + 1) %
|
||||
sub_stripes == remaining_stripes)
|
||||
|
||||
if (stripe_index >= last_stripe &&
|
||||
stripe_index <= (last_stripe +
|
||||
sub_stripes - 1))
|
||||
bbio->stripes[i].length -=
|
||||
stripe_end_offset;
|
||||
|
||||
if (i == sub_stripes - 1)
|
||||
stripe_offset = 0;
|
||||
} else
|
||||
|
Loading…
Reference in New Issue
Block a user