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
Unified · Split
| @@ -2818,10 +2818,20 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache, · 2817 unmodified lines | ||
| 2818 | 2818 | } |
| 2819 | 2819 | |
| 2820 | 2820 | ret = inc_block_group_ro(cache, 0); |
| 2821 | − if (!do_chunk_alloc || ret == -ETXTBSY) | |
| 2822 | − goto unlock_out; | |
| 2823 | 2821 | if (!ret) |
| 2824 | 2822 | 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 | + | |
| 2825 | 2835 | alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags); |
| 2826 | 2836 | ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE); |
| 2827 | 2837 | if (ret < 0) |
| @@ -4936,7 +4936,11 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) · 4935 unmodified lines | ||
| 4936 | 4936 | */ |
| 4937 | 4937 | inode = igrab(&btrfs_inode->vfs_inode); |
| 4938 | 4938 | if (inode) { |
| 4939 | + unsigned int nofs_flag; | |
| 4940 | + | |
| 4941 | + nofs_flag = memalloc_nofs_save(); | |
| 4939 | 4942 | invalidate_inode_pages2(inode->i_mapping); |
| 4943 | + memalloc_nofs_restore(nofs_flag); | |
| 4940 | 4944 | iput(inode); |
| 4941 | 4945 | } |
| 4942 | 4946 | spin_lock(&root->delalloc_lock); |
| @@ -5042,7 +5046,12 @@ static void btrfs_cleanup_bg_io(struct btrfs_block_group *cache) · 99 unmodified lines | ||
| 5042 | 5046 | |
| 5043 | 5047 | inode = cache->io_ctl.inode; |
| 5044 | 5048 | if (inode) { |
| 5049 | + unsigned int nofs_flag; | |
| 5050 | + | |
| 5051 | + nofs_flag = memalloc_nofs_save(); | |
| 5045 | 5052 | invalidate_inode_pages2(inode->i_mapping); |
| 5053 | + memalloc_nofs_restore(nofs_flag); | |
| 5054 | + | |
| 5046 | 5055 | BTRFS_I(inode)->generation = 0; |
| 5047 | 5056 | cache->io_ctl.inode = NULL; |
| 5048 | 5057 | iput(inode); |
| @@ -792,7 +792,9 @@ blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio) · 791 unmodified lines | ||
| 792 | 792 | sums = kvzalloc(btrfs_ordered_sum_size(fs_info, |
| 793 | 793 | bytes_left), GFP_KERNEL); |
| 794 | 794 | memalloc_nofs_restore(nofs_flag); |
| 795 | − BUG_ON(!sums); /* -ENOMEM */ | |
| 795 | + if (!sums) | |
| 796 | + return BLK_STS_RESOURCE; | |
| 797 | + | |
| 796 | 798 | sums->len = bytes_left; |
| 797 | 799 | ordered = btrfs_lookup_ordered_extent(inode, |
| 798 | 800 | offset); |
| @@ -2518,13 +2518,20 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, · 2517 unmodified lines | ||
| 2518 | 2518 | |
| 2519 | 2519 | if (ret == 0) { |
| 2520 | 2520 | 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)) { | |
| 2522 | 2523 | /* |
| 2523 | 2524 | * btrfs_inc_block_group_ro return -ENOSPC when it |
| 2524 | 2525 | * failed in creating new chunk for metadata. |
| 2525 | 2526 | * It is not a problem for scrub, because |
| 2526 | 2527 | * metadata are always cowed, and our scrub paused |
| 2527 | 2528 | * 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. | |
| 2528 | 2535 | */ |
| 2529 | 2536 | ro_set = 0; |
| 2530 | 2537 | } else if (ret == -ETXTBSY) { |