// SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h"
#include "btree_update.h"
#include "errcode.h"
#include "error.h"
#include "inode.h"
#include "quota.h"
#include "snapshot.h"
#include "super-io.h"

static const char * const bch2_quota_types[] = {
	"user",
	"group",
	"project",
};

static const char * const bch2_quota_counters[] = {
	"space",
	"inodes",
};

static int bch2_sb_quota_validate(struct bch_sb *sb, struct bch_sb_field *f,
				  enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_quota *q = field_to_type(f, quota);

	if (vstruct_bytes(&q->field) < sizeof(*q)) {
		prt_printf(err, "wrong size (got %zu should be %zu)",
		       vstruct_bytes(&q->field), sizeof(*q));
		return -BCH_ERR_invalid_sb_quota;
	}

	return 0;
}

static void bch2_sb_quota_to_text(struct printbuf *out, struct bch_sb *sb,
				  struct bch_sb_field *f)
{
	struct bch_sb_field_quota *q = field_to_type(f, quota);
	unsigned qtyp, counter;

	for (qtyp = 0; qtyp < ARRAY_SIZE(q->q); qtyp++) {
		prt_printf(out, "%s: flags %llx",
		       bch2_quota_types[qtyp],
		       le64_to_cpu(q->q[qtyp].flags));

		for (counter = 0; counter < Q_COUNTERS; counter++)
			prt_printf(out, " %s timelimit %u warnlimit %u",
			       bch2_quota_counters[counter],
			       le32_to_cpu(q->q[qtyp].c[counter].timelimit),
			       le32_to_cpu(q->q[qtyp].c[counter].warnlimit));

		prt_newline(out);
	}
}

const struct bch_sb_field_ops bch_sb_field_ops_quota = {
	.validate	= bch2_sb_quota_validate,
	.to_text	= bch2_sb_quota_to_text,
};

int bch2_quota_validate(struct bch_fs *c, struct bkey_s_c k,
			struct bkey_validate_context from)
{
	int ret = 0;

	bkey_fsck_err_on(k.k->p.inode >= QTYP_NR,
			 c, quota_type_invalid,
			 "invalid quota type (%llu >= %u)",
			 k.k->p.inode, QTYP_NR);
fsck_err:
	return ret;
}

void bch2_quota_to_text(struct printbuf *out, struct bch_fs *c,
			struct bkey_s_c k)
{
	struct bkey_s_c_quota dq = bkey_s_c_to_quota(k);
	unsigned i;

	for (i = 0; i < Q_COUNTERS; i++)
		prt_printf(out, "%s hardlimit %llu softlimit %llu",
		       bch2_quota_counters[i],
		       le64_to_cpu(dq.v->c[i].hardlimit),
		       le64_to_cpu(dq.v->c[i].softlimit));
}

#ifdef CONFIG_BCACHEFS_QUOTA

#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/quota.h>

static void qc_info_to_text(struct printbuf *out, struct qc_info *i)
{
	printbuf_tabstops_reset(out);
	printbuf_tabstop_push(out, 20);

	prt_printf(out, "i_fieldmask\t%x\n",		i->i_fieldmask);
	prt_printf(out, "i_flags\t%u\n",		i->i_flags);
	prt_printf(out, "i_spc_timelimit\t%u\n",	i->i_spc_timelimit);
	prt_printf(out, "i_ino_timelimit\t%u\n",	i->i_ino_timelimit);
	prt_printf(out, "i_rt_spc_timelimit\t%u\n",	i->i_rt_spc_timelimit);
	prt_printf(out, "i_spc_warnlimit\t%u\n",	i->i_spc_warnlimit);
	prt_printf(out, "i_ino_warnlimit\t%u\n",	i->i_ino_warnlimit);
	prt_printf(out, "i_rt_spc_warnlimit\t%u\n",	i->i_rt_spc_warnlimit);
}

