]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled
authorQu Wenruo <wqu@suse.com>
Tue, 9 Oct 2018 06:36:45 +0000 (14:36 +0800)
committerJuerg Haefliger <juergh@canonical.com>
Wed, 24 Jul 2019 01:57:45 +0000 (19:57 -0600)
BugLink: https://bugs.launchpad.net/bugs/1836802
commit 3628b4ca64f24a4ec55055597d0cb1c814729f8b upstream.

Some qgroup trace events like btrfs_qgroup_release_data() and
btrfs_qgroup_free_delayed_ref() can still be triggered even if qgroup is
not enabled.

This is caused by the lack of qgroup status check before calling some
qgroup functions.  Thankfully the functions can handle quota disabled
case well and just do nothing for qgroup disabled case.

This patch will do earlier check before triggering related trace events.

And for enabled <-> disabled race case:

1) For enabled->disabled case
   Disable will wipe out all qgroups data including reservation and
   excl/rfer. Even if we leak some reservation or numbers, it will
   still be cleared, so nothing will go wrong.

2) For disabled -> enabled case
   Current btrfs_qgroup_release_data() will use extent_io tree to ensure
   we won't underflow reservation. And for delayed_ref we use
   head->qgroup_reserved to record the reserved space, so in that case
   head->qgroup_reserved should be 0 and we won't underflow.

CC: stable@vger.kernel.org # 4.14+
Reported-by: Chris Murphy <lists@colorremedies.com>
Link: https://lore.kernel.org/linux-btrfs/CAJCQCtQau7DtuUUeycCkZ36qjbKuxNzsgqJ7+sJ6W0dK_NLE3w@mail.gmail.com/
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
fs/btrfs/qgroup.c
fs/btrfs/qgroup.h

index 95c6e8e5e246c0ed05dcb3e68cdd0993e1a80923..dd5e41280502dbcef2d3698e64efcc7d99f3cde2 100644 (file)
@@ -2972,6 +2972,10 @@ static int __btrfs_qgroup_release_data(struct inode *inode,
        int trace_op = QGROUP_RELEASE;
        int ret;
 
+       if (!test_bit(BTRFS_FS_QUOTA_ENABLED,
+                     &BTRFS_I(inode)->root->fs_info->flags))
+               return 0;
+
        /* In release case, we shouldn't have @reserved */
        WARN_ON(!free && reserved);
        if (free && reserved)
index d9984e87cddfcba3066e6755d3d6a72c96bc14ac..83483ade3b19d726b0c4afdbe3bdd1d48b047f36 100644 (file)
@@ -232,6 +232,8 @@ void btrfs_qgroup_free_refroot(struct btrfs_fs_info *fs_info,
 static inline void btrfs_qgroup_free_delayed_ref(struct btrfs_fs_info *fs_info,
                                                 u64 ref_root, u64 num_bytes)
 {
+       if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
+               return;
        trace_btrfs_qgroup_free_delayed_ref(fs_info, ref_root, num_bytes);
        btrfs_qgroup_free_refroot(fs_info, ref_root, num_bytes);
 }