On Wed, Feb 27, 2019 at 12:12 PM David Sterba <[email protected]> wrote: > > 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. > > Signed-off-by: David Sterba <[email protected]>
Reviewed-by: Filipe Manana <[email protected]> Looks good now. > > v2: > - use qgroup_ulist directly, drop the temporary variable > - update changelog > --- > fs/btrfs/qgroup.c | 13 ++++++------- > 1 file 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 > */ > -- > 2.20.1 > -- Filipe David Manana, “Whether you think you can, or you think you can't — you're right.”
