Patch "btrfs: fix race between quota disable and relocation" has been added to the 6.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    btrfs: fix race between quota disable and relocation

to the 6.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     btrfs-fix-race-between-quota-disable-and-relocation.patch
and it can be found in the queue-6.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit bba37123142550a2467252249f109608aae2ce94
Author: Filipe Manana <fdmanana@xxxxxxxx>
Date:   Mon Jun 19 17:21:50 2023 +0100

    btrfs: fix race between quota disable and relocation
    
    [ Upstream commit 8a4a0b2a3eaf75ca8854f856ef29690c12b2f531 ]
    
    If we disable quotas while we have a relocation of a metadata block group
    that has extents belonging to the quota root, we can cause the relocation
    to fail with -ENOENT. This is because relocation builds backref nodes for
    extents of the quota root and later needs to walk the backrefs and access
    the quota root - however if in between a task disables quotas, it results
    in deleting the quota root from the root tree (with btrfs_del_root(),
    called from btrfs_quota_disable().
    
    This can be sporadically triggered by test case btrfs/255 from fstests:
    
      $ ./check btrfs/255
      FSTYP         -- btrfs
      PLATFORM      -- Linux/x86_64 debian0 6.4.0-rc6-btrfs-next-134+ #1 SMP PREEMPT_DYNAMIC Thu Jun 15 11:59:28 WEST 2023
      MKFS_OPTIONS  -- /dev/sdc
      MOUNT_OPTIONS -- /dev/sdc /home/fdmanana/btrfs-tests/scratch_1
    
      btrfs/255 6s ... _check_dmesg: something found in dmesg (see /home/fdmanana/git/hub/xfstests/results//btrfs/255.dmesg)
      - output mismatch (see /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad)
          --- tests/btrfs/255.out   2023-03-02 21:47:53.876609426 +0000
          +++ /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad    2023-06-16 10:20:39.267563212 +0100
          @@ -1,2 +1,4 @@
           QA output created by 255
          +ERROR: error during balancing '/home/fdmanana/btrfs-tests/scratch_1': No such file or directory
          +There may be more info in syslog - try dmesg | tail
           Silence is golden
          ...
          (Run 'diff -u /home/fdmanana/git/hub/xfstests/tests/btrfs/255.out /home/fdmanana/git/hub/xfstests/results//btrfs/255.out.bad'  to see the entire diff)
      Ran: btrfs/255
      Failures: btrfs/255
      Failed 1 of 1 tests
    
    To fix this make the quota disable operation take the cleaner mutex, as
    relocation of a block group also takes this mutex. This is also what we
    do when deleting a subvolume/snapshot, we take the cleaner mutex in the
    cleaner kthread (at cleaner_kthread()) and then we call btrfs_del_root()
    at btrfs_drop_snapshot() while under the protection of the cleaner mutex.
    
    Fixes: bed92eae26cc ("Btrfs: qgroup implementation and prototypes")
    CC: stable@xxxxxxxxxxxxxxx # 5.4+
    Signed-off-by: Filipe Manana <fdmanana@xxxxxxxx>
    Signed-off-by: David Sterba <dsterba@xxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 360bf2522a871..2637d6b157ff9 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1232,12 +1232,23 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 	int ret = 0;
 
 	/*
-	 * We need to have subvol_sem write locked, to prevent races between
-	 * concurrent tasks trying to disable quotas, because we will unlock
-	 * and relock qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes.
+	 * We need to have subvol_sem write locked to prevent races with
+	 * snapshot creation.
 	 */
 	lockdep_assert_held_write(&fs_info->subvol_sem);
 
+	/*
+	 * Lock the cleaner mutex to prevent races with concurrent relocation,
+	 * because relocation may be building backrefs for blocks of the quota
+	 * root while we are deleting the root. This is like dropping fs roots
+	 * of deleted snapshots/subvolumes, we need the same protection.
+	 *
+	 * This also prevents races between concurrent tasks trying to disable
+	 * quotas, because we will unlock and relock qgroup_ioctl_lock across
+	 * BTRFS_FS_QUOTA_ENABLED changes.
+	 */
+	mutex_lock(&fs_info->cleaner_mutex);
+
 	mutex_lock(&fs_info->qgroup_ioctl_lock);
 	if (!fs_info->quota_root)
 		goto out;
@@ -1319,6 +1330,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 		btrfs_end_transaction(trans);
 	else if (trans)
 		ret = btrfs_end_transaction(trans);
+	mutex_unlock(&fs_info->cleaner_mutex);
 
 	return ret;
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux