// 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_invalid(struct bch_fs *c, struct bkey_s_c k,
		       enum bch_validate_flags flags, struct printbuf *err)
{
	int ret = 0;

	bkey_fsck_err_on(k.k->p.inode >= QTYP_NR, c, err,
			 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_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 */
