]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/quota.c
Update bcachefs sources to e99d29e402 bcachefs: zstd support, compression refactoring
[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_quota_invalid(const struct bch_fs *c, struct bkey_s_c k)
8 {
9         struct bkey_s_c_quota dq;
10
11         if (k.k->p.inode >= QTYP_NR)
12                 return "invalid quota type";
13
14         switch (k.k->type) {
15         case BCH_QUOTA: {
16                 dq = bkey_s_c_to_quota(k);
17
18                 if (bkey_val_bytes(k.k) != sizeof(struct bch_quota))
19                         return "incorrect value size";
20
21                 return NULL;
22         }
23         default:
24                 return "invalid type";
25         }
26 }
27
28 static const char * const bch2_quota_counters[] = {
29         "space",
30         "inodes",
31 };
32
33 static void bch2_quota_to_text(struct bch_fs *c, char *buf,
34                                size_t size, struct bkey_s_c k)
35 {
36         char *out = buf, *end= buf + size;
37         struct bkey_s_c_quota dq;
38         unsigned i;
39
40         switch (k.k->type) {
41         case BCH_QUOTA:
42                 dq = bkey_s_c_to_quota(k);
43
44                 for (i = 0; i < Q_COUNTERS; i++)
45                         out += scnprintf(out, end - 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                 break;
50         }
51 }
52
53 const struct bkey_ops bch2_bkey_quota_ops = {
54         .key_invalid    = bch2_quota_invalid,
55         .val_to_text    = bch2_quota_to_text,
56 };
57
58 #ifdef CONFIG_BCACHEFS_QUOTA
59
60 #include <linux/cred.h>
61 #include <linux/fs.h>
62 #include <linux/quota.h>
63
64 static inline unsigned __next_qtype(unsigned i, unsigned qtypes)
65 {
66         qtypes >>= i;
67         return qtypes ? i + __ffs(qtypes) : QTYP_NR;
68 }
69
70 #define for_each_set_qtype(_c, _i, _q, _qtypes)                         \
71         for (_i = 0;                                                    \
72              (_i = __next_qtype(_i, _qtypes),                           \
73               _q = &(_c)->quotas[_i],                                   \
74               _i < QTYP_NR);                                            \
75              _i++)
76
77 static bool ignore_hardlimit(struct bch_memquota_type *q)
78 {
79         if (capable(CAP_SYS_RESOURCE))
80                 return true;
81 #if 0
82         struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
83
84         return capable(CAP_SYS_RESOURCE) &&
85                (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
86                 !(info->dqi_flags & DQF_ROOT_SQUASH));
87 #endif
88         return false;
89 }
90
91 enum quota_msg {
92         SOFTWARN,       /* Softlimit reached */
93         SOFTLONGWARN,   /* Grace time expired */
94         HARDWARN,       /* Hardlimit reached */
95
96         HARDBELOW,      /* Usage got below inode hardlimit */
97         SOFTBELOW,      /* Usage got below inode softlimit */
98 };
99
100 static int quota_nl[][Q_COUNTERS] = {
101         [HARDWARN][Q_SPC]       = QUOTA_NL_BHARDWARN,
102         [SOFTLONGWARN][Q_SPC]   = QUOTA_NL_BSOFTLONGWARN,
103         [SOFTWARN][Q_SPC]       = QUOTA_NL_BSOFTWARN,
104         [HARDBELOW][Q_SPC]      = QUOTA_NL_BHARDBELOW,
105         [SOFTBELOW][Q_SPC]      = QUOTA_NL_BSOFTBELOW,
106
107         [HARDWARN][Q_INO]       = QUOTA_NL_IHARDWARN,
108         [SOFTLONGWARN][Q_INO]   = QUOTA_NL_ISOFTLONGWARN,
109         [SOFTWARN][Q_INO]       = QUOTA_NL_ISOFTWARN,
110         [HARDBELOW][Q_INO]      = QUOTA_NL_IHARDBELOW,
111         [SOFTBELOW][Q_INO]      = QUOTA_NL_ISOFTBELOW,
112 };
113
114 struct quota_msgs {
115         u8              nr;
116         struct {
117                 u8      qtype;
118                 u8      msg;
119         }               m[QTYP_NR * Q_COUNTERS];
120 };
121
122 static void prepare_msg(unsigned qtype,
123                         enum quota_counters counter,
124                         struct quota_msgs *msgs,
125                         enum quota_msg msg_type)
126 {
127         BUG_ON(msgs->nr >= ARRAY_SIZE(msgs->m));
128
129         msgs->m[msgs->nr].qtype = qtype;
130         msgs->m[msgs->nr].msg   = quota_nl[msg_type][counter];
131         msgs->nr++;
132 }
133
134 static void prepare_warning(struct memquota_counter *qc,
135                             unsigned qtype,
136                             enum quota_counters counter,
137                             struct quota_msgs *msgs,
138                             enum quota_msg msg_type)
139 {
140         if (qc->warning_issued & (1 << msg_type))
141                 return;
142
143         prepare_msg(qtype, counter, msgs, msg_type);
144 }
145
146 static void flush_warnings(struct bch_qid qid,
147                            struct super_block *sb,
148                            struct quota_msgs *msgs)
149 {
150         unsigned i;
151
152         for (i = 0; i < msgs->nr; i++)
153                 quota_send_warning(make_kqid(&init_user_ns, msgs->m[i].qtype, qid.q[i]),
154                                    sb->s_dev, msgs->m[i].msg);
155 }
156
157 static int bch2_quota_check_limit(struct bch_fs *c,
158                                   unsigned qtype,
159                                   struct bch_memquota *mq,
160                                   struct quota_msgs *msgs,
161                                   enum quota_counters counter,
162                                   s64 v,
163                                   enum quota_acct_mode mode)
164 {
165         struct bch_memquota_type *q = &c->quotas[qtype];
166         struct memquota_counter *qc = &mq->c[counter];
167         u64 n = qc->v + v;
168
169         BUG_ON((s64) n < 0);
170
171         if (mode == BCH_QUOTA_NOCHECK)
172                 return 0;
173
174         if (v <= 0) {
175                 if (n < qc->hardlimit &&
176                     (qc->warning_issued & (1 << HARDWARN))) {
177                         qc->warning_issued &= ~(1 << HARDWARN);
178                         prepare_msg(qtype, counter, msgs, HARDBELOW);
179                 }
180
181                 if (n < qc->softlimit &&
182                     (qc->warning_issued & (1 << SOFTWARN))) {
183                         qc->warning_issued &= ~(1 << SOFTWARN);
184                         prepare_msg(qtype, counter, msgs, SOFTBELOW);
185                 }
186
187                 qc->warning_issued = 0;
188                 return 0;
189         }
190
191         if (qc->hardlimit &&
192             qc->hardlimit < n &&
193             !ignore_hardlimit(q)) {
194                 if (mode == BCH_QUOTA_PREALLOC)
195                         return -EDQUOT;
196
197                 prepare_warning(qc, qtype, counter, msgs, HARDWARN);
198         }
199
200         if (qc->softlimit &&
201             qc->softlimit < n &&
202             qc->timer &&
203             ktime_get_real_seconds() >= qc->timer &&
204             !ignore_hardlimit(q)) {
205                 if (mode == BCH_QUOTA_PREALLOC)
206                         return -EDQUOT;
207
208                 prepare_warning(qc, qtype, counter, msgs, SOFTLONGWARN);
209         }
210
211         if (qc->softlimit &&
212             qc->softlimit < n &&
213             qc->timer == 0) {
214                 if (mode == BCH_QUOTA_PREALLOC)
215                         return -EDQUOT;
216
217                 prepare_warning(qc, qtype, counter, msgs, SOFTWARN);
218
219                 /* XXX is this the right one? */
220                 qc->timer = ktime_get_real_seconds() +
221                         q->limits[counter].warnlimit;
222         }
223
224         return 0;
225 }
226
227 int bch2_quota_acct(struct bch_fs *c, struct bch_qid qid,
228                     enum quota_counters counter, s64 v,
229                     enum quota_acct_mode mode)
230 {
231         unsigned qtypes = enabled_qtypes(c);
232         struct bch_memquota_type *q;
233         struct bch_memquota *mq[QTYP_NR];
234         struct quota_msgs msgs;
235         unsigned i;
236         int ret = 0;
237
238         memset(&msgs, 0, sizeof(msgs));
239
240         for_each_set_qtype(c, i, q, qtypes)
241                 mutex_lock_nested(&q->lock, i);
242
243         for_each_set_qtype(c, i, q, qtypes) {
244                 mq[i] = genradix_ptr_alloc(&q->table, qid.q[i], GFP_NOFS);
245                 if (!mq[i]) {
246                         ret = -ENOMEM;
247                         goto err;
248                 }
249
250                 ret = bch2_quota_check_limit(c, i, mq[i], &msgs, counter, v, mode);
251                 if (ret)
252                         goto err;
253         }
254
255         for_each_set_qtype(c, i, q, qtypes)
256                 mq[i]->c[counter].v += v;
257 err:
258         for_each_set_qtype(c, i, q, qtypes)
259                 mutex_unlock(&q->lock);
260
261         flush_warnings(qid, c->vfs_sb, &msgs);
262
263         return ret;
264 }
265
266 static void __bch2_quota_transfer(struct bch_memquota *src_q,
267                                   struct bch_memquota *dst_q,
268                                   enum quota_counters counter, s64 v)
269 {
270         BUG_ON(v > src_q->c[counter].v);
271         BUG_ON(v + dst_q->c[counter].v < v);
272
273         src_q->c[counter].v -= v;
274         dst_q->c[counter].v += v;
275 }
276
277 int bch2_quota_transfer(struct bch_fs *c, unsigned qtypes,
278                         struct bch_qid dst,
279                         struct bch_qid src, u64 space)
280 {
281         struct bch_memquota_type *q;
282         struct bch_memquota *src_q[3], *dst_q[3];
283         struct quota_msgs msgs;
284         unsigned i;
285         int ret = 0;
286
287         qtypes &= enabled_qtypes(c);
288
289         memset(&msgs, 0, sizeof(msgs));
290
291         for_each_set_qtype(c, i, q, qtypes)
292                 mutex_lock_nested(&q->lock, i);
293
294         for_each_set_qtype(c, i, q, qtypes) {
295                 src_q[i] = genradix_ptr_alloc(&q->table, src.q[i], GFP_NOFS);
296                 dst_q[i] = genradix_ptr_alloc(&q->table, dst.q[i], GFP_NOFS);
297
298                 if (!src_q[i] || !dst_q[i]) {
299                         ret = -ENOMEM;
300                         goto err;
301                 }
302
303                 ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_SPC,
304                                              dst_q[i]->c[Q_SPC].v + space,
305                                              BCH_QUOTA_PREALLOC);
306                 if (ret)
307                         goto err;
308
309                 ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_INO,
310                                              dst_q[i]->c[Q_INO].v + 1,
311                                              BCH_QUOTA_PREALLOC);
312                 if (ret)
313                         goto err;
314         }
315
316         for_each_set_qtype(c, i, q, qtypes) {
317                 __bch2_quota_transfer(src_q[i], dst_q[i], Q_SPC, space);
318                 __bch2_quota_transfer(src_q[i], dst_q[i], Q_INO, 1);
319         }
320
321 err:
322         for_each_set_qtype(c, i, q, qtypes)
323                 mutex_unlock(&q->lock);
324
325         flush_warnings(dst, c->vfs_sb, &msgs);
326
327         return ret;
328 }
329
330 static int __bch2_quota_set(struct bch_fs *c, struct bkey_s_c k)
331 {
332         struct bkey_s_c_quota dq;
333         struct bch_memquota_type *q;
334         struct bch_memquota *mq;
335         unsigned i;
336
337         BUG_ON(k.k->p.inode >= QTYP_NR);
338
339         switch (k.k->type) {
340         case BCH_QUOTA:
341                 dq = bkey_s_c_to_quota(k);
342                 q = &c->quotas[k.k->p.inode];
343
344                 mutex_lock(&q->lock);
345                 mq = genradix_ptr_alloc(&q->table, k.k->p.offset, GFP_KERNEL);
346                 if (!mq) {
347                         mutex_unlock(&q->lock);
348                         return -ENOMEM;
349                 }
350
351                 for (i = 0; i < Q_COUNTERS; i++) {
352                         mq->c[i].hardlimit = le64_to_cpu(dq.v->c[i].hardlimit);
353                         mq->c[i].softlimit = le64_to_cpu(dq.v->c[i].softlimit);
354                 }
355
356                 mutex_unlock(&q->lock);
357         }
358
359         return 0;
360 }
361
362 static int bch2_quota_init_type(struct bch_fs *c, enum quota_types type)
363 {
364         struct btree_iter iter;
365         struct bkey_s_c k;
366         int ret = 0;
367
368         for_each_btree_key(&iter, c, BTREE_ID_QUOTAS, POS(type, 0),
369                            BTREE_ITER_PREFETCH, k) {
370                 if (k.k->p.inode != type)
371                         break;
372
373                 ret = __bch2_quota_set(c, k);
374                 if (ret)
375                         break;
376         }
377
378         return bch2_btree_iter_unlock(&iter) ?: ret;
379 }
380
381 void bch2_fs_quota_exit(struct bch_fs *c)
382 {
383         unsigned i;
384
385         for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
386                 genradix_free(&c->quotas[i].table);
387 }
388
389 void bch2_fs_quota_init(struct bch_fs *c)
390 {
391         unsigned i;
392
393         for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
394                 mutex_init(&c->quotas[i].lock);
395 }
396
397 static void bch2_sb_quota_read(struct bch_fs *c)
398 {
399         struct bch_sb_field_quota *sb_quota;
400         unsigned i, j;
401
402         sb_quota = bch2_sb_get_quota(c->disk_sb);
403         if (!sb_quota)
404                 return;
405
406         for (i = 0; i < QTYP_NR; i++) {
407                 struct bch_memquota_type *q = &c->quotas[i];
408
409                 for (j = 0; j < Q_COUNTERS; j++) {
410                         q->limits[j].timelimit =
411                                 le32_to_cpu(sb_quota->q[i].c[j].timelimit);
412                         q->limits[j].warnlimit =
413                                 le32_to_cpu(sb_quota->q[i].c[j].warnlimit);
414                 }
415         }
416 }
417
418 int bch2_fs_quota_read(struct bch_fs *c)
419 {
420         unsigned i, qtypes = enabled_qtypes(c);
421         struct bch_memquota_type *q;
422         struct btree_iter iter;
423         struct bch_inode_unpacked u;
424         struct bkey_s_c k;
425         int ret;
426
427         mutex_lock(&c->sb_lock);
428         bch2_sb_quota_read(c);
429         mutex_unlock(&c->sb_lock);
430
431         for_each_set_qtype(c, i, q, qtypes) {
432                 ret = bch2_quota_init_type(c, i);
433                 if (ret)
434                         return ret;
435         }
436
437         for_each_btree_key(&iter, c, BTREE_ID_INODES, POS_MIN,
438                            BTREE_ITER_PREFETCH, k) {
439                 switch (k.k->type) {
440                 case BCH_INODE_FS:
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                                         BCH_QUOTA_NOCHECK);
447                         bch2_quota_acct(c, bch_qid(&u), Q_INO, 1,
448                                         BCH_QUOTA_NOCHECK);
449                 }
450         }
451         return bch2_btree_iter_unlock(&iter) ?: 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 & MS_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, true);
480
481         if (uflags & FS_QUOTA_GDQ_ENFD)
482                 SET_BCH_SB_GRPQUOTA(c->disk_sb, true);
483
484         if (uflags & FS_QUOTA_PDQ_ENFD)
485                 SET_BCH_SB_PRJQUOTA(c->disk_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 & MS_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, false);
503
504         if (uflags & FS_QUOTA_GDQ_ENFD)
505                 SET_BCH_SB_GRPQUOTA(c->disk_sb, false);
506
507         if (uflags & FS_QUOTA_PDQ_ENFD)
508                 SET_BCH_SB_PRJQUOTA(c->disk_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 & MS_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                                               ZERO_VERSION, NULL, NULL, 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                                               ZERO_VERSION, NULL, NULL, 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                                               ZERO_VERSION, NULL, NULL, 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 & MS_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);
620         if (!sb_quota) {
621                 sb_quota = bch2_fs_sb_resize_quota(c, sizeof(*sb_quota) / sizeof(u64));
622                 if (!sb_quota)
623                         return -ENOSPC;
624         }
625
626         if (info->i_fieldmask & QC_SPC_TIMER)
627                 sb_quota->q[type].c[Q_SPC].timelimit =
628                         cpu_to_le32(info->i_spc_timelimit);
629
630         if (info->i_fieldmask & QC_SPC_WARNS)
631                 sb_quota->q[type].c[Q_SPC].warnlimit =
632                         cpu_to_le32(info->i_spc_warnlimit);
633
634         if (info->i_fieldmask & QC_INO_TIMER)
635                 sb_quota->q[type].c[Q_INO].timelimit =
636                         cpu_to_le32(info->i_ino_timelimit);
637
638         if (info->i_fieldmask & QC_INO_WARNS)
639                 sb_quota->q[type].c[Q_INO].warnlimit =
640                         cpu_to_le32(info->i_ino_warnlimit);
641
642         bch2_sb_quota_read(c);
643
644         bch2_write_super(c);
645         mutex_unlock(&c->sb_lock);
646
647         return 0;
648 }
649
650 /* Get/set individual quotas: */
651
652 static void __bch2_quota_get(struct qc_dqblk *dst, struct bch_memquota *src)
653 {
654         dst->d_space            = src->c[Q_SPC].v << 9;
655         dst->d_spc_hardlimit    = src->c[Q_SPC].hardlimit << 9;
656         dst->d_spc_softlimit    = src->c[Q_SPC].softlimit << 9;
657         dst->d_spc_timer        = src->c[Q_SPC].timer;
658         dst->d_spc_warns        = src->c[Q_SPC].warns;
659
660         dst->d_ino_count        = src->c[Q_INO].v;
661         dst->d_ino_hardlimit    = src->c[Q_INO].hardlimit;
662         dst->d_ino_softlimit    = src->c[Q_INO].softlimit;
663         dst->d_ino_timer        = src->c[Q_INO].timer;
664         dst->d_ino_warns        = src->c[Q_INO].warns;
665 }
666
667 static int bch2_get_quota(struct super_block *sb, struct kqid kqid,
668                           struct qc_dqblk *qdq)
669 {
670         struct bch_fs *c                = sb->s_fs_info;
671         struct bch_memquota_type *q     = &c->quotas[kqid.type];
672         qid_t qid                       = from_kqid(&init_user_ns, kqid);
673         struct bch_memquota *mq;
674
675         memset(qdq, 0, sizeof(*qdq));
676
677         mutex_lock(&q->lock);
678         mq = genradix_ptr(&q->table, qid);
679         if (mq)
680                 __bch2_quota_get(qdq, mq);
681         mutex_unlock(&q->lock);
682
683         return 0;
684 }
685
686 static int bch2_get_next_quota(struct super_block *sb, struct kqid *kqid,
687                                struct qc_dqblk *qdq)
688 {
689         struct bch_fs *c                = sb->s_fs_info;
690         struct bch_memquota_type *q     = &c->quotas[kqid->type];
691         qid_t qid                       = from_kqid(&init_user_ns, *kqid);
692         struct genradix_iter iter       = genradix_iter_init(&q->table, qid);
693         struct bch_memquota *mq;
694         int ret = 0;
695
696         mutex_lock(&q->lock);
697
698         while ((mq = genradix_iter_peek(&iter, &q->table))) {
699                 if (memcmp(mq, page_address(ZERO_PAGE(0)), sizeof(*mq))) {
700                         __bch2_quota_get(qdq, mq);
701                         *kqid = make_kqid(current_user_ns(), kqid->type, iter.pos);
702                         goto found;
703                 }
704
705                 genradix_iter_advance(&iter, &q->table);
706         }
707
708         ret = -ENOENT;
709 found:
710         mutex_unlock(&q->lock);
711         return ret;
712 }
713
714 static int bch2_set_quota(struct super_block *sb, struct kqid qid,
715                           struct qc_dqblk *qdq)
716 {
717         struct bch_fs *c = sb->s_fs_info;
718         struct btree_iter iter;
719         struct bkey_s_c k;
720         struct bkey_i_quota new_quota;
721         int ret;
722
723         if (sb->s_flags & MS_RDONLY)
724                 return -EROFS;
725
726         bkey_quota_init(&new_quota.k_i);
727         new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));
728
729         bch2_btree_iter_init(&iter, c, BTREE_ID_QUOTAS, new_quota.k.p,
730                              BTREE_ITER_SLOTS|BTREE_ITER_INTENT);
731         k = bch2_btree_iter_peek_slot(&iter);
732
733         ret = btree_iter_err(k);
734         if (unlikely(ret))
735                 return ret;
736
737         switch (k.k->type) {
738         case BCH_QUOTA:
739                 new_quota.v = *bkey_s_c_to_quota(k).v;
740                 break;
741         }
742
743         if (qdq->d_fieldmask & QC_SPC_SOFT)
744                 new_quota.v.c[Q_SPC].softlimit = cpu_to_le64(qdq->d_spc_softlimit >> 9);
745         if (qdq->d_fieldmask & QC_SPC_HARD)
746                 new_quota.v.c[Q_SPC].hardlimit = cpu_to_le64(qdq->d_spc_hardlimit >> 9);
747
748         if (qdq->d_fieldmask & QC_INO_SOFT)
749                 new_quota.v.c[Q_INO].softlimit = cpu_to_le64(qdq->d_ino_softlimit);
750         if (qdq->d_fieldmask & QC_INO_HARD)
751                 new_quota.v.c[Q_INO].hardlimit = cpu_to_le64(qdq->d_ino_hardlimit);
752
753         ret = bch2_btree_insert_at(c, NULL, NULL, NULL, 0,
754                                    BTREE_INSERT_ENTRY(&iter, &new_quota.k_i));
755         bch2_btree_iter_unlock(&iter);
756
757         if (ret)
758                 return ret;
759
760         ret = __bch2_quota_set(c, bkey_i_to_s_c(&new_quota.k_i));
761
762         return ret;
763 }
764
765 const struct quotactl_ops bch2_quotactl_operations = {
766         .quota_enable           = bch2_quota_enable,
767         .quota_disable          = bch2_quota_disable,
768         .rm_xquota              = bch2_quota_remove,
769
770         .get_state              = bch2_quota_get_state,
771         .set_info               = bch2_quota_set_info,
772
773         .get_dqblk              = bch2_get_quota,
774         .get_nextdqblk          = bch2_get_next_quota,
775         .set_dqblk              = bch2_set_quota,
776 };
777
778 #endif /* CONFIG_BCACHEFS_QUOTA */