Skip to content

Commit 7de25c8

Browse files
committed
Merge tag 'for-6.6-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
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
2 parents 1d47ae2 + e36f949 commit 7de25c8

File tree

4 files changed

+47
-17
lines changed

4 files changed

+47
-17
lines changed

fs/btrfs/ctree.c

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -682,18 +682,30 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
682682
u64 search_start;
683683
int ret;
684684

685-
if (test_bit(BTRFS_ROOT_DELETING, &root->state))
686-
btrfs_err(fs_info,
687-
"COW'ing blocks on a fs root that's being dropped");
688-
689-
if (trans->transaction != fs_info->running_transaction)
690-
WARN(1, KERN_CRIT "trans %llu running %llu\n",
691-
trans->transid,
692-
fs_info->running_transaction->transid);
685+
if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) {
686+
btrfs_abort_transaction(trans, -EUCLEAN);
687+
btrfs_crit(fs_info,
688+
"attempt to COW block %llu on root %llu that is being deleted",
689+
buf->start, btrfs_root_id(root));
690+
return -EUCLEAN;
691+
}
693692

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

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

808-
WARN_ON(trans->transaction != fs_info->running_transaction);
809-
WARN_ON(trans->transid != fs_info->generation);
820+
/*
821+
* COWing must happen through a running transaction, which always
822+
* matches the current fs generation (it's a transaction with a state
823+
* less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
824+
* into error state to prevent the commit of any transaction.
825+
*/
826+
if (unlikely(trans->transaction != fs_info->running_transaction ||
827+
trans->transid != fs_info->generation)) {
828+
btrfs_abort_transaction(trans, -EUCLEAN);
829+
btrfs_crit(fs_info,
830+
"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu",
831+
parent->start, btrfs_root_id(root), trans->transid,
832+
fs_info->running_transaction->transid,
833+
fs_info->generation);
834+
return -EUCLEAN;
835+
}
810836

811837
parent_nritems = btrfs_header_nritems(parent);
812838
blocksize = fs_info->nodesize;

fs/btrfs/ioctl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,7 +2978,7 @@ static void get_block_group_info(struct list_head *groups_list,
29782978
static long btrfs_ioctl_space_info(struct btrfs_fs_info *fs_info,
29792979
void __user *arg)
29802980
{
2981-
struct btrfs_ioctl_space_args space_args;
2981+
struct btrfs_ioctl_space_args space_args = { 0 };
29822982
struct btrfs_ioctl_space_info space;
29832983
struct btrfs_ioctl_space_info *dest;
29842984
struct btrfs_ioctl_space_info *dest_orig;
@@ -4338,7 +4338,7 @@ static int _btrfs_ioctl_send(struct inode *inode, void __user *argp, bool compat
43384338

43394339
if (compat) {
43404340
#if defined(CONFIG_64BIT) && defined(CONFIG_COMPAT)
4341-
struct btrfs_ioctl_send_args_32 args32;
4341+
struct btrfs_ioctl_send_args_32 args32 = { 0 };
43424342

43434343
ret = copy_from_user(&args32, argp, sizeof(args32));
43444344
if (ret)

fs/btrfs/super.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,10 @@ static int btrfs_parse_subvol_options(const char *options, char **subvol_name,
954954

955955
*subvol_objectid = subvolid;
956956
break;
957+
case Opt_err:
958+
btrfs_err(NULL, "unrecognized mount option '%s'", p);
959+
error = -EINVAL;
960+
goto out;
957961
default:
958962
break;
959963
}

fs/btrfs/transaction.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ do { \
219219
(errno))) { \
220220
/* Stack trace printed. */ \
221221
} else { \
222-
btrfs_debug((trans)->fs_info, \
223-
"Transaction aborted (error %d)", \
222+
btrfs_err((trans)->fs_info, \
223+
"Transaction aborted (error %d)", \
224224
(errno)); \
225225
} \
226226
} \

0 commit comments

Comments
 (0)