static void qc_dqblk_to_text(struct printbuf *out, struct qc_dqblk *q)
{
	printbuf_tabstops_reset(out);
	printbuf_tabstop_push(out, 20);

	prt_printf(out, "d_fieldmask\t%x\n",		q->d_fieldmask);
	prt_printf(out, "d_spc_hardlimit\t%llu\n",	q->d_spc_hardlimit);
	prt_printf(out, "d_spc_softlimit\t%llu\n",	q->d_spc_softlimit);
	prt_printf(out, "d_ino_hardlimit\%llu\n",	q->d_ino_hardlimit);
	prt_printf(out, "d_ino_softlimit\t%llu\n",	q->d_ino_softlimit);
	prt_printf(out, "d_space\t%llu\n",		q->d_space);
	prt_printf(out, "d_ino_count\t%llu\n",		q->d_ino_count);
	prt_printf(out, "d_ino_timer\t%llu\n",		q->d_ino_timer);
	prt_printf(out, "d_spc_timer\t%llu\n",		q->d_spc_timer);
	prt_printf(out, "d_ino_warns\t%i\n",		q->d_ino_warns);
	prt_printf(out, "d_spc_warns\t%i\n",		q->d_spc_warns);
}

static inline unsigned __next_qtype(unsigned i, unsigned qtypes)
{
	qtypes >>= i;
	return qtypes ? i + __ffs(qtypes) : QTYP_NR;
}

#define for_each_set_qtype(_c, _i, _q, _qtypes)				\
	for (_i = 0;							\
	     (_i = __next_qtype(_i, _qtypes),				\
	      _q = &(_c)->quotas[_i],					\
	      _i < QTYP_NR);						\
	     _i++)

static bool ignore_hardlimit(struct bch_memquota_type *q)
{
	if (capable(CAP_SYS_RESOURCE))
		return true;
#if 0
	struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];

	return capable(CAP_SYS_RESOURCE) &&
	       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
		!(info->dqi_flags & DQF_ROOT_SQUASH));
#endif
	return false;
}

enum quota_msg {
	SOFTWARN,	/* Softlimit reached */
	SOFTLONGWARN,	/* Grace time expired */
	HARDWARN,	/* Hardlimit reached */

	HARDBELOW,	/* Usage got below inode hardlimit */
	SOFTBELOW,	/* Usage got below inode softlimit */
};

static int quota_nl[][Q_COUNTERS] = {
	[HARDWARN][Q_SPC]	= QUOTA_NL_BHARDWARN,
	[SOFTLONGWARN][Q_SPC]	= QUOTA_NL_BSOFTLONGWARN,
	[SOFTWARN][Q_SPC]	= QUOTA_NL_BSOFTWARN,
	[HARDBELOW][Q_SPC]	= QUOTA_NL_BHARDBELOW,
	[SOFTBELOW][Q_SPC]	= QUOTA_NL_BSOFTBELOW,

	[HARDWARN][Q_INO]	= QUOTA_NL_IHARDWARN,
	[SOFTLONGWARN][Q_INO]	= QUOTA_NL_ISOFTLONGWARN,
	[SOFTWARN][Q_INO]	= QUOTA_NL_ISOFTWARN,
	[HARDBELOW][Q_INO]	= QUOTA_NL_IHARDBELOW,
	[SOFTBELOW][Q_INO]	= QUOTA_NL_ISOFTBELOW,
};

struct quota_msgs {
	u8		nr;
	struct {
		u8	qtype;
		u8	msg;
	}		m[QTYP_NR * Q_COUNTERS];
};

static void prepare_msg(unsigned qtype,
			enum quota_counters counter,
			struct quota_msgs *msgs,
			enum quota_msg msg_type)
{
	BUG_ON(msgs->nr >= ARRAY_SIZE(msgs->m));

	msgs->m[msgs->nr].qtype	= qtype;
	msgs->m[msgs->nr].msg	= quota_nl[msg_type][counter];
	msgs->nr++;
}

static void prepare_warning(struct memquota_counter *qc,
			    unsigned qtype,
			    enum quota_counters counter,
			    struct quota_msgs *msgs,
			    enum quota_msg msg_type)
{
	if (qc->warning_issued & (1 << msg_type))
		return;

	prepare_msg(qtype, counter, msgs, msg_type);
}

static void flush_warnings(struct bch_qid qid,
			   struct super_block *sb,
			   struct quota_msgs *msgs)
{
	unsigned i;

	for (i = 0; i < msgs->nr; i++)
		quota_send_warning(make_kqid(&init_user_ns, msgs->m[i].qtype, qid.q[i]),
				   sb->s_dev, msgs->m[i].msg);
}

