Commit 1767a722 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:

 - revert memory optimization for scrub blocks, this misses errors in
   2nd and following blocks

 - add exception for ENOMEM as reason for transaction abort to not print
   stack trace, syzbot has reported many

 - zoned fixes:
      - fix locking imbalance during scrub
      - initialize zones for seeding device
      - initialize zones for cloned device structures

 - when looking up device, change assertion to a real check as some of
   the search parameters can be passed by ioctl, reported by syzbot

 - fix error pointer check in self tests

* tag 'for-6.1-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: zoned: fix locking imbalance on scrub
  btrfs: zoned: initialize device's zone info for seeding
  btrfs: zoned: clone zoned device info when cloning a device
  Revert "btrfs: scrub: use larger block size for data extent scrub"
  btrfs: don't print stack trace when transaction is aborted due to ENOMEM
  btrfs: selftests: fix wrong error check in btrfs_free_dummy_root()
  btrfs: fix match incorrectly in dev_args_match_device
parents f014699c c62f6bec
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -113,6 +113,22 @@ noinline void btrfs_release_path(struct btrfs_path *p)
	}
}

/*
 * We want the transaction abort to print stack trace only for errors where the
 * cause could be a bug, eg. due to ENOSPC, and not for common errors that are
 * caused by external factors.
 */
bool __cold abort_should_print_stack(int errno)
{
	switch (errno) {
	case -EIO:
	case -EROFS:
	case -ENOMEM:
		return false;
	}
	return true;
}

/*
 * safely gets a reference on the root node of a tree.  A lock
 * is not taken, so a concurrent writer may put a different node
+7 −4
Original line number Diff line number Diff line
@@ -3796,9 +3796,11 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
			       const char *function,
			       unsigned int line, int errno, bool first_hit);

bool __cold abort_should_print_stack(int errno);

/*
 * Call btrfs_abort_transaction as early as possible when an error condition is
 * detected, that way the exact line number is reported.
 * detected, that way the exact stack trace is reported for some errors.
 */
#define btrfs_abort_transaction(trans, errno)		\
do {								\
@@ -3807,10 +3809,11 @@ do { \
	if (!test_and_set_bit(BTRFS_FS_STATE_TRANS_ABORTED,	\
			&((trans)->fs_info->fs_state))) {	\
		first = true;					\
		if ((errno) != -EIO && (errno) != -EROFS) {		\
			WARN(1, KERN_DEBUG				\
		if (WARN(abort_should_print_stack(errno), 	\
			KERN_DEBUG				\
			"BTRFS: Transaction aborted (error %d)\n",	\
			(errno));					\
			(errno))) {					\
			/* Stack trace printed. */			\
		} else {						\
			btrfs_debug((trans)->fs_info,			\
				    "Transaction aborted (error %d)", \
+3 −1
Original line number Diff line number Diff line
@@ -2551,7 +2551,9 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
		fs_info->dev_root = root;
	}
	/* Initialize fs_info for all devices in any case */
	btrfs_init_devices_late(fs_info);
	ret = btrfs_init_devices_late(fs_info);
	if (ret)
		goto out;

	/*
	 * This tree can share blocks with some other fs tree during relocation
+1 −8
Original line number Diff line number Diff line
@@ -2672,17 +2672,11 @@ static int scrub_extent(struct scrub_ctx *sctx, struct map_lookup *map,
	u8 csum[BTRFS_CSUM_SIZE];
	u32 blocksize;

	/*
	 * Block size determines how many scrub_block will be allocated.  Here
	 * we use BTRFS_STRIPE_LEN (64KiB) as default limit, so we won't
	 * allocate too many scrub_block, while still won't cause too large
	 * bios for large extents.
	 */
	if (flags & BTRFS_EXTENT_FLAG_DATA) {
		if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
			blocksize = map->stripe_len;
		else
			blocksize = BTRFS_STRIPE_LEN;
			blocksize = sctx->fs_info->sectorsize;
		spin_lock(&sctx->stat_lock);
		sctx->stat.data_extents_scrubbed++;
		sctx->stat.data_bytes_scrubbed += len;
@@ -3917,7 +3911,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,

		if (sctx->is_dev_replace && btrfs_is_zoned(fs_info)) {
			if (!test_bit(BLOCK_GROUP_FLAG_TO_COPY, &cache->runtime_flags)) {
				spin_unlock(&cache->lock);
				btrfs_put_block_group(cache);
				goto skip;
			}
+1 −1
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)

void btrfs_free_dummy_root(struct btrfs_root *root)
{
	if (!root)
	if (IS_ERR_OR_NULL(root))
		return;
	/* Will be freed by btrfs_free_fs_roots */
	if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))
Loading