summaryrefslogtreecommitdiff
path: root/fs/bcachefs/quota.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2022-10-15 03:52:28 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:44 -0400
commitbd954215cad1dbe4304736e6968d8a0c10d1e048 (patch)
treeafd3cd1ec7a14b2f1b003e74d817258d3d3eac5f /fs/bcachefs/quota.c
parentd7e4e51370ef62776ea4af22f83047640425efda (diff)
bcachefs: Quota fixes
- We now correctly allow soft limits to be exceeded, instead of always returning -EDQUOT - Disk quota grate times/warnings can now be set, not just the systemwide defaults Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/quota.c')
-rw-r--r--fs/bcachefs/quota.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/fs/bcachefs/quota.c b/fs/bcachefs/quota.c
index ad7130a14691..db8172736527 100644
--- a/fs/bcachefs/quota.c
+++ b/fs/bcachefs/quota.c
@@ -332,34 +332,20 @@ static int bch2_quota_check_limit(struct bch_fs *c,
if (qc->hardlimit &&
qc->hardlimit < n &&
!ignore_hardlimit(q)) {
- if (mode == KEY_TYPE_QUOTA_PREALLOC)
- return -EDQUOT;
-
prepare_warning(qc, qtype, counter, msgs, HARDWARN);
+ return -EDQUOT;
}
if (qc->softlimit &&
- qc->softlimit < n &&
- qc->timer &&
- ktime_get_real_seconds() >= qc->timer &&
- !ignore_hardlimit(q)) {
- if (mode == KEY_TYPE_QUOTA_PREALLOC)
- return -EDQUOT;
-
- prepare_warning(qc, qtype, counter, msgs, SOFTLONGWARN);
- }
-
- if (qc->softlimit &&
- qc->softlimit < n &&
- qc->timer == 0) {
- if (mode == KEY_TYPE_QUOTA_PREALLOC)
+ qc->softlimit < n) {
+ if (qc->timer == 0) {
+ qc->timer = ktime_get_real_seconds() + q->limits[counter].timelimit;
+ prepare_warning(qc, qtype, counter, msgs, SOFTWARN);
+ } else if (ktime_get_real_seconds() >= qc->timer &&
+ !ignore_hardlimit(q)) {
+ prepare_warning(qc, qtype, counter, msgs, SOFTLONGWARN);
return -EDQUOT;
-
- prepare_warning(qc, qtype, counter, msgs, SOFTWARN);
-
- /* XXX is this the right one? */
- qc->timer = ktime_get_real_seconds() +
- q->limits[counter].warnlimit;
+ }
}
return 0;
@@ -469,7 +455,8 @@ err:
return ret;
}
-static int __bch2_quota_set(struct bch_fs *c, struct bkey_s_c k)
+static int __bch2_quota_set(struct bch_fs *c, struct bkey_s_c k,
+ struct qc_dqblk *qdq)
{
struct bkey_s_c_quota dq;
struct bch_memquota_type *q;
@@ -498,6 +485,15 @@ static int __bch2_quota_set(struct bch_fs *c, struct bkey_s_c k)
mq->c[i].softlimit = le64_to_cpu(dq.v->c[i].softlimit);
}
+ if (qdq && qdq->d_fieldmask & QC_SPC_TIMER)
+ mq->c[Q_SPC].timer = cpu_to_le64(qdq->d_spc_timer);
+ if (qdq && qdq->d_fieldmask & QC_SPC_WARNS)
+ mq->c[Q_SPC].warns = cpu_to_le64(qdq->d_spc_warns);
+ if (qdq && qdq->d_fieldmask & QC_INO_TIMER)
+ mq->c[Q_INO].timer = cpu_to_le64(qdq->d_ino_timer);
+ if (qdq && qdq->d_fieldmask & QC_INO_WARNS)
+ mq->c[Q_INO].warns = cpu_to_le64(qdq->d_ino_warns);
+
mutex_unlock(&q->lock);
}
@@ -618,7 +614,7 @@ int bch2_fs_quota_read(struct bch_fs *c)
ret = for_each_btree_key2(&trans, iter, BTREE_ID_quotas,
POS_MIN, BTREE_ITER_PREFETCH, k,
- __bch2_quota_set(c, k)) ?:
+ __bch2_quota_set(c, k, NULL)) ?:
for_each_btree_key2(&trans, iter, BTREE_ID_inodes,
POS_MIN, BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k,
bch2_fs_quota_read_inode(&trans, &iter, k));
@@ -961,7 +957,7 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
ret = bch2_trans_do(c, NULL, NULL, 0,
bch2_set_quota_trans(&trans, &new_quota, qdq)) ?:
- __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i));
+ __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i), qdq);
return ret;
}