static int bch2_quota_check_limit(struct bch_fs *c,
				  unsigned qtype,
				  struct bch_memquota *mq,
				  struct quota_msgs *msgs,
				  enum quota_counters counter,
				  s64 v,
				  enum quota_acct_mode mode)
{
	struct bch_memquota_type *q = &c->quotas[qtype];
	struct memquota_counter *qc = &mq->c[counter];
	u64 n = qc->v + v;

	BUG_ON((s64) n < 0);

	if (mode == KEY_TYPE_QUOTA_NOCHECK)
		return 0;

	if (v <= 0) {
		if (n < qc->hardlimit &&
		    (qc->warning_issued & (1 << HARDWARN))) {
			qc->warning_issued &= ~(1 << HARDWARN);
			prepare_msg(qtype, counter, msgs, HARDBELOW);
		}

		if (n < qc->softlimit &&
		    (qc->warning_issued & (1 << SOFTWARN))) {
			qc->warning_issued &= ~(1 << SOFTWARN);
			prepare_msg(qtype, counter, msgs, SOFTBELOW);
		}

		qc->warning_issued = 0;
		return 0;
	}

	if (qc->hardlimit &&
	    qc->hardlimit < n &&
	    !ignore_hardlimit(q)) {
		prepare_warning(qc, qtype, counter, msgs, HARDWARN);
		return -EDQUOT;
	}

	if (qc->softlimit &&
	    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;
		}
	}

	return 0;
}

int bch2_quota_acct(struct bch_fs *c, struct bch_qid qid,
		    enum quota_counters counter, s64 v,
		    enum quota_acct_mode mode)
{
	unsigned qtypes = enabled_qtypes(c);
	struct bch_memquota_type *q;
	struct bch_memquota *mq[QTYP_NR];
	struct quota_msgs msgs;
	unsigned i;
	int ret = 0;

	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) {
		ret = bch2_quota_check_limit(c, i, mq[i], &msgs, counter, v, mode);
		if (ret)
			goto err;
	}

	for_each_set_qtype(c, i, q, qtypes)
		mq[i]->c[counter].v += v;
err:
	for_each_set_qtype(c, i, q, qtypes)
		mutex_unlock(&q->lock);

	flush_warnings(qid, c->vfs_sb, &msgs);

	return ret;
}

static void __bch2_quota_transfer(struct bch_memquota *src_q,
				  struct bch_memquota *dst_q,
				  enum quota_counters counter, s64 v)
{
	BUG_ON(v > src_q->c[counter].v);
	BUG_ON(v + dst_q->c[counter].v < v);

	src_q->c[counter].v -= v;
	dst_q->c[counter].v += v;
}

int bch2_quota_transfer(struct bch_fs *c, unsigned qtypes,
			struct bch_qid dst,
			struct bch_qid src, u64 space,
			enum quota_acct_mode mode)
{
	struct bch_memquota_type *q;
	struct bch_memquota *src_q[3], *dst_q[3];
	struct quota_msgs msgs;
	unsigned i;
	int ret = 0;

	qtypes &= enabled_qtypes(c);

	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) {
		ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_SPC,
					     dst_q[i]->c[Q_SPC].v + space,
					     mode);
		if (ret)
			goto err;

		ret = bch2_quota_check_limit(c, i, dst_q[i], &msgs, Q_INO,
					     dst_q[i]->c[Q_INO].v + 1,
					     mode);
		if (ret)
			goto err;
	}

	for_each_set_qtype(c, i, q, qtypes) {
		__bch2_quota_transfer(src_q[i], dst_q[i], Q_SPC, space);
		__bch2_quota_transfer(src_q[i], dst_q[i], Q_INO, 1);
	}

