diff options
author | David Sterba <dsterba@suse.com> | 2018-12-19 19:47:37 +0100 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2019-02-27 14:10:25 +0100 |
commit | 7503b83d80f0a3da5dead1293f5454206e7f9db6 (patch) | |
tree | eab3153af1def62923574438f992fc2cd7458af5 /fs/btrfs/qgroup.c | |
parent | aea6f028d01d629eda2e958ccd1133e805cda159 (diff) | |
download | lwn-7503b83d80f0a3da5dead1293f5454206e7f9db6.tar.gz lwn-7503b83d80f0a3da5dead1293f5454206e7f9db6.zip |
btrfs: move ulist allocation out of transaction in quota enable
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>
Diffstat (limited to 'fs/btrfs/qgroup.c')
-rw-r--r-- | fs/btrfs/qgroup.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index c1cd5558a646..eb680b715dd6 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -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 */ |