aboutsummaryrefslogtreecommitdiff
path: root/fs/bcachefs/quota.c
diff options
context:
space:
mode:
authorGravatar Kent Overstreet <kent.overstreet@linux.dev> 2022-11-13 22:35:55 -0500
committerGravatar Kent Overstreet <kent.overstreet@linux.dev> 2023-10-22 17:09:46 -0400
commit84fea8e5b3abc9147a20211e608ba8844c479998 (patch)
tree314ef36a893d7c1799a982d1dd92cae5b58bcde9 /fs/bcachefs/quota.c
parentbcachefs: Fix a use after free (diff)
downloadlinux-84fea8e5b3abc9147a20211e608ba8844c479998.tar.gz
linux-84fea8e5b3abc9147a20211e608ba8844c479998.tar.bz2
linux-84fea8e5b3abc9147a20211e608ba8844c479998.zip
bcachefs: Quota: Don't allocate memory under lock
The genradix code can handle multiple threads trying to allocate at the same time - we don't need the genradix_ptr_alloc() call to happen under a lock. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/quota.c')
-rw-r--r--fs/bcachefs/quota.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/fs/bcachefs/quota.c b/fs/bcachefs/quota.c
index db8172736527..7f74c026e9da 100644
--- a/fs/bcachefs/quota.c
+++ b/fs/bcachefs/quota.c
@@ -364,16 +364,16 @@ int bch2_quota_acct(struct bch_fs *c, struct bch_qid qid,
memset(&msgs, 0, sizeof(msgs));
+ for_each_set_qtype(c, i, q, qtypes) {
+ mq[i] = genradix_ptr_alloc(&q->table, qid.q[i], GFP_KERNEL);
+ if (!mq[i])
+ return -ENOMEM;
+ }
+
for_each_set_qtype(c, i, q, qtypes)
mutex_lock_nested(&q->lock, i);
for_each_set_qtype(c, i, q, qtypes) {
- mq[i] = genradix_ptr_alloc(&q->table, qid.q[i], GFP_NOFS);
- if (!mq[i]) {
- ret = -ENOMEM;
- goto err;
- }
-
ret = bch2_quota_check_limit(c, i, mq[i], &msgs, counter, v, mode);
if (ret)
goto err;
@@ -416,18 +416,17 @@ int bch2_quota_transfer(struct bch_fs *c, unsigned qtypes,
memset(&msgs, 0, sizeof(msgs));
+ for_each_set_qtype(c, i, q, qtypes) {
+ src_q[i] = genradix_ptr_alloc(&q->table, src.q[i], GFP_KERNEL);
+ dst_q[i] = genradix_ptr_alloc(&q->table, dst.q[i], GFP_KERNEL);
+ if (!src_q[i] || !dst_q[i])
+ return -ENOMEM;
+ }
+
for_each_set_qtype(c, i, q, qtypes)
mutex_lock_nested(&q->lock, i);
for_each_set_qtype(c, i, q, qtypes) {
- src_q[i] = genradix_ptr_alloc(&q->table, src.q[i], GFP_NOFS);
- dst_q[i] = genradix_ptr_alloc(&q->table, dst.q[i], GFP_NOFS);
-
- if (!src_q[i] || !dst_q[i]) {
- ret = -ENOMEM;
- goto err;
- }
-
ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_SPC,
dst_q[i]->c[Q_SPC].v + space,
mode);