err:
	for_each_set_qtype(c, i, q, qtypes)
		mutex_unlock(&q->lock);

	flush_warnings(dst, c->vfs_sb, &msgs);

	return ret;
}

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;
	struct bch_memquota *mq;
	unsigned i;

	BUG_ON(k.k->p.inode >= QTYP_NR);

	if (!((1U << k.k->p.inode) & enabled_qtypes(c)))
		return 0;

	switch (k.k->type) {
	case KEY_TYPE_quota:
		dq = bkey_s_c_to_quota(k);
		q = &c->quotas[k.k->p.inode];

		mutex_lock(&q->lock);
		mq = genradix_ptr_alloc(&q->table, k.k->p.offset, GFP_KERNEL);
		if (!mq) {
			mutex_unlock(&q->lock);
			return -ENOMEM;
		}

		for (i = 0; i < Q_COUNTERS; i++) {
			mq->c[i].hardlimit = le64_to_cpu(dq.v->c[i].hardlimit);
			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	= qdq->d_spc_timer;
		if (qdq && qdq->d_fieldmask & QC_SPC_WARNS)
			mq->c[Q_SPC].warns	= qdq->d_spc_warns;
		if (qdq && qdq->d_fieldmask & QC_INO_TIMER)
			mq->c[Q_INO].timer	= qdq->d_ino_timer;
		if (qdq && qdq->d_fieldmask & QC_INO_WARNS)
			mq->c[Q_INO].warns	= qdq->d_ino_warns;

		mutex_unlock(&q->lock);
	}

	return 0;
}

void bch2_fs_quota_exit(struct bch_fs *c)
{
	unsigned i;

	for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
		genradix_free(&c->quotas[i].table);
}

void bch2_fs_quota_init(struct bch_fs *c)
{
	unsigned i;

	for (i = 0; i < ARRAY_SIZE(c->quotas); i++)
		mutex_init(&c->quotas[i].lock);
}

static struct bch_sb_field_quota *bch2_sb_get_or_create_quota(struct bch_sb_handle *sb)
{
	struct bch_sb_field_quota *sb_quota = bch2_sb_field_get(sb->sb, quota);

	if (sb_quota)
		return sb_quota;

	sb_quota = bch2_sb_field_resize(sb, quota, sizeof(*sb_quota) / sizeof(u64));
	if (sb_quota) {
		unsigned qtype, qc;

		for (qtype = 0; qtype < QTYP_NR; qtype++)
			for (qc = 0; qc < Q_COUNTERS; qc++)
				sb_quota->q[qtype].c[qc].timelimit =
					cpu_to_le32(7 * 24 * 60 * 60);
	}

	return sb_quota;
}

static void bch2_sb_quota_read(struct bch_fs *c)
{
	struct bch_sb_field_quota *sb_quota;
	unsigned i, j;

	sb_quota = bch2_sb_field_get(c->disk_sb.sb, quota);
	if (!sb_quota)
		return;

	for (i = 0; i < QTYP_NR; i++) {
		struct bch_memquota_type *q = &c->quotas[i];

		for (j = 0; j < Q_COUNTERS; j++) {
			q->limits[j].timelimit =
				le32_to_cpu(sb_quota->q[i].c[j].timelimit);
			q->limits[j].warnlimit =
				le32_to_cpu(sb_quota->q[i].c[j].warnlimit);
		}
	}
}

static int bch2_fs_quota_read_inode(struct btree_trans *trans,
				    struct btree_iter *iter,
				    struct bkey_s_c k)
{
	struct bch_fs *c = trans->c;
	struct bch_inode_unpacked u;
	struct bch_snapshot_tree s_t;
	u32 tree = bch2_snapshot_tree(c, k.k->p.snapshot);

	int ret = bch2_snapshot_tree_lookup(trans, tree, &s_t);
	bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c,
			"%s: snapshot tree %u not found", __func__, tree);
	if (ret)
		return ret;

	if (!s_t.master_subvol)
		goto advance;

	ret = bch2_inode_find_by_inum_nowarn_trans(trans,
				(subvol_inum) {
					le32_to_cpu(s_t.master_subvol),
					k.k->p.offset,
				}, &u);
	/*
	 * Inode might be deleted in this snapshot - the easiest way to handle
	 * that is to just skip it here:
	 */
	if (bch2_err_matches(ret, ENOENT))
		goto advance;

	if (ret)
		return ret;

	bch2_quota_acct(c, bch_qid(&u), Q_SPC, u.bi_sectors,
			KEY_TYPE_QUOTA_NOCHECK);
	bch2_quota_acct(c, bch_qid(&u), Q_INO, 1,
			KEY_TYPE_QUOTA_NOCHECK);
advance:
	bch2_btree_iter_set_pos(iter, bpos_nosnap_successor(iter->pos));
	return 0;
}

