Skip to content

Commit 659e45d

Browse files
committed
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"
2 parents c104f1f + d53ba47 commit 659e45d

File tree

7 files changed

+40
-21
lines changed

7 files changed

+40
-21
lines changed

fs/btrfs/compression.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
405405
bio_put(bio);
406406

407407
bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
408+
BUG_ON(!bio);
408409
bio->bi_private = cb;
409410
bio->bi_end_io = end_compressed_bio_write;
410411
bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
@@ -687,6 +688,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
687688

688689
comp_bio = compressed_bio_alloc(bdev, cur_disk_byte,
689690
GFP_NOFS);
691+
BUG_ON(!comp_bio);
690692
comp_bio->bi_private = cb;
691693
comp_bio->bi_end_io = end_compressed_bio_read;
692694

fs/btrfs/extent-tree.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
529529
* allocate blocks for the tree root we can't do the fast caching since
530530
* we likely hold important locks.
531531
*/
532-
if (trans && (!trans->transaction->in_commit) &&
533-
(root && root != root->fs_info->tree_root) &&
534-
btrfs_test_opt(root, SPACE_CACHE)) {
532+
if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) {
535533
ret = load_free_space_cache(fs_info, cache);
536534

537535
spin_lock(&cache->lock);
@@ -3152,15 +3150,14 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
31523150
/*
31533151
* returns target flags in extended format or 0 if restripe for this
31543152
* chunk_type is not in progress
3153+
*
3154+
* should be called with either volume_mutex or balance_lock held
31553155
*/
31563156
static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags)
31573157
{
31583158
struct btrfs_balance_control *bctl = fs_info->balance_ctl;
31593159
u64 target = 0;
31603160

3161-
BUG_ON(!mutex_is_locked(&fs_info->volume_mutex) &&
3162-
!spin_is_locked(&fs_info->balance_lock));
3163-
31643161
if (!bctl)
31653162
return 0;
31663163

@@ -4205,7 +4202,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
42054202
num_bytes += div64_u64(data_used + meta_used, 50);
42064203

42074204
if (num_bytes * 3 > meta_used)
4208-
num_bytes = div64_u64(meta_used, 3) * 2;
4205+
num_bytes = div64_u64(meta_used, 3);
42094206

42104207
return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10);
42114208
}

fs/btrfs/extent_io.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb,
19371937
struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree;
19381938
u64 start = eb->start;
19391939
unsigned long i, num_pages = num_extent_pages(eb->start, eb->len);
1940-
int ret;
1940+
int ret = 0;
19411941

19421942
for (i = 0; i < num_pages; i++) {
19431943
struct page *p = extent_buffer_page(eb, i);
@@ -2180,6 +2180,10 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
21802180
}
21812181

21822182
bio = bio_alloc(GFP_NOFS, 1);
2183+
if (!bio) {
2184+
free_io_failure(inode, failrec, 0);
2185+
return -EIO;
2186+
}
21832187
bio->bi_private = state;
21842188
bio->bi_end_io = failed_bio->bi_end_io;
21852189
bio->bi_sector = failrec->logical >> 9;

fs/btrfs/free-space-cache.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -747,13 +747,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
747747
bool matched;
748748
u64 used = btrfs_block_group_used(&block_group->item);
749749

750-
/*
751-
* If we're unmounting then just return, since this does a search on the
752-
* normal root and not the commit root and we could deadlock.
753-
*/
754-
if (btrfs_fs_closing(fs_info))
755-
return 0;
756-
757750
/*
758751
* If this block group has been marked to be cleared for one reason or
759752
* 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,
768761
path = btrfs_alloc_path();
769762
if (!path)
770763
return 0;
764+
path->search_commit_root = 1;
765+
path->skip_locking = 1;
771766

772767
inode = lookup_free_space_inode(root, block_group, path);
773768
if (IS_ERR(inode)) {

fs/btrfs/scrub.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,8 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
10441044

10451045
BUG_ON(!page->page);
10461046
bio = bio_alloc(GFP_NOFS, 1);
1047+
if (!bio)
1048+
return -EIO;
10471049
bio->bi_bdev = page->bdev;
10481050
bio->bi_sector = page->physical >> 9;
10491051
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,
11711173
DECLARE_COMPLETION_ONSTACK(complete);
11721174

11731175
bio = bio_alloc(GFP_NOFS, 1);
1176+
if (!bio)
1177+
return -EIO;
11741178
bio->bi_bdev = page_bad->bdev;
11751179
bio->bi_sector = page_bad->physical >> 9;
11761180
bio->bi_end_io = scrub_complete_bio_end_io;

fs/btrfs/transaction.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
480480
struct btrfs_transaction *cur_trans = trans->transaction;
481481
struct btrfs_fs_info *info = root->fs_info;
482482
int count = 0;
483+
int err = 0;
483484

484485
if (--trans->use_count) {
485486
trans->block_rsv = trans->orig_rsv;
@@ -532,18 +533,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
532533

533534
if (current->journal_info == trans)
534535
current->journal_info = NULL;
535-
memset(trans, 0, sizeof(*trans));
536-
kmem_cache_free(btrfs_trans_handle_cachep, trans);
537536

538537
if (throttle)
539538
btrfs_run_delayed_iputs(root);
540539

541540
if (trans->aborted ||
542541
root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
543-
return -EIO;
542+
err = -EIO;
544543
}
545544

546-
return 0;
545+
memset(trans, 0, sizeof(*trans));
546+
kmem_cache_free(btrfs_trans_handle_cachep, trans);
547+
return err;
547548
}
548549

549550
int btrfs_end_transaction(struct btrfs_trans_handle *trans,

fs/btrfs/volumes.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3833,6 +3833,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
38333833
int sub_stripes = 0;
38343834
u64 stripes_per_dev = 0;
38353835
u32 remaining_stripes = 0;
3836+
u32 last_stripe = 0;
38363837

38373838
if (map->type &
38383839
(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,
38463847
stripe_nr_orig,
38473848
factor,
38483849
&remaining_stripes);
3850+
div_u64_rem(stripe_nr_end - 1, factor, &last_stripe);
3851+
last_stripe *= sub_stripes;
38493852
}
38503853

38513854
for (i = 0; i < num_stripes; i++) {
@@ -3858,16 +3861,29 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
38583861
BTRFS_BLOCK_GROUP_RAID10)) {
38593862
bbio->stripes[i].length = stripes_per_dev *
38603863
map->stripe_len;
3864+
38613865
if (i / sub_stripes < remaining_stripes)
38623866
bbio->stripes[i].length +=
38633867
map->stripe_len;
3868+
3869+
/*
3870+
* Special for the first stripe and
3871+
* the last stripe:
3872+
*
3873+
* |-------|...|-------|
3874+
* |----------|
3875+
* off end_off
3876+
*/
38643877
if (i < sub_stripes)
38653878
bbio->stripes[i].length -=
38663879
stripe_offset;
3867-
if ((i / sub_stripes + 1) %
3868-
sub_stripes == remaining_stripes)
3880+
3881+
if (stripe_index >= last_stripe &&
3882+
stripe_index <= (last_stripe +
3883+
sub_stripes - 1))
38693884
bbio->stripes[i].length -=
38703885
stripe_end_offset;
3886+
38713887
if (i == sub_stripes - 1)
38723888
stripe_offset = 0;
38733889
} else

0 commit comments

Comments
 (0)