Skip to content

Commit b158dd9

Browse files
committed
Merge tag 'for-6.4-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - handle memory allocation error in checksumming helper (reported by syzbot) - fix lockdep splat when aborting a transaction, add NOFS protection around invalidate_inode_pages2 that could allocate with GFP_KERNEL - reduce chances to hit an ENOSPC during scrub with RAID56 profiles * tag 'for-6.4-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: use nofs when cleaning up aborted transactions btrfs: handle memory allocation failure in btrfs_csum_one_bio btrfs: scrub: try harder to mark RAID56 block groups read-only
2 parents b83ac44 + 597441b commit b158dd9

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

fs/btrfs/block-group.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,10 +2818,20 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache,
28182818
}
28192819

28202820
ret = inc_block_group_ro(cache, 0);
2821-
if (!do_chunk_alloc || ret == -ETXTBSY)
2822-
goto unlock_out;
28232821
if (!ret)
28242822
goto out;
2823+
if (ret == -ETXTBSY)
2824+
goto unlock_out;
2825+
2826+
/*
2827+
* Skip chunk alloction if the bg is SYSTEM, this is to avoid system
2828+
* chunk allocation storm to exhaust the system chunk array. Otherwise
2829+
* we still want to try our best to mark the block group read-only.
2830+
*/
2831+
if (!do_chunk_alloc && ret == -ENOSPC &&
2832+
(cache->flags & BTRFS_BLOCK_GROUP_SYSTEM))
2833+
goto unlock_out;
2834+
28252835
alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags);
28262836
ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
28272837
if (ret < 0)

fs/btrfs/disk-io.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4936,7 +4936,11 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
49364936
*/
49374937
inode = igrab(&btrfs_inode->vfs_inode);
49384938
if (inode) {
4939+
unsigned int nofs_flag;
4940+
4941+
nofs_flag = memalloc_nofs_save();
49394942
invalidate_inode_pages2(inode->i_mapping);
4943+
memalloc_nofs_restore(nofs_flag);
49404944
iput(inode);
49414945
}
49424946
spin_lock(&root->delalloc_lock);
@@ -5042,7 +5046,12 @@ static void btrfs_cleanup_bg_io(struct btrfs_block_group *cache)
50425046

50435047
inode = cache->io_ctl.inode;
50445048
if (inode) {
5049+
unsigned int nofs_flag;
5050+
5051+
nofs_flag = memalloc_nofs_save();
50455052
invalidate_inode_pages2(inode->i_mapping);
5053+
memalloc_nofs_restore(nofs_flag);
5054+
50465055
BTRFS_I(inode)->generation = 0;
50475056
cache->io_ctl.inode = NULL;
50485057
iput(inode);

fs/btrfs/file-item.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,9 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio)
792792
sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
793793
bytes_left), GFP_KERNEL);
794794
memalloc_nofs_restore(nofs_flag);
795-
BUG_ON(!sums); /* -ENOMEM */
795+
if (!sums)
796+
return BLK_STS_RESOURCE;
797+
796798
sums->len = bytes_left;
797799
ordered = btrfs_lookup_ordered_extent(inode,
798800
offset);

fs/btrfs/scrub.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2518,13 +2518,20 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
25182518

25192519
if (ret == 0) {
25202520
ro_set = 1;
2521-
} else if (ret == -ENOSPC && !sctx->is_dev_replace) {
2521+
} else if (ret == -ENOSPC && !sctx->is_dev_replace &&
2522+
!(cache->flags & BTRFS_BLOCK_GROUP_RAID56_MASK)) {
25222523
/*
25232524
* btrfs_inc_block_group_ro return -ENOSPC when it
25242525
* failed in creating new chunk for metadata.
25252526
* It is not a problem for scrub, because
25262527
* metadata are always cowed, and our scrub paused
25272528
* commit_transactions.
2529+
*
2530+
* For RAID56 chunks, we have to mark them read-only
2531+
* for scrub, as later we would use our own cache
2532+
* out of RAID56 realm.
2533+
* Thus we want the RAID56 bg to be marked RO to
2534+
* prevent RMW from screwing up out cache.
25282535
*/
25292536
ro_set = 0;
25302537
} else if (ret == -ETXTBSY) {

0 commit comments

Comments
 (0)