int bch2_fs_quota_read(struct bch_fs *c)
{

	mutex_lock(&c->sb_lock);
	struct bch_sb_field_quota *sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
	if (!sb_quota) {
		mutex_unlock(&c->sb_lock);
		return -BCH_ERR_ENOSPC_sb_quota;
	}

	bch2_sb_quota_read(c);
	mutex_unlock(&c->sb_lock);

	int ret = bch2_trans_run(c,
		for_each_btree_key(trans, iter, BTREE_ID_quotas, POS_MIN,
				   BTREE_ITER_prefetch, k,
			__bch2_quota_set(c, k, NULL)) ?:
		for_each_btree_key(trans, iter, BTREE_ID_inodes, POS_MIN,
				   BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k,
			bch2_fs_quota_read_inode(trans, &iter, k)));
	bch_err_fn(c, ret);
	return ret;
}

/* Enable/disable/delete quotas for an entire filesystem: */

static int bch2_quota_enable(struct super_block	*sb, unsigned uflags)
{
	struct bch_fs *c = sb->s_fs_info;
	struct bch_sb_field_quota *sb_quota;
	int ret = 0;

	if (sb->s_flags & SB_RDONLY)
		return -EROFS;

	/* Accounting must be enabled at mount time: */
	if (uflags & (FS_QUOTA_UDQ_ACCT|FS_QUOTA_GDQ_ACCT|FS_QUOTA_PDQ_ACCT))
		return -EINVAL;

	/* Can't enable enforcement without accounting: */
	if ((uflags & FS_QUOTA_UDQ_ENFD) && !c->opts.usrquota)
		return -EINVAL;

	if ((uflags & FS_QUOTA_GDQ_ENFD) && !c->opts.grpquota)
		return -EINVAL;

	if (uflags & FS_QUOTA_PDQ_ENFD && !c->opts.prjquota)
		return -EINVAL;

	mutex_lock(&c->sb_lock);
	sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
	if (!sb_quota) {
		ret = -BCH_ERR_ENOSPC_sb_quota;
		goto unlock;
	}

	if (uflags & FS_QUOTA_UDQ_ENFD)
		SET_BCH_SB_USRQUOTA(c->disk_sb.sb, true);

	if (uflags & FS_QUOTA_GDQ_ENFD)
		SET_BCH_SB_GRPQUOTA(c->disk_sb.sb, true);

	if (uflags & FS_QUOTA_PDQ_ENFD)
		SET_BCH_SB_PRJQUOTA(c->disk_sb.sb, true);

	bch2_write_super(c);
unlock:
	mutex_unlock(&c->sb_lock);

	return bch2_err_class(ret);
}

static int bch2_quota_disable(struct super_block *sb, unsigned uflags)
{
	struct bch_fs *c = sb->s_fs_info;

	if (sb->s_flags & SB_RDONLY)
		return -EROFS;

	mutex_lock(&c->sb_lock);
	if (uflags & FS_QUOTA_UDQ_ENFD)
		SET_BCH_SB_USRQUOTA(c->disk_sb.sb, false);

	if (uflags & FS_QUOTA_GDQ_ENFD)
		SET_BCH_SB_GRPQUOTA(c->disk_sb.sb, false);

	if (uflags & FS_QUOTA_PDQ_ENFD)
		SET_BCH_SB_PRJQUOTA(c->disk_sb.sb, false);

	bch2_write_super(c);
	mutex_unlock(&c->sb_lock);

	return 0;
}

static int bch2_quota_remove(struct super_block *sb, unsigned uflags)
{
	struct bch_fs *c = sb->s_fs_info;
	int ret;

	if (sb->s_flags & SB_RDONLY)
		return -EROFS;

	if (uflags & FS_USER_QUOTA) {
		if (c->opts.usrquota)
			return -EINVAL;

		ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
					      POS(QTYP_USR, 0),
					      POS(QTYP_USR, U64_MAX),
					      0, NULL);
		if (ret)
			return ret;
	}

	if (uflags & FS_GROUP_QUOTA) {
		if (c->opts.grpquota)
			return -EINVAL;

		ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
					      POS(QTYP_GRP, 0),
					      POS(QTYP_GRP, U64_MAX),
					      0, NULL);
		if (ret)
			return ret;
	}

	if (uflags & FS_PROJ_QUOTA) {
		if (c->opts.prjquota)
			return -EINVAL;

		ret = bch2_btree_delete_range(c, BTREE_ID_quotas,
					      POS(QTYP_PRJ, 0),
					      POS(QTYP_PRJ, U64_MAX),
					      0, NULL);
		if (ret)
			return ret;
	}

	return 0;
}

