]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/quota.c
Update bcachefs sources to f38382c574 bcachefs: Improve key marking interface
[bcachefs-tools-debian] / libbcachefs / quota.c
1 #include "bcachefs.h"
2 #include "btree_update.h"
3 #include "inode.h"
4 #include "quota.h"
5 #include "super-io.h"
6
7 static const char *bch2_sb_validate_quota(struct bch_sb *sb,
8                                           struct bch_sb_field *f)
9 {
10         struct bch_sb_field_quota *q = field_to_type(f, quota);
11
12         if (vstruct_bytes(&q->field) != sizeof(*q))
13                 return "invalid field quota: wrong size";
14
15         return NULL;
16 }
17
18 const struct bch_sb_field_ops bch_sb_field_ops_quota = {
19         .validate       = bch2_sb_validate_quota,
20 };
21
22 const char *bch2_quota_invalid(const struct bch_fs *c, struct bkey_s_c k)
23 {
24         if (k.k->p.inode >= QTYP_NR)
25                 return "invalid quota type";
26
27         if (bkey_val_bytes(k.k) != sizeof(struct bch_quota))
28                 return "incorrect value size";
29
30         return NULL;
31 }
32
33 static const char * const bch2_quota_counters[] = {
34         "space",
35         "inodes",
36 };
37
38 void bch2_quota_to_text(struct printbuf *out, struct bch_fs *c,
39                         struct bkey_s_c k)
40 {
41         struct bkey_s_c_quota dq = bkey_s_c_to_quota(k);
42         unsigned i;
43
44         for (i = 0; i < Q_COUNTERS; i++)
45                 pr_buf(out, "%s hardlimit %llu softlimit %llu",
46                        bch2_quota_counters[i],
47                        le64_to_cpu(dq.v->c[i].hardlimit),
48                        le64_to_cpu(dq.v->c[i].softlimit));
49 }
50
51 #ifdef CONFIG_BCACHEFS_QUOTA
52
53 #include <linux/cred.h>
54 #include <linux/fs.h>
55 #include <linux/quota.h>
56
57 static inline unsigned __next_qtype(unsigned i, unsigned qtypes)
58 {
59         qtypes >>= i;
60         return qtypes ? i + __ffs(qtypes) : QTYP_NR;
61 }
62
63 #define for_each_set_qtype(_c, _i, _q, _qtypes)                         \
64         for (_i = 0;                                                    \
65              (_i = __next_qtype(_i, _qtypes),                           \
66               _q = &(_c)->quotas[_i],                                   \
67               _i < QTYP_NR);                                            \
68              _i++)
69
70 static bool ignore_hardlimit(struct bch_memquota_type *q)
71 {
72         if (capable(CAP_SYS_RESOURCE))
73                 return true;
74 #if 0
75         struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
76
77         return capable(CAP_SYS_RESOURCE) &&
78                (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
79                 !(info->dqi_flags & DQF_ROOT_SQUASH));
80 #endif
81         return false;
82 }
83
84 enum quota_msg {
85         SOFTWARN,       /* Softlimit reached */
86         SOFTLONGWARN,   /* Grace time expired */
87         HARDWARN,       /* Hardlimit reached */
88
89         HARDBELOW,      /* Usage got below inode hardlimit */
90         SOFTBELOW,      /* Usage got below inode softlimit */
91 };
92
93 static int quota_nl[][Q_COUNTERS] = {
94         [HARDWARN][Q_SPC]       = QUOTA_NL_BHARDWARN,
95         [SOFTLONGWARN][Q_SPC]   = QUOTA_NL_BSOFTLONGWARN,
96         [SOFTWARN][Q_SPC]       = QUOTA_NL_BSOFTWARN,
97         [HARDBELOW][Q_SPC]      = QUOTA_NL_BHARDBELOW,
98         [SOFTBELOW][Q_SPC]      = QUOTA_NL_BSOFTBELOW,
99
100         [HARDWARN][Q_INO]       = QUOTA_NL_IHARDWARN,
101         [SOFTLONGWARN][Q_INO]   = QUOTA_NL_ISOFTLONGWARN,
102         [SOFTWARN][Q_INO]       = QUOTA_NL_ISOFTWARN,
103         [HARDBELOW][Q_INO]      = QUOTA_NL_IHARDBELOW,
104         [SOFTBELOW][Q_INO]      = QUOTA_NL_ISOFTBELOW,
105 };
106
107 struct quota_msgs {
108         u8              nr;
109         struct {
110                 u8      qtype;
111                 u8      msg;
112         }               m[QTYP_NR * Q_COUNTERS];
113 };
114
115 static void prepare_msg(unsigned qtype,
116                         enum quota_counters counter,
117                         struct quota_msgs *msgs,
118                         enum quota_msg msg_type)
119 {
120         BUG_ON(msgs->nr >= ARRAY_SIZE(msgs->m));
121
122         msgs->m[msgs->nr].qtype = qtype;
123         msgs->m[msgs->nr].msg   = quota_nl[msg_type][counter];
124         msgs->nr++;
125 }
126
127 static void prepare_warning(struct memquota_counter *qc,
128                             unsigned qtype,
129                             enum quota_counters counter,
130                             struct quota_msgs *msgs,
131                             enum quota_msg msg_type)
132 {
133         if (qc->warning_issued & (1 << msg_type))
134                 return;
135
136         prepare_msg(qtype, counter, msgs, msg_type);
137 }
138
139 static void flush_warnings(struct bch_qid qid,
140                            struct super_block *sb,
141                            struct quota_msgs *msgs)
142 {
143         unsigned i;
144
145         for (i = 0; i < msgs->nr; i++)
146                 quota_send_warning(make_kqid(&init_user_ns, msgs->m[i].qtype, qid.q[i]),
147                                    sb->s_dev, msgs->m[i].msg);
148 }
149
150 static int bch2_quota_check_limit(struct bch_fs *c,
151                                   unsigned qtype,
152                                   struct bch_memquota *mq,
153                                   struct quota_msgs *msgs,
154                                   enum quota_counters counter,
155                                   s64 v,
156                                   enum quota_acct_mode mode)
157 {
158         struct bch_memquota_type *q = &c->quotas[qtype];
159         struct memquota_counter *qc = &mq->c[counter];
160         u64 n = qc->v + v;
161
162         BUG_ON((s64) n < 0);
163
164         if (mode == KEY_TYPE_QUOTA_NOCHECK)
165                 return 0;
166
167         if (v <= 0) {
168                 if (n < qc->hardlimit &&
169                     (qc->warning_issued & (1 << HARDWARN))) {
170                         qc->warning_issued &= ~(1 << HARDWARN);
171                         prepare_msg(qtype, counter, msgs, HARDBELOW);
172                 }
173
174                 if (n < qc->softlimit &&
175                     (qc->warning_issued & (1 << SOFTWARN))) {
176                         qc->warning_issued &= ~(1 << SOFTWARN);
177                         prepare_msg(qtype, counter, msgs, SOFTBELOW);
178                 }
179
180                 qc->warning_issued = 0;
181                 return 0;
182         }
183
184         if (qc->hardlimit &&
185             qc->hardlimit < n &&
186             !ignore_hardlimit(q)) {
187                 if (mode == KEY_TYPE_QUOTA_PREALLOC)
188                         return -EDQUOT;
189
190                 prepare_warning(qc, qtype, counter, msgs, HARDWARN);
191         }
192
193         if (qc->softlimit &&
194             qc->softlimit < n &&
195             qc->timer &&
196             ktime_get_real_seconds() >= qc->timer &&
197             !ignore_hardlimit(q)) {
198                 if (mode == KEY_TYPE_QUOTA_PREALLOC)
199                         return -EDQUOT;
200
201                 prepare_warning(qc, qtype, counter, msgs, SOFTLONGWARN);
202         }
203
204         if (qc->softlimit &&
205             qc->softlimit < n &&
206             qc->timer == 0) {
207                 if (mode == KEY_TYPE_QUOTA_PREALLOC)
208                         return -EDQUOT;
209
210                 prepare_warning(qc, qtype, counter, msgs, SOFTWARN);
211
212                 /* XXX is this the right one? */
213                 qc->timer = ktime_get_real_seconds() +
214                         q->limits[counter].warnlimit;
215         }
216
217         return 0;
218 }
219
220 int bch2_quota_acct(struct bch_fs *c, struct bch_qid qid,
221                     enum quota_counters counter, s64 v,
222                     enum quota_acct_mode mode)
223 {
224         unsigned qtypes = enabled_qtypes(c);
225         struct bch_memquota_type *q;
226         struct bch_memquota *mq[QTYP_NR];
227         struct quota_msgs msgs;
228         unsigned i;
229         int ret = 0;
230
231         memset(&msgs, 0, sizeof(msgs));
232
233         for_each_set_qtype(c, i, q, qtypes)
234                 mutex_lock_nested(&q->lock, i);
235
236         for_each_set_qtype(c, i, q, qtypes) {
237                 mq[i] = genradix_ptr_alloc(&q->table, qid.q[i], GFP_NOFS);
238                 if (!mq[i]) {
239                         ret = -ENOMEM;
240                         goto err;
241                 }
242
243                 ret = bch2_quota_check_limit(c, i, mq[i], &msgs, counter, v, mode);
244                 if (ret)
245                         goto err;
246         }
247
248         for_each_set_qtype(c, i, q, qtypes)
249                 mq[i]->c[counter].v += v;
250 err:
251         for_each_set_qtype(c, i, q, qtypes)
252                 mutex_unlock(&q->lock);
253
254         flush_warnings(qid, c->vfs_sb, &msgs);
255
256         return ret;
257 }
258
259 static void __bch2_quota_transfer(struct bch_memquota *src_q,
260                                   struct bch_memquota *dst_q,
261                                   enum quota_counters counter, s64 v)
262 {
263         BUG_ON(v > src_q->c[counter].v);
264         BUG_ON(v + dst_q->c[counter].v < v);
265
266         src_q->c[counter].v -= v;
267         dst_q->c[counter].v += v;
268 }
269
270 int bch2_quota_transfer(struct bch_fs *c, unsigned qtypes,
271                         struct bch_qid dst,
272                         struct bch_qid src, u64 space,
273                         enum quota_acct_mode mode)
274 {
275         struct bch_memquota_type *q;
276         struct bch_memquota *src_q[3], *dst_q[3];
277         struct quota_msgs msgs;
278         unsigned i;
279         int ret = 0;
280
281         qtypes &= enabled_qtypes(c);
282
283         memset(&msgs, 0, sizeof(msgs));
284
285         for_each_set_qtype(c, i, q, qtypes)
286                 mutex_lock_nested(&q->lock, i);
287
288         for_each_set_qtype(c, i, q, qtypes) {
289                 src_q[i] = genradix_ptr_alloc(&q->table, src.q[i], GFP_NOFS);
290                 dst_q[i] = genradix_ptr_alloc(&q->table, dst.q[i], GFP_NOFS);
291
292                 if (!src_q[i] || !dst_q[i]) {
293                         ret = -ENOMEM;
294                         goto err;
295                 }
296
297                 ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_SPC,
298                                              dst_q[i]->c[Q_SPC].v + space,
299                                              mode);
300                 if (ret)
301                         goto err;
302
303                 ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_INO,
304                                              dst_q[i]->c[Q_INO].v + 1,
305                                              mode);
306                 if (ret)
307                         goto err;
308         }
309
310         for_each_set_qtype(c, i, q, qtypes) {
311                 __bch2_quota_transfer(src_q[i], dst_q[i], Q_SPC, space);
312                 __bch2_quota_transfer(src_q[i], dst_q[i], Q_INO, 1);
313         }
314
315 err:
316         for_each_set_qtype(c, i, q, qtypes)
317                 mutex_unlock(&q->lock);
318
319         flush_warnings(dst, c->vfs_sb, &msgs);
320
321         return ret;
322 }
323
324 static int __bch2_quota_set(struct bch_fs *c, struct bkey_s_c k)
325 {
326         struct bkey_s_c_quota dq;
327         struct bch_memquota_type *q;
328         struct bch_memquota *mq;
329         unsigned i;
330
331         BUG_ON(k.k->p.inode >= QTYP_NR);
332
333         switch (k.k->type) {
334         case KEY_TYPE_quota:
335                 dq = bkey_s_c_to_quota(k);
336                 q = &c->quotas[k.k->p.inode];
337
338                 mutex_lock(&q->lock);
339                 mq = genradix_ptr_alloc(&q->table, k.k->p.offset, GFP_KERNEL);
340                 if (!mq) {
341                         mutex_unlock(&q->lock);
342                         return -ENOMEM;
343                 }
344
345                 for (i = 0; i < Q_COUNTERS; i++) {
346                         mq->c[i].hardlimit = le64_to_cpu(dq.v->c[i].hardlimit);
347                         mq->c[i].softlimit = le64_to_cpu(dq.v->c[i].softlimit);
348                 }
349
350                 mutex_unlock(&q->lock);
351         }
352
353         return 0;
354 }
355
356 static int bch2_quota_init_type(struct bch_fs *c, enum quota_types type)
357 {
358         struct btree_trans trans;
359         struct btree_iter *iter;
360         struct bkey_s_c k;
361         int ret = 0;
362
363         bch2_trans_init(&trans, c, 0, 0);
364
365         for_each_btree_key(&trans, iter, BTREE_ID_QUOTAS, POS(type, 0),
366                            BTREE_ITER_PREFETCH, k, ret) {
367                 if (k.k->p.inode != type)
368                         break;
369
370                 ret = __bch2_quota_set(c, k);
371                 if (ret)
372                         break;
373         }
374
375         return bch2_trans_exit(&trans) ?: ret;
376 }
377
378 void bch2_fs_quota_exit(struct bch_fs *c)
379 {
380         unsigned i;
381
382         for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
383                 genradix_free(&c->quotas[i].table);
384 }
385
386 void bch2_fs_quota_init(struct bch_fs *c)
387 {
388         unsigned i;
389
390         for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
391                 mutex_init(&c->quotas[i].lock);
392 }
393
394 static void bch2_sb_quota_read(struct bch_fs *c)
395 {
396         struct bch_sb_field_quota *sb_quota;
397         unsigned i, j;
398
399         sb_quota = bch2_sb_get_quota(c->disk_sb.sb);
400         if (!sb_quota)
401                 return;
402
403         for (i = 0; i < QTYP_NR; i++) {
404                 struct bch_memquota_type *q = &c->quotas[i];
405
406                 for (j = 0; j < Q_COUNTERS; j++) {
407                         q->limits[j].timelimit =
408                                 le32_to_cpu(sb_quota->q[i].c[j].timelimit);
409                         q->limits[j].warnlimit =
410                                 le32_to_cpu(sb_quota->q[i].c[j].warnlimit);
411                 }
412         }
413 }
414
415 int bch2_fs_quota_read(struct bch_fs *c)
416 {
417         unsigned i, qtypes = enabled_qtypes(c);
418         struct bch_memquota_type *q;
419         struct btree_trans trans;
420         struct btree_iter *iter;
421         struct bch_inode_unpacked u;
422         struct bkey_s_c k;
423         int ret;
424
425         mutex_lock(&c->sb_lock);
426         bch2_sb_quota_read(c);
427         mutex_unlock(&c->sb_lock);
428
429         for_each_set_qtype(c, i, q, qtypes) {
430                 ret = bch2_quota_init_type(c, i);
431                 if (ret)
432                         return ret;
433         }
434
435         bch2_trans_init(&trans, c, 0, 0);
436
437         for_each_btree_key(&trans, iter, BTREE_ID_INODES, POS_MIN,
438                            BTREE_ITER_PREFETCH, k, ret) {
439                 switch (k.k->type) {
440                 case KEY_TYPE_inode:
441                         ret = bch2_inode_unpack(bkey_s_c_to_inode(k), &u);
442                         if (ret)
443                                 return ret;
444
445                         bch2_quota_acct(c, bch_qid(&u), Q_SPC, u.bi_sectors,
446                                         KEY_TYPE_QUOTA_NOCHECK);
447                         bch2_quota_acct(c, bch_qid(&u), Q_INO, 1,
448                                         KEY_TYPE_QUOTA_NOCHECK);
449                 }
450         }
451         return bch2_trans_exit(&trans) ?: ret;
452 }
453
454 /* Enable/disable/delete quotas for an entire filesystem: */
455
456 static int bch2_quota_enable(struct super_block *sb, unsigned uflags)
457 {
458         struct bch_fs *c = sb->s_fs_info;
459
460         if (sb->s_flags & SB_RDONLY)
461                 return -EROFS;
462
463         /* Accounting must be enabled at mount time: */
464         if (uflags & (FS_QUOTA_UDQ_ACCT|FS_QUOTA_GDQ_ACCT|FS_QUOTA_PDQ_ACCT))
465                 return -EINVAL;
466
467         /* Can't enable enforcement without accounting: */
468         if ((uflags & FS_QUOTA_UDQ_ENFD) && !c->opts.usrquota)
469                 return -EINVAL;
470
471         if ((uflags & FS_QUOTA_GDQ_ENFD) && !c->opts.grpquota)
472                 return -EINVAL;
473
474         if (uflags & FS_QUOTA_PDQ_ENFD && !c->opts.prjquota)
475                 return -EINVAL;
476
477         mutex_lock(&c->sb_lock);
478         if (uflags & FS_QUOTA_UDQ_ENFD)
479                 SET_BCH_SB_USRQUOTA(c->disk_sb.sb, true);
480
481         if (uflags & FS_QUOTA_GDQ_ENFD)
482                 SET_BCH_SB_GRPQUOTA(c->disk_sb.sb, true);
483
484         if (uflags & FS_QUOTA_PDQ_ENFD)
485                 SET_BCH_SB_PRJQUOTA(c->disk_sb.sb, true);
486
487         bch2_write_super(c);
488         mutex_unlock(&c->sb_lock);
489
490         return 0;
491 }
492
493 static int bch2_quota_disable(struct super_block *sb, unsigned uflags)
494 {
495         struct bch_fs *c = sb->s_fs_info;
496
497         if (sb->s_flags & SB_RDONLY)
498                 return -EROFS;
499
500         mutex_lock(&c->sb_lock);
501         if (uflags & FS_QUOTA_UDQ_ENFD)
502                 SET_BCH_SB_USRQUOTA(c->disk_sb.sb, false);
503
504         if (uflags & FS_QUOTA_GDQ_ENFD)
505                 SET_BCH_SB_GRPQUOTA(c->disk_sb.sb, false);
506
507         if (uflags & FS_QUOTA_PDQ_ENFD)
508                 SET_BCH_SB_PRJQUOTA(c->disk_sb.sb, false);
509
510         bch2_write_super(c);
511         mutex_unlock(&c->sb_lock);
512
513         return 0;
514 }
515
516 static int bch2_quota_remove(struct super_block *sb, unsigned uflags)
517 {
518         struct bch_fs *c = sb->s_fs_info;
519         int ret;
520
521         if (sb->s_flags & SB_RDONLY)
522                 return -EROFS;
523
524         if (uflags & FS_USER_QUOTA) {
525                 if (c->opts.usrquota)
526                         return -EINVAL;
527
528                 ret = bch2_btree_delete_range(c, BTREE_ID_QUOTAS,
529                                               POS(QTYP_USR, 0),
530                                               POS(QTYP_USR + 1, 0),
531                                               NULL);
532                 if (ret)
533                         return ret;
534         }
535
536         if (uflags & FS_GROUP_QUOTA) {
537                 if (c->opts.grpquota)
538                         return -EINVAL;
539
540                 ret = bch2_btree_delete_range(c, BTREE_ID_QUOTAS,
541                                               POS(QTYP_GRP, 0),
542                                               POS(QTYP_GRP + 1, 0),
543                                               NULL);
544                 if (ret)
545                         return ret;
546         }
547
548         if (uflags & FS_PROJ_QUOTA) {
549                 if (c->opts.prjquota)
550                         return -EINVAL;
551
552                 ret = bch2_btree_delete_range(c, BTREE_ID_QUOTAS,
553                                               POS(QTYP_PRJ, 0),
554                                               POS(QTYP_PRJ + 1, 0),
555                                               NULL);
556                 if (ret)
557                         return ret;
558         }
559
560         return 0;
561 }
562
563 /*
564  * Return quota status information, such as enforcements, quota file inode
565  * numbers etc.
566  */
567 static int bch2_quota_get_state(struct super_block *sb, struct qc_state *state)
568 {
569         struct bch_fs *c = sb->s_fs_info;
570         unsigned qtypes = enabled_qtypes(c);
571         unsigned i;
572
573         memset(state, 0, sizeof(*state));
574
575         for (i = 0; i < QTYP_NR; i++) {
576                 state->s_state[i].flags |= QCI_SYSFILE;
577
578                 if (!(qtypes & (1 << i)))
579                         continue;
580
581                 state->s_state[i].flags |= QCI_ACCT_ENABLED;
582
583                 state->s_state[i].spc_timelimit = c->quotas[i].limits[Q_SPC].timelimit;
584                 state->s_state[i].spc_warnlimit = c->quotas[i].limits[Q_SPC].warnlimit;
585
586                 state->s_state[i].ino_timelimit = c->quotas[i].limits[Q_INO].timelimit;
587                 state->s_state[i].ino_warnlimit = c->quotas[i].limits[Q_INO].warnlimit;
588         }
589
590         return 0;
591 }
592
593 /*
594  * Adjust quota timers & warnings
595  */
596 static int bch2_quota_set_info(struct super_block *sb, int type,
597                                struct qc_info *info)
598 {
599         struct bch_fs *c = sb->s_fs_info;
600         struct bch_sb_field_quota *sb_quota;
601         struct bch_memquota_type *q;
602
603         if (sb->s_flags & SB_RDONLY)
604                 return -EROFS;
605
606         if (type >= QTYP_NR)
607                 return -EINVAL;
608
609         if (!((1 << type) & enabled_qtypes(c)))
610                 return -ESRCH;
611
612         if (info->i_fieldmask &
613             ~(QC_SPC_TIMER|QC_INO_TIMER|QC_SPC_WARNS|QC_INO_WARNS))
614                 return -EINVAL;
615
616         q = &c->quotas[type];
617
618         mutex_lock(&c->sb_lock);
619         sb_quota = bch2_sb_get_quota(c->disk_sb.sb);
620         if (!sb_quota) {
621                 sb_quota = bch2_sb_resize_quota(&c->disk_sb,
622                                         sizeof(*sb_quota) / sizeof(u64));
623                 if (!sb_quota)
624                         return -ENOSPC;
625         }
626
627         if (info->i_fieldmask & QC_SPC_TIMER)
628                 sb_quota->q[type].c[Q_SPC].timelimit =
629                         cpu_to_le32(info->i_spc_timelimit);
630
631         if (info->i_fieldmask & QC_SPC_WARNS)
632                 sb_quota->q[type].c[Q_SPC].warnlimit =
633                         cpu_to_le32(info->i_spc_warnlimit);
634
635         if (info->i_fieldmask & QC_INO_TIMER)
636                 sb_quota->q[type].c[Q_INO].timelimit =
637                         cpu_to_le32(info->i_ino_timelimit);
638
639         if (info->i_fieldmask & QC_INO_WARNS)
640                 sb_quota->q[type].c[Q_INO].warnlimit =
641                         cpu_to_le32(info->i_ino_warnlimit);
642
643         bch2_sb_quota_read(c);
644
645         bch2_write_super(c);
646         mutex_unlock(&c->sb_lock);
647
648         return 0;
649 }
650
651 /* Get/set individual quotas: */
652
653 static void __bch2_quota_get(struct qc_dqblk *dst, struct bch_memquota *src)
654 {
655         dst->d_space            = src->c[Q_SPC].v << 9;
656         dst->d_spc_hardlimit    = src->c[Q_SPC].hardlimit << 9;
657         dst->d_spc_softlimit    = src->c[Q_SPC].softlimit << 9;
658         dst->d_spc_timer        = src->c[Q_SPC].timer;
659         dst->d_spc_warns        = src->c[Q_SPC].warns;
660
661         dst->d_ino_count        = src->c[Q_INO].v;
662         dst->d_ino_hardlimit    = src->c[Q_INO].hardlimit;
663         dst->d_ino_softlimit    = src->c[Q_INO].softlimit;
664         dst->d_ino_timer        = src->c[Q_INO].timer;
665         dst->d_ino_warns        = src->c[Q_INO].warns;
666 }
667
668 static int bch2_get_quota(struct super_block *sb, struct kqid kqid,
669                           struct qc_dqblk *qdq)
670 {
671         struct bch_fs *c                = sb->s_fs_info;
672         struct bch_memquota_type *q     = &c->quotas[kqid.type];
673         qid_t qid                       = from_kqid(&init_user_ns, kqid);
674         struct bch_memquota *mq;
675
676         memset(qdq, 0, sizeof(*qdq));
677
678         mutex_lock(&q->lock);
679         mq = genradix_ptr(&q->table, qid);
680         if (mq)
681                 __bch2_quota_get(qdq, mq);
682         mutex_unlock(&q->lock);
683
684         return 0;
685 }
686
687 static int bch2_get_next_quota(struct super_block *sb, struct kqid *kqid,
688                                struct qc_dqblk *qdq)
689 {
690         struct bch_fs *c                = sb->s_fs_info;
691         struct bch_memquota_type *q     = &c->quotas[kqid->type];
692         qid_t qid                       = from_kqid(&init_user_ns, *kqid);
693         struct genradix_iter iter;
694         struct bch_memquota *mq;
695         int ret = 0;
696
697         mutex_lock(&q->lock);
698
699         genradix_for_each_from(&q->table, iter, mq, qid)
700                 if (memcmp(mq, page_address(ZERO_PAGE(0)), sizeof(*mq))) {
701                         __bch2_quota_get(qdq, mq);
702                         *kqid = make_kqid(current_user_ns(), kqid->type, iter.pos);
703                         goto found;
704                 }
705
706         ret = -ENOENT;
707 found:
708         mutex_unlock(&q->lock);
709         return ret;
710 }
711
712 static int bch2_set_quota(struct super_block *sb, struct kqid qid,
713                           struct qc_dqblk *qdq)
714 {
715         struct bch_fs *c = sb->s_fs_info;
716         struct btree_trans trans;
717         struct btree_iter *iter;
718         struct bkey_s_c k;
719         struct bkey_i_quota new_quota;
720         int ret;
721
722         if (sb->s_flags & SB_RDONLY)
723                 return -EROFS;
724
725         bkey_quota_init(&new_quota.k_i);
726         new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
727
728         bch2_trans_init(&trans, c, 0, 0);
729
730         iter = bch2_trans_get_iter(&trans, BTREE_ID_QUOTAS, new_quota.k.p,
731                                    BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
732         k = bch2_btree_iter_peek_slot(iter);
733
734         ret = bkey_err(k);
735         if (unlikely(ret))
736                 return ret;
737
738         switch (k.k->type) {
739         case KEY_TYPE_quota:
740                 new_quota.v = *bkey_s_c_to_quota(k).v;
741                 break;
742         }
743
744         if (qdq->d_fieldmask & QC_SPC_SOFT)
745                 new_quota.v.c[Q_SPC].softlimit = cpu_to_le64(qdq->d_spc_softlimit >> 9);
746         if (qdq->d_fieldmask & QC_SPC_HARD)
747                 new_quota.v.c[Q_SPC].hardlimit = cpu_to_le64(qdq->d_spc_hardlimit >> 9);
748
749         if (qdq->d_fieldmask & QC_INO_SOFT)
750                 new_quota.v.c[Q_INO].softlimit = cpu_to_le64(qdq->d_ino_softlimit);
751         if (qdq->d_fieldmask & QC_INO_HARD)
752                 new_quota.v.c[Q_INO].hardlimit = cpu_to_le64(qdq->d_ino_hardlimit);
753
754         bch2_trans_update(&trans, BTREE_INSERT_ENTRY(iter, &new_quota.k_i));
755
756         ret = bch2_trans_commit(&trans, NULL, NULL, 0);
757
758         bch2_trans_exit(&trans);
759
760         if (ret)
761                 return ret;
762
763         ret = __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i));
764
765         return ret;
766 }
767
768 const struct quotactl_ops bch2_quotactl_operations = {
769         .quota_enable           = bch2_quota_enable,
770         .quota_disable          = bch2_quota_disable,
771         .rm_xquota              = bch2_quota_remove,
772
773         .get_state              = bch2_quota_get_state,
774         .set_info               = bch2_quota_set_info,
775
776         .get_dqblk              = bch2_get_quota,
777         .get_nextdqblk          = bch2_get_next_quota,
778         .set_dqblk              = bch2_set_quota,
779 };
780
781 #endif /* CONFIG_BCACHEFS_QUOTA */