]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: fix leaking BTRFS_FS_STATE_REMOUNTING flag
authorQu Wenruo <wqu@suse.com>
Sat, 4 Jul 2026 08:28:56 +0000 (17:58 +0930)
committerDavid Sterba <dsterba@suse.com>
Tue, 21 Jul 2026 04:39:39 +0000 (06:39 +0200)
[BUG]
The following script can lead to unexpected qgroup rescan failure:

  # mkfs.btrfs -f -O quota $dev
  # mount $dev $mnt
  # mount -o remount,rescue=ibadroots $mnt
    ^^^^^ This above command is expected to fail

  # btrfs quota rescan -w $mnt
    ^^^^^ The above qgroup rescan is not expected to fail

  # btrfs qgroup show $mnt
  WARNING: qgroup data inconsistent, rescan recommended
  Qgroupid    Referenced    Exclusive   Path
  --------    ----------    ---------   ----
  0/5           16.00KiB     16.00KiB   <toplevel>

The above short script will be converted to a proper fstests case.

[CAUSE]
Inside btrfs_reconfigure(), if either btrfs_check_options() or
btrfs_check_features() failed, we will always have
BTRFS_FS_STATE_REMOUNTING set for the fs until the next successful
remount.

That BTRFS_FS_STATE_REMOUNTING flag will interrupt several operations,
including:

- Qgroup rescan
- Auto defrag
- Space reclaim

[FIX]
Change the error handling of btrfs_check_options() and
btrfs_check_features() to goto restore label.

Fixes: eddb1a433f26 ("btrfs: add reconfigure callback for fs_context")
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/super.c

index c946bccf07481baa56e8d2d9e08c22a0bd2de254..63bf1f1e16d480fc8dc2d52b946accc303fadcb5 100644 (file)
@@ -1519,12 +1519,14 @@ static int btrfs_reconfigure(struct fs_context *fc)
        sync_filesystem(sb);
        set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
 
-       if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
-               return -EINVAL;
+       if (!btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags)) {
+               ret = -EINVAL;
+               goto restore;
+       }
 
        ret = btrfs_check_features(fs_info, !(fc->sb_flags & SB_RDONLY));
        if (ret < 0)
-               return ret;
+               goto restore;
 
        btrfs_ctx_to_info(fs_info, ctx);
        btrfs_remount_begin(fs_info, old_ctx.mount_opt, fc->sb_flags);