/*
 * Return quota status information, such as enforcements, quota file inode
 * numbers etc.
 */
static int bch2_quota_get_state(struct super_block *sb, struct qc_state *state)
{
	struct bch_fs *c = sb->s_fs_info;
	unsigned qtypes = enabled_qtypes(c);
	unsigned i;

	memset(state, 0, sizeof(*state));

	for (i = 0; i < QTYP_NR; i++) {
		state->s_state[i].flags |= QCI_SYSFILE;

		if (!(qtypes & (1 << i)))
			continue;

		state->s_state[i].flags |= QCI_ACCT_ENABLED;

		state->s_state[i].spc_timelimit = c->quotas[i].limits[Q_SPC].timelimit;
		state->s_state[i].spc_warnlimit = c->quotas[i].limits[Q_SPC].warnlimit;

		state->s_state[i].ino_timelimit = c->quotas[i].limits[Q_INO].timelimit;
		state->s_state[i].ino_warnlimit = c->quotas[i].limits[Q_INO].warnlimit;
	}

	return 0;
}

/*
 * Adjust quota timers & warnings
 */
static int bch2_quota_set_info(struct super_block *sb, int type,
			       struct qc_info *info)
{
	struct bch_fs *c = sb->s_fs_info;
	struct bch_sb_field_quota *sb_quota;
	int ret = 0;

	if (0) {
		struct printbuf buf = PRINTBUF;

		qc_info_to_text(&buf, info);
		pr_info("setting:\n%s", buf.buf);
		printbuf_exit(&buf);
	}

	if (sb->s_flags & SB_RDONLY)
		return -EROFS;

	if (type >= QTYP_NR)
		return -EINVAL;

	if (!((1 << type) & enabled_qtypes(c)))
		return -ESRCH;

	if (info->i_fieldmask &
	    ~(QC_SPC_TIMER|QC_INO_TIMER|QC_SPC_WARNS|QC_INO_WARNS))
		return -EINVAL;

	mutex_lock(&c->sb_lock);
	sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
	if (!sb_quota) {
		ret = -BCH_ERR_ENOSPC_sb_quota;
		goto unlock;
	}

	if (info->i_fieldmask & QC_SPC_TIMER)
		sb_quota->q[type].c[Q_SPC].timelimit =
			cpu_to_le32(info->i_spc_timelimit);

	if (info->i_fieldmask & QC_SPC_WARNS)
		sb_quota->q[type].c[Q_SPC].warnlimit =
			cpu_to_le32(info->i_spc_warnlimit);

	if (info->i_fieldmask & QC_INO_TIMER)
		sb_quota->q[type].c[Q_INO].timelimit =
			cpu_to_le32(info->i_ino_timelimit);

	if (info->i_fieldmask & QC_INO_WARNS)
		sb_quota->q[type].c[Q_INO].warnlimit =
			cpu_to_le32(info->i_ino_warnlimit);

	bch2_sb_quota_read(c);

	bch2_write_super(c);
unlock:
	mutex_unlock(&c->sb_lock);

	return bch2_err_class(ret);
}

/* Get/set individual quotas: */

static void __bch2_quota_get(struct qc_dqblk *dst, struct bch_memquota *src)
{
	dst->d_space		= src->c[Q_SPC].v << 9;
	dst->d_spc_hardlimit	= src->c[Q_SPC].hardlimit << 9;
	dst->d_spc_softlimit	= src->c[Q_SPC].softlimit << 9;
	dst->d_spc_timer	= src->c[Q_SPC].timer;
	dst->d_spc_warns	= src->c[Q_SPC].warns;

	dst->d_ino_count	= src->c[Q_INO].v;
	dst->d_ino_hardlimit	= src->c[Q_INO].hardlimit;
	dst->d_ino_softlimit	= src->c[Q_INO].softlimit;
	dst->d_ino_timer	= src->c[Q_INO].timer;
	dst->d_ino_warns	= src->c[Q_INO].warns;
}

