]> git.hungrycats.org Git - linux/commitdiff
btrfs: move ulist allocation out of transaction in quota enable
authorDavid Sterba <dsterba@suse.com>
Wed, 19 Dec 2018 18:47:37 +0000 (19:47 +0100)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Tue, 26 Mar 2019 18:43:44 +0000 (14:43 -0400)
The allocation happens with GFP_KERNEL after a transaction has been
started, this can potentially cause deadlock if reclaim tries to get the
memory by flushing filesystem data.

The fs_info::qgroup_ulist is not used during transaction start when
quotas are not enabled. The status bit BTRFS_FS_QUOTA_ENABLED is set
later in btrfs_quota_enable so it's safe to move it before the
transaction start.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
(cherry picked from commit 7503b83d80f0a3da5dead1293f5454206e7f9db6)
(cherry picked from commit 523fb64e6cbf2e9c2029ea37e9bf1e648120f646)

fs/btrfs/qgroup.c

index 9e419f6878c567aa795f8c4e605c0034ed73b287..14ae86d37b7a30f8305bb6d1e75803f169ce7a4c 100644 (file)
@@ -894,6 +894,12 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
        if (fs_info->quota_root)
                goto out;
 
+       fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
+       if (!fs_info->qgroup_ulist) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
        /*
         * 1 for quota root item
         * 1 for BTRFS_QGROUP_STATUS item
@@ -909,13 +915,6 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
                goto out;
        }
 
-       fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
-       if (!fs_info->qgroup_ulist) {
-               ret = -ENOMEM;
-               btrfs_abort_transaction(trans, ret);
-               goto out;
-       }
-
        /*
         * initially create the quota tree
         */