lkml.org 
[lkml]   [2018]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 326/361] btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Qu Wenruo <wqu@suse.com>

    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>

    ---
    fs/btrfs/qgroup.c | 4 ++++
    fs/btrfs/qgroup.h | 2 ++
    2 files changed, 6 insertions(+)

    --- a/fs/btrfs/qgroup.c
    +++ b/fs/btrfs/qgroup.c
    @@ -3106,6 +3106,10 @@ static int __btrfs_qgroup_release_data(s
    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)
    --- a/fs/btrfs/qgroup.h
    +++ b/fs/btrfs/qgroup.h
    @@ -249,6 +249,8 @@ void btrfs_qgroup_free_refroot(struct bt
    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,
    BTRFS_QGROUP_RSV_DATA);

    \
     
     \ /
      Last update: 2018-11-12 00:55    [W:3.131 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site