btrfs: do nofs allocations when adding and removing qgroup relations
When adding or removing a qgroup relation we are doing a GFP_KERNEL allocation which is not safe because we are holding a transaction handle open and that can make us deadlock if the allocator needs to recurse into the filesystem. So just surround those calls with a nofs context. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
3d05cad3c3
commit
7aa6d35984
|
@ -11,6 +11,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/btrfs.h>
|
||||
#include <linux/sched/mm.h>
|
||||
|
||||
#include "ctree.h"
|
||||
#include "transaction.h"
|
||||
|
@ -1324,13 +1325,17 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
|
|||
struct btrfs_qgroup *member;
|
||||
struct btrfs_qgroup_list *list;
|
||||
struct ulist *tmp;
|
||||
unsigned int nofs_flag;
|
||||
int ret = 0;
|
||||
|
||||
/* Check the level of src and dst first */
|
||||
if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst))
|
||||
return -EINVAL;
|
||||
|
||||
/* We hold a transaction handle open, must do a NOFS allocation. */
|
||||
nofs_flag = memalloc_nofs_save();
|
||||
tmp = ulist_alloc(GFP_KERNEL);
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1387,10 +1392,14 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
|
|||
struct btrfs_qgroup_list *list;
|
||||
struct ulist *tmp;
|
||||
bool found = false;
|
||||
unsigned int nofs_flag;
|
||||
int ret = 0;
|
||||
int ret2;
|
||||
|
||||
/* We hold a transaction handle open, must do a NOFS allocation. */
|
||||
nofs_flag = memalloc_nofs_save();
|
||||
tmp = ulist_alloc(GFP_KERNEL);
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
Loading…
Reference in New Issue