Commit e2f0c565 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from David Sterba:
 "A handful of minor fixes and updates:

   - handle missing device replace item on mount (syzbot report)

   - fix space reservation calculation when finishing relocation

   - fix memory leak on error path in ref-verify (debugging feature)

   - fix potential overflow during defrag on 32bit arches

   - minor code update to silence smatch warning

   - minor error message updates"

* tag 'for-5.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: ref-verify: fix memory leak in btrfs_ref_tree_mod
  btrfs: dev-replace: fail mount if we don't have replace item with target device
  btrfs: scrub: update message regarding read-only status
  btrfs: clean up NULL checks in qgroup_unreserve_range()
  btrfs: fix min reserved size calculation in merge_reloc_root
  btrfs: print the block rsv type when we fail our reservation
  btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch
parents 52d1998d 468600c6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -511,7 +511,8 @@ struct btrfs_block_rsv *btrfs_use_block_rsv(struct btrfs_trans_handle *trans,
				/*DEFAULT_RATELIMIT_BURST*/ 1);
		if (__ratelimit(&_rs))
			WARN(1, KERN_DEBUG
				"BTRFS: block rsv returned %d\n", ret);
				"BTRFS: block rsv %d returned %d\n",
				block_rsv->type, ret);
	}
try_reserve:
	ret = btrfs_reserve_metadata_bytes(root, block_rsv, blocksize,
+24 −2
Original line number Diff line number Diff line
@@ -91,6 +91,17 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
	ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);
	if (ret) {
no_valid_dev_replace_entry_found:
		/*
		 * We don't have a replace item or it's corrupted.  If there is
		 * a replace target, fail the mount.
		 */
		if (btrfs_find_device(fs_info->fs_devices,
				      BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) {
			btrfs_err(fs_info,
			"found replace target device without a valid replace item");
			ret = -EUCLEAN;
			goto out;
		}
		ret = 0;
		dev_replace->replace_state =
			BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
@@ -143,8 +154,19 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
	case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
	case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
	case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
		/*
		 * We don't have an active replace item but if there is a
		 * replace target, fail the mount.
		 */
		if (btrfs_find_device(fs_info->fs_devices,
				      BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) {
			btrfs_err(fs_info,
			"replace devid present without an active replace item");
			ret = -EUCLEAN;
		} else {
			dev_replace->srcdev = NULL;
			dev_replace->tgtdev = NULL;
		}
		break;
	case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
	case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
+4 −6
Original line number Diff line number Diff line
@@ -1274,6 +1274,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
	u64 page_start;
	u64 page_end;
	u64 page_cnt;
	u64 start = (u64)start_index << PAGE_SHIFT;
	int ret;
	int i;
	int i_done;
@@ -1290,8 +1291,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
	page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1);

	ret = btrfs_delalloc_reserve_space(BTRFS_I(inode), &data_reserved,
			start_index << PAGE_SHIFT,
			page_cnt << PAGE_SHIFT);
			start, page_cnt << PAGE_SHIFT);
	if (ret)
		return ret;
	i_done = 0;
@@ -1380,8 +1380,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
		btrfs_mod_outstanding_extents(BTRFS_I(inode), 1);
		spin_unlock(&BTRFS_I(inode)->lock);
		btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
				start_index << PAGE_SHIFT,
				(page_cnt - i_done) << PAGE_SHIFT, true);
				start, (page_cnt - i_done) << PAGE_SHIFT, true);
	}


@@ -1408,8 +1407,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
		put_page(pages[i]);
	}
	btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved,
			start_index << PAGE_SHIFT,
			page_cnt << PAGE_SHIFT, true);
			start, page_cnt << PAGE_SHIFT, true);
	btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT);
	extent_changeset_free(data_reserved);
	return ret;
+4 −8
Original line number Diff line number Diff line
@@ -3435,24 +3435,20 @@ static int qgroup_unreserve_range(struct btrfs_inode *inode,
{
	struct rb_node *node;
	struct rb_node *next;
	struct ulist_node *entry = NULL;
	struct ulist_node *entry;
	int ret = 0;

	node = reserved->range_changed.root.rb_node;
	if (!node)
		return 0;
	while (node) {
		entry = rb_entry(node, struct ulist_node, rb_node);
		if (entry->val < start)
			node = node->rb_right;
		else if (entry)
			node = node->rb_left;
		else
			break;
			node = node->rb_left;
	}

	/* Empty changeset */
	if (!entry)
		return 0;

	if (entry->val > start && rb_prev(&entry->rb_node))
		entry = rb_entry(rb_prev(&entry->rb_node), struct ulist_node,
				 rb_node);
+1 −0
Original line number Diff line number Diff line
@@ -860,6 +860,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
"dropping a ref for a root that doesn't have a ref on the block");
			dump_block_entry(fs_info, be);
			dump_ref_action(fs_info, ra);
			kfree(ref);
			kfree(ra);
			goto out_unlock;
		}
Loading