static int bch2_get_quota(struct super_block *sb, struct kqid kqid,
			  struct qc_dqblk *qdq)
{
	struct bch_fs *c		= sb->s_fs_info;
	struct bch_memquota_type *q	= &c->quotas[kqid.type];
	qid_t qid			= from_kqid(&init_user_ns, kqid);
	struct bch_memquota *mq;

	memset(qdq, 0, sizeof(*qdq));

	mutex_lock(&q->lock);
	mq = genradix_ptr(&q->table, qid);
	if (mq)
		__bch2_quota_get(qdq, mq);
	mutex_unlock(&q->lock);

	return 0;
}

static int bch2_get_next_quota(struct super_block *sb, struct kqid *kqid,
			       struct qc_dqblk *qdq)
{
	struct bch_fs *c		= sb->s_fs_info;
	struct bch_memquota_type *q	= &c->quotas[kqid->type];
	qid_t qid			= from_kqid(&init_user_ns, *kqid);
	struct genradix_iter iter;
	struct bch_memquota *mq;
	int ret = 0;

	mutex_lock(&q->lock);

	genradix_for_each_from(&q->table, iter, mq, qid)
		if (memcmp(mq, page_address(ZERO_PAGE(0)), sizeof(*mq))) {
			__bch2_quota_get(qdq, mq);
			*kqid = make_kqid(current_user_ns(), kqid->type, iter.pos);
			goto found;
		}

	ret = -ENOENT;
found:
	mutex_unlock(&q->lock);
	return bch2_err_class(ret);
}

static int bch2_set_quota_trans(struct btree_trans *trans,
				struct bkey_i_quota *new_quota,
				struct qc_dqblk *qdq)
{
	struct btree_iter iter;
	struct bkey_s_c k;
	int ret;

	k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_quotas, new_quota->k.p,
			       BTREE_ITER_slots|BTREE_ITER_intent);
	ret = bkey_err(k);
	if (unlikely(ret))
		return ret;

	if (k.k->type == KEY_TYPE_quota)
		new_quota->v = *bkey_s_c_to_quota(k).v;

	if (qdq->d_fieldmask & QC_SPC_SOFT)
		new_quota->v.c[Q_SPC].softlimit = cpu_to_le64(qdq->d_spc_softlimit >> 9);
	if (qdq->d_fieldmask & QC_SPC_HARD)
		new_quota->v.c[Q_SPC].hardlimit = cpu_to_le64(qdq->d_spc_hardlimit >> 9);

	if (qdq->d_fieldmask & QC_INO_SOFT)
		new_quota->v.c[Q_INO].softlimit = cpu_to_le64(qdq->d_ino_softlimit);
	if (qdq->d_fieldmask & QC_INO_HARD)
		new_quota->v.c[Q_INO].hardlimit = cpu_to_le64(qdq->d_ino_hardlimit);

	ret = bch2_trans_update(trans, &iter, &new_quota->k_i, 0);
	bch2_trans_iter_exit(trans, &iter);
	return ret;
}

static int bch2_set_quota(struct super_block *sb, struct kqid qid,
			  struct qc_dqblk *qdq)
{
	struct bch_fs *c = sb->s_fs_info;
	struct bkey_i_quota new_quota;
	int ret;

	if (0) {
		struct printbuf buf = PRINTBUF;

		qc_dqblk_to_text(&buf, qdq);
		pr_info("setting:\n%s", buf.buf);
		printbuf_exit(&buf);
	}

	if (sb->s_flags & SB_RDONLY)
		return -EROFS;

	bkey_quota_init(&new_quota.k_i);
	new_quota.k.p = POS(qid.type, from_kqid(&init_user_ns, qid));

	ret = bch2_trans_commit_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), qdq);

	return bch2_err_class(ret);
}

const struct quotactl_ops bch2_quotactl_operations = {
	.quota_enable		= bch2_quota_enable,
	.quota_disable		= bch2_quota_disable,
	.rm_xquota		= bch2_quota_remove,

	.get_state		= bch2_quota_get_state,
	.set_info		= bch2_quota_set_info,

	.get_dqblk		= bch2_get_quota,
	.get_nextdqblk		= bch2_get_next_quota,
	.set_dqblk		= bch2_set_quota,
};

#endif /* CONFIG_BCACHEFS_QUOTA */
