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