Skip to content

Commit 7aa6d35

Browse files
fdmananakdave
authored andcommitted
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 <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 3d05cad commit 7aa6d35

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

fs/btrfs/qgroup.c

+9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/slab.h>
1212
#include <linux/workqueue.h>
1313
#include <linux/btrfs.h>
14+
#include <linux/sched/mm.h>
1415

1516
#include "ctree.h"
1617
#include "transaction.h"
@@ -1324,13 +1325,17 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
13241325
struct btrfs_qgroup *member;
13251326
struct btrfs_qgroup_list *list;
13261327
struct ulist *tmp;
1328+
unsigned int nofs_flag;
13271329
int ret = 0;
13281330

13291331
/* Check the level of src and dst first */
13301332
if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst))
13311333
return -EINVAL;
13321334

1335+
/* We hold a transaction handle open, must do a NOFS allocation. */
1336+
nofs_flag = memalloc_nofs_save();
13331337
tmp = ulist_alloc(GFP_KERNEL);
1338+
memalloc_nofs_restore(nofs_flag);
13341339
if (!tmp)
13351340
return -ENOMEM;
13361341

@@ -1387,10 +1392,14 @@ static int __del_qgroup_relation(struct btrfs_trans_handle *trans, u64 src,
13871392
struct btrfs_qgroup_list *list;
13881393
struct ulist *tmp;
13891394
bool found = false;
1395+
unsigned int nofs_flag;
13901396
int ret = 0;
13911397
int ret2;
13921398

1399+
/* We hold a transaction handle open, must do a NOFS allocation. */
1400+
nofs_flag = memalloc_nofs_save();
13931401
tmp = ulist_alloc(GFP_KERNEL);
1402+
memalloc_nofs_restore(nofs_flag);
13941403
if (!tmp)
13951404
return -ENOMEM;
13961405

0 commit comments

Comments
 (0)