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

 - reject unknown mount options

 - adjust transaction abort error message level

 - fix one more build warning with -Wmaybe-uninitialized

 - proper error handling in several COW-related cases

* tag 'for-6.6-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: error out when reallocating block for defrag using a stale transaction
  btrfs: error when COWing block from a root that is being deleted
  btrfs: error out when COWing block using a stale transaction
  btrfs: always print transaction aborted messages with an error level
  btrfs: reject unknown mount options early
  btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c
parents 1d47ae27 e36f9491
Loading
Loading
Loading
Loading
+39 −13
Original line number Diff line number Diff line
@@ -682,18 +682,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
	u64 search_start;
	int ret;

	if (test_bit(BTRFS_ROOT_DELETING, &root->state))
		btrfs_err(fs_info,
			"COW'ing blocks on a fs root that's being dropped");

	if (trans->transaction != fs_info->running_transaction)
		WARN(1, KERN_CRIT "trans %llu running %llu\n",
		       trans->transid,
		       fs_info->running_transaction->transid);
	if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) {
		btrfs_abort_transaction(trans, -EUCLEAN);
		btrfs_crit(fs_info,
		   "attempt to COW block %llu on root %llu that is being deleted",
			   buf->start, btrfs_root_id(root));
		return -EUCLEAN;
	}

	if (trans->transid != fs_info->generation)
		WARN(1, KERN_CRIT "trans %llu running %llu\n",
		       trans->transid, fs_info->generation);
	/*
	 * COWing must happen through a running transaction, which always
	 * matches the current fs generation (it's a transaction with a state
	 * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
	 * into error state to prevent the commit of any transaction.
	 */
	if (unlikely(trans->transaction != fs_info->running_transaction ||
		     trans->transid != fs_info->generation)) {
		btrfs_abort_transaction(trans, -EUCLEAN);
		btrfs_crit(fs_info,
"unexpected transaction when attempting to COW block %llu on root %llu, transaction %llu running transaction %llu fs generation %llu",
			   buf->start, btrfs_root_id(root), trans->transid,
			   fs_info->running_transaction->transid,
			   fs_info->generation);
		return -EUCLEAN;
	}

	if (!should_cow_block(trans, root, buf)) {
		*cow_ret = buf;
@@ -805,8 +817,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
	int progress_passed = 0;
	struct btrfs_disk_key disk_key;

	WARN_ON(trans->transaction != fs_info->running_transaction);
	WARN_ON(trans->transid != fs_info->generation);
	/*
	 * COWing must happen through a running transaction, which always
	 * matches the current fs generation (it's a transaction with a state
	 * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
	 * into error state to prevent the commit of any transaction.
	 */
	if (unlikely(trans->transaction != fs_info->running_transaction ||
		     trans->transid != fs_info->generation)) {
		btrfs_abort_transaction(trans, -EUCLEAN);
		btrfs_crit(fs_info,
"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu",
			   parent->start, btrfs_root_id(root), trans->transid,
			   fs_info->running_transaction->transid,
			   fs_info->generation);
		return -EUCLEAN;
	}

	parent_nritems = btrfs_header_nritems(parent);
	blocksize = fs_info->nodesize;
+2 −2
Original line number Diff line number Diff line
@@ -2978,7 +2978,7 @@ static void get_block_group_info(struct list_head *groups_list,
static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
				   void __user *arg)
{
	struct btrfs_ioctl_space_args space_args;
	struct btrfs_ioctl_space_args space_args = { 0 };
	struct btrfs_ioctl_space_info space;
	struct btrfs_ioctl_space_info *dest;
	struct btrfs_ioctl_space_info *dest_orig;
@@ -4338,7 +4338,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat

	if (compat) {
#if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT)
		struct btrfs_ioctl_send_args_32 args32;
		struct btrfs_ioctl_send_args_32 args32 = { 0 };

		ret = copy_from_user(&args32, argp, sizeof(args32));
		if (ret)
+4 −0
Original line number Diff line number Diff line
@@ -954,6 +954,10 @@ static int btrfs_parse_subvol_options(const char *options, char **subvol_name,

			*subvol_objectid = subvolid;
			break;
		case Opt_err:
			btrfs_err(NULL, "unrecognized mount option '%s'", p);
			error = -EINVAL;
			goto out;
		default:
			break;
		}
+2 −2
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ do { \
			(errno))) {					\
			/* Stack trace printed. */			\
		} else {						\
			btrfs_debug((trans)->fs_info,			\
			btrfs_err((trans)->fs_info,			\
				  "Transaction aborted (error %d)",	\
				  (errno));			\
		}						\