Commit fc7b76c4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:
 "A few more regression and regular fixes:

   - regressions:
       - fix assertion condition using = instead of ==
       - fix false alert on bad tree level check
       - fix off-by-one error in delalloc search during lseek

   - fix compat ro feature check at read-write remount

   - handle case when read-repair happens with ongoing device replace

   - updated error messages"

* tag 'for-6.2-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix compat_ro checks against remount
  btrfs: always report error in run_one_delayed_ref()
  btrfs: handle case when repair happens with dev-replace
  btrfs: fix off-by-one in delalloc search during lseek
  btrfs: fix false alert on bad tree level check
  btrfs: add error message for metadata level mismatch
  btrfs: fix ASSERT em->len condition in btrfs_get_extent
parents a389e546 2ba48b20
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -329,7 +329,16 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
				      &map_length, &bioc, mirror_num);
		if (ret)
			goto out_counter_dec;
		BUG_ON(mirror_num != bioc->mirror_num);
		/*
		 * This happens when dev-replace is also running, and the
		 * mirror_num indicates the dev-replace target.
		 *
		 * In this case, we don't need to do anything, as the read
		 * error just means the replace progress hasn't reached our
		 * read range, and later replace routine would handle it well.
		 */
		if (mirror_num != bioc->mirror_num)
			goto out_counter_dec;
	}

	sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
+8 −3
Original line number Diff line number Diff line
@@ -530,6 +530,9 @@ static int validate_extent_buffer(struct extent_buffer *eb,
	}

	if (found_level != check->level) {
		btrfs_err(fs_info,
		"level verify failed on logical %llu mirror %u wanted %u found %u",
			  eb->start, eb->read_mirror, check->level, found_level);
		ret = -EIO;
		goto out;
	}
@@ -3381,6 +3384,8 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
/*
 * Do various sanity and dependency checks of different features.
 *
 * @is_rw_mount:	If the mount is read-write.
 *
 * This is the place for less strict checks (like for subpage or artificial
 * feature dependencies).
 *
@@ -3391,7 +3396,7 @@ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info)
 * (space cache related) can modify on-disk format like free space tree and
 * screw up certain feature dependencies.
 */
int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb)
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
{
	struct btrfs_super_block *disk_super = fs_info->super_copy;
	u64 incompat = btrfs_super_incompat_flags(disk_super);
@@ -3430,7 +3435,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb)
	if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
		incompat |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;

	if (compat_ro_unsupp && !sb_rdonly(sb)) {
	if (compat_ro_unsupp && is_rw_mount) {
		btrfs_err(fs_info,
	"cannot mount read-write because of unknown compat_ro features (0x%llx)",
		       compat_ro);
@@ -3633,7 +3638,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
		goto fail_alloc;
	}

	ret = btrfs_check_features(fs_info, sb);
	ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
	if (ret < 0) {
		err = ret;
		goto fail_alloc;
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ int __cold open_ctree(struct super_block *sb,
void __cold close_ctree(struct btrfs_fs_info *fs_info);
int btrfs_validate_super(struct btrfs_fs_info *fs_info,
			 struct btrfs_super_block *sb, int mirror_num);
int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb);
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+1 −1
Original line number Diff line number Diff line
@@ -1551,7 +1551,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
	u64 last = 0;
	int found = 0;

	if (WARN_ON(search_end <= cur_start))
	if (WARN_ON(search_end < cur_start))
		return 0;

	spin_lock(&tree->lock);
+5 −2
Original line number Diff line number Diff line
@@ -1713,6 +1713,11 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
		BUG();
	if (ret && insert_reserved)
		btrfs_pin_extent(trans, node->bytenr, node->num_bytes, 1);
	if (ret < 0)
		btrfs_err(trans->fs_info,
"failed to run delayed ref for logical %llu num_bytes %llu type %u action %u ref_mod %d: %d",
			  node->bytenr, node->num_bytes, node->type,
			  node->action, node->ref_mod, ret);
	return ret;
}

@@ -1954,8 +1959,6 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
		if (ret) {
			unselect_delayed_ref_head(delayed_refs, locked_ref);
			btrfs_put_delayed_ref(ref);
			btrfs_debug(fs_info, "run_one_delayed_ref returned %d",
				    ret);
			return ret;
		}

Loading