15e5c12b0Sopenharmony_ci/*
25e5c12b0Sopenharmony_ci * Implementation of new quotafile format
35e5c12b0Sopenharmony_ci *
45e5c12b0Sopenharmony_ci * Jan Kara <jack@suse.cz> - sponsored by SuSE CR
55e5c12b0Sopenharmony_ci * Hyojun Kim <hyojun@google.com> - Ported to f2fs-tools
65e5c12b0Sopenharmony_ci */
75e5c12b0Sopenharmony_ci
85e5c12b0Sopenharmony_ci#include <sys/types.h>
95e5c12b0Sopenharmony_ci#include <errno.h>
105e5c12b0Sopenharmony_ci#include <stdio.h>
115e5c12b0Sopenharmony_ci#include <stdlib.h>
125e5c12b0Sopenharmony_ci#include <string.h>
135e5c12b0Sopenharmony_ci#include <unistd.h>
145e5c12b0Sopenharmony_ci
155e5c12b0Sopenharmony_ci#include "common.h"
165e5c12b0Sopenharmony_ci
175e5c12b0Sopenharmony_ci#include "quotaio_v2.h"
185e5c12b0Sopenharmony_ci#include "dqblk_v2.h"
195e5c12b0Sopenharmony_ci#include "quotaio_tree.h"
205e5c12b0Sopenharmony_ci
215e5c12b0Sopenharmony_cistatic int v2_check_file(struct quota_handle *h, int type);
225e5c12b0Sopenharmony_cistatic int v2_init_io(struct quota_handle *h, enum quota_type qtype);
235e5c12b0Sopenharmony_cistatic int v2_new_io(struct quota_handle *h);
245e5c12b0Sopenharmony_cistatic int v2_write_info(struct quota_handle *h);
255e5c12b0Sopenharmony_cistatic struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id);
265e5c12b0Sopenharmony_cistatic int v2_commit_dquot(struct dquot *dquot);
275e5c12b0Sopenharmony_cistatic int v2_scan_dquots(struct quota_handle *h,
285e5c12b0Sopenharmony_ci			  int (*process_dquot) (struct dquot *dquot,
295e5c12b0Sopenharmony_ci						void *data),
305e5c12b0Sopenharmony_ci			  void *data);
315e5c12b0Sopenharmony_cistatic int v2_report(struct quota_handle *h, int verbose);
325e5c12b0Sopenharmony_ci
335e5c12b0Sopenharmony_cistruct quotafile_ops quotafile_ops_2 = {
345e5c12b0Sopenharmony_ci	.check_file	= v2_check_file,
355e5c12b0Sopenharmony_ci	.init_io 	= v2_init_io,
365e5c12b0Sopenharmony_ci	.new_io 	= v2_new_io,
375e5c12b0Sopenharmony_ci	.write_info	= v2_write_info,
385e5c12b0Sopenharmony_ci	.read_dquot	= v2_read_dquot,
395e5c12b0Sopenharmony_ci	.commit_dquot	= v2_commit_dquot,
405e5c12b0Sopenharmony_ci	.scan_dquots	= v2_scan_dquots,
415e5c12b0Sopenharmony_ci	.report		= v2_report,
425e5c12b0Sopenharmony_ci};
435e5c12b0Sopenharmony_ci
445e5c12b0Sopenharmony_ci/*
455e5c12b0Sopenharmony_ci * Copy dquot from disk to memory
465e5c12b0Sopenharmony_ci */
475e5c12b0Sopenharmony_cistatic void v2r1_disk2memdqblk(struct dquot *dquot, void *dp)
485e5c12b0Sopenharmony_ci{
495e5c12b0Sopenharmony_ci	struct util_dqblk *m = &dquot->dq_dqb;
505e5c12b0Sopenharmony_ci	struct v2r1_disk_dqblk *d = dp, empty;
515e5c12b0Sopenharmony_ci
525e5c12b0Sopenharmony_ci	dquot->dq_id = le32_to_cpu(d->dqb_id);
535e5c12b0Sopenharmony_ci	m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
545e5c12b0Sopenharmony_ci	m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
555e5c12b0Sopenharmony_ci	m->dqb_bhardlimit = le64_to_cpu(d->dqb_bhardlimit);
565e5c12b0Sopenharmony_ci	m->dqb_bsoftlimit = le64_to_cpu(d->dqb_bsoftlimit);
575e5c12b0Sopenharmony_ci	m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
585e5c12b0Sopenharmony_ci	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
595e5c12b0Sopenharmony_ci	m->dqb_itime = le64_to_cpu(d->dqb_itime);
605e5c12b0Sopenharmony_ci	m->dqb_btime = le64_to_cpu(d->dqb_btime);
615e5c12b0Sopenharmony_ci
625e5c12b0Sopenharmony_ci	memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
635e5c12b0Sopenharmony_ci	empty.dqb_itime = cpu_to_le64(1);
645e5c12b0Sopenharmony_ci	if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
655e5c12b0Sopenharmony_ci		m->dqb_itime = 0;
665e5c12b0Sopenharmony_ci}
675e5c12b0Sopenharmony_ci
685e5c12b0Sopenharmony_ci/*
695e5c12b0Sopenharmony_ci * Copy dquot from memory to disk
705e5c12b0Sopenharmony_ci */
715e5c12b0Sopenharmony_cistatic void v2r1_mem2diskdqblk(void *dp, struct dquot *dquot)
725e5c12b0Sopenharmony_ci{
735e5c12b0Sopenharmony_ci	struct util_dqblk *m = &dquot->dq_dqb;
745e5c12b0Sopenharmony_ci	struct v2r1_disk_dqblk *d = dp;
755e5c12b0Sopenharmony_ci
765e5c12b0Sopenharmony_ci	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
775e5c12b0Sopenharmony_ci	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
785e5c12b0Sopenharmony_ci	d->dqb_bhardlimit = cpu_to_le64(m->dqb_bhardlimit);
795e5c12b0Sopenharmony_ci	d->dqb_bsoftlimit = cpu_to_le64(m->dqb_bsoftlimit);
805e5c12b0Sopenharmony_ci	d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
815e5c12b0Sopenharmony_ci	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
825e5c12b0Sopenharmony_ci	d->dqb_itime = cpu_to_le64(m->dqb_itime);
835e5c12b0Sopenharmony_ci	d->dqb_btime = cpu_to_le64(m->dqb_btime);
845e5c12b0Sopenharmony_ci	d->dqb_id = cpu_to_le32(dquot->dq_id);
855e5c12b0Sopenharmony_ci	if (qtree_entry_unused(&dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree, dp))
865e5c12b0Sopenharmony_ci		d->dqb_itime = cpu_to_le64(1);
875e5c12b0Sopenharmony_ci}
885e5c12b0Sopenharmony_ci
895e5c12b0Sopenharmony_cistatic int v2r1_is_id(void *dp, struct dquot *dquot)
905e5c12b0Sopenharmony_ci{
915e5c12b0Sopenharmony_ci	struct v2r1_disk_dqblk *d = dp;
925e5c12b0Sopenharmony_ci	struct qtree_mem_dqinfo *info =
935e5c12b0Sopenharmony_ci			&dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree;
945e5c12b0Sopenharmony_ci
955e5c12b0Sopenharmony_ci	if (qtree_entry_unused(info, dp))
965e5c12b0Sopenharmony_ci		return 0;
975e5c12b0Sopenharmony_ci	return le32_to_cpu(d->dqb_id) == dquot->dq_id;
985e5c12b0Sopenharmony_ci}
995e5c12b0Sopenharmony_ci
1005e5c12b0Sopenharmony_cistatic struct qtree_fmt_operations v2r1_fmt_ops = {
1015e5c12b0Sopenharmony_ci	.mem2disk_dqblk = v2r1_mem2diskdqblk,
1025e5c12b0Sopenharmony_ci	.disk2mem_dqblk = v2r1_disk2memdqblk,
1035e5c12b0Sopenharmony_ci	.is_id = v2r1_is_id,
1045e5c12b0Sopenharmony_ci};
1055e5c12b0Sopenharmony_ci
1065e5c12b0Sopenharmony_ci/*
1075e5c12b0Sopenharmony_ci * Copy dqinfo from disk to memory
1085e5c12b0Sopenharmony_ci */
1095e5c12b0Sopenharmony_cistatic inline void v2_disk2memdqinfo(struct util_dqinfo *m,
1105e5c12b0Sopenharmony_ci				     struct v2_disk_dqinfo *d)
1115e5c12b0Sopenharmony_ci{
1125e5c12b0Sopenharmony_ci	m->dqi_bgrace = le32_to_cpu(d->dqi_bgrace);
1135e5c12b0Sopenharmony_ci	m->dqi_igrace = le32_to_cpu(d->dqi_igrace);
1145e5c12b0Sopenharmony_ci	m->u.v2_mdqi.dqi_flags = le32_to_cpu(d->dqi_flags) & V2_DQF_MASK;
1155e5c12b0Sopenharmony_ci	m->u.v2_mdqi.dqi_qtree.dqi_blocks = le32_to_cpu(d->dqi_blocks);
1165e5c12b0Sopenharmony_ci	m->u.v2_mdqi.dqi_qtree.dqi_free_blk =
1175e5c12b0Sopenharmony_ci		le32_to_cpu(d->dqi_free_blk);
1185e5c12b0Sopenharmony_ci	m->u.v2_mdqi.dqi_qtree.dqi_free_entry =
1195e5c12b0Sopenharmony_ci				le32_to_cpu(d->dqi_free_entry);
1205e5c12b0Sopenharmony_ci}
1215e5c12b0Sopenharmony_ci
1225e5c12b0Sopenharmony_ci/*
1235e5c12b0Sopenharmony_ci * Copy dqinfo from memory to disk
1245e5c12b0Sopenharmony_ci */
1255e5c12b0Sopenharmony_cistatic inline void v2_mem2diskdqinfo(struct v2_disk_dqinfo *d,
1265e5c12b0Sopenharmony_ci				     struct util_dqinfo *m)
1275e5c12b0Sopenharmony_ci{
1285e5c12b0Sopenharmony_ci	d->dqi_bgrace = cpu_to_le32(m->dqi_bgrace);
1295e5c12b0Sopenharmony_ci	d->dqi_igrace = cpu_to_le32(m->dqi_igrace);
1305e5c12b0Sopenharmony_ci	d->dqi_flags = cpu_to_le32(m->u.v2_mdqi.dqi_flags & V2_DQF_MASK);
1315e5c12b0Sopenharmony_ci	d->dqi_blocks = cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_blocks);
1325e5c12b0Sopenharmony_ci	d->dqi_free_blk =
1335e5c12b0Sopenharmony_ci		cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_free_blk);
1345e5c12b0Sopenharmony_ci	d->dqi_free_entry =
1355e5c12b0Sopenharmony_ci		cpu_to_le32(m->u.v2_mdqi.dqi_qtree.dqi_free_entry);
1365e5c12b0Sopenharmony_ci}
1375e5c12b0Sopenharmony_ci
1385e5c12b0Sopenharmony_cistatic int v2_read_header(struct quota_handle *h, struct v2_disk_dqheader *dqh)
1395e5c12b0Sopenharmony_ci{
1405e5c12b0Sopenharmony_ci	if (h->read(&h->qh_qf, 0, dqh, sizeof(struct v2_disk_dqheader)) !=
1415e5c12b0Sopenharmony_ci			sizeof(struct v2_disk_dqheader))
1425e5c12b0Sopenharmony_ci		return 0;
1435e5c12b0Sopenharmony_ci
1445e5c12b0Sopenharmony_ci	return 1;
1455e5c12b0Sopenharmony_ci}
1465e5c12b0Sopenharmony_ci
1475e5c12b0Sopenharmony_ci/*
1485e5c12b0Sopenharmony_ci * Check whether given quota file is in our format
1495e5c12b0Sopenharmony_ci */
1505e5c12b0Sopenharmony_cistatic int v2_check_file(struct quota_handle *h, int type)
1515e5c12b0Sopenharmony_ci{
1525e5c12b0Sopenharmony_ci	struct v2_disk_dqheader dqh;
1535e5c12b0Sopenharmony_ci	int file_magics[] = INITQMAGICS;
1545e5c12b0Sopenharmony_ci	int be_magic;
1555e5c12b0Sopenharmony_ci
1565e5c12b0Sopenharmony_ci	if (!v2_read_header(h, &dqh))
1575e5c12b0Sopenharmony_ci		return 0;
1585e5c12b0Sopenharmony_ci
1595e5c12b0Sopenharmony_ci	be_magic = be32_to_cpu((__force __be32)dqh.dqh_magic);
1605e5c12b0Sopenharmony_ci	if (be_magic == file_magics[type]) {
1615e5c12b0Sopenharmony_ci		log_err("Your quota file is stored in wrong endianity");
1625e5c12b0Sopenharmony_ci		return 0;
1635e5c12b0Sopenharmony_ci	}
1645e5c12b0Sopenharmony_ci	if (V2_VERSION != le32_to_cpu(dqh.dqh_version))
1655e5c12b0Sopenharmony_ci		return 0;
1665e5c12b0Sopenharmony_ci	return 1;
1675e5c12b0Sopenharmony_ci}
1685e5c12b0Sopenharmony_ci
1695e5c12b0Sopenharmony_ci/*
1705e5c12b0Sopenharmony_ci * Open quotafile
1715e5c12b0Sopenharmony_ci */
1725e5c12b0Sopenharmony_cistatic int v2_init_io(struct quota_handle *h, enum quota_type qtype)
1735e5c12b0Sopenharmony_ci{
1745e5c12b0Sopenharmony_ci	struct v2_disk_dqinfo ddqinfo;
1755e5c12b0Sopenharmony_ci	struct v2_mem_dqinfo *info;
1765e5c12b0Sopenharmony_ci	u64 filesize;
1775e5c12b0Sopenharmony_ci	struct quota_file *qf = &h->qh_qf;
1785e5c12b0Sopenharmony_ci	u32 last_blkofs = qf_last_blkofs[qtype];
1795e5c12b0Sopenharmony_ci
1805e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size =
1815e5c12b0Sopenharmony_ci		sizeof(struct v2r1_disk_dqblk);
1825e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_ops = &v2r1_fmt_ops;
1835e5c12b0Sopenharmony_ci
1845e5c12b0Sopenharmony_ci	/* Read information about quotafile */
1855e5c12b0Sopenharmony_ci	if (h->read(qf, V2_DQINFOOFF, &ddqinfo,
1865e5c12b0Sopenharmony_ci			sizeof(ddqinfo)) != sizeof(ddqinfo))
1875e5c12b0Sopenharmony_ci		return -1;
1885e5c12b0Sopenharmony_ci	v2_disk2memdqinfo(&h->qh_info, &ddqinfo);
1895e5c12b0Sopenharmony_ci
1905e5c12b0Sopenharmony_ci	/* Check to make sure quota file info is sane */
1915e5c12b0Sopenharmony_ci	info = &h->qh_info.u.v2_mdqi;
1925e5c12b0Sopenharmony_ci	filesize = qf->filesize = f2fs_quota_size(qf);
1935e5c12b0Sopenharmony_ci	if (qf_szchk_type[qtype] == QF_SZCHK_REGFILE &&
1945e5c12b0Sopenharmony_ci			((filesize + F2FS_BLKSIZE - 1) >> F2FS_BLKSIZE_BITS <
1955e5c12b0Sopenharmony_ci			last_blkofs + 1 || filesize > qf_maxsize[qtype])) {
1965e5c12b0Sopenharmony_ci		/*
1975e5c12b0Sopenharmony_ci		 * reqular: qf_szchk is now the last block index,
1985e5c12b0Sopenharmony_ci		 * including the hole's index
1995e5c12b0Sopenharmony_ci		 */
2005e5c12b0Sopenharmony_ci		log_err("Quota inode %u corrupted: file size %" PRIu64
2015e5c12b0Sopenharmony_ci			" does not match page offset %" PRIu32,
2025e5c12b0Sopenharmony_ci			h->qh_qf.ino,
2035e5c12b0Sopenharmony_ci			filesize,
2045e5c12b0Sopenharmony_ci			last_blkofs);
2055e5c12b0Sopenharmony_ci		filesize = (last_blkofs + 1) << F2FS_BLKSIZE_BITS;
2065e5c12b0Sopenharmony_ci		f2fs_filesize_update(qf->sbi, qf->ino, filesize);
2075e5c12b0Sopenharmony_ci	}
2085e5c12b0Sopenharmony_ci
2095e5c12b0Sopenharmony_ci	if ((info->dqi_qtree.dqi_blocks >
2105e5c12b0Sopenharmony_ci			(filesize + QT_BLKSIZE - 1) >> QT_BLKSIZE_BITS)) {
2115e5c12b0Sopenharmony_ci		log_err("Quota inode %u corrupted: file size %" PRId64 "; "
2125e5c12b0Sopenharmony_ci				"dqi_blocks %u", h->qh_qf.ino,
2135e5c12b0Sopenharmony_ci				filesize, info->dqi_qtree.dqi_blocks);
2145e5c12b0Sopenharmony_ci		return -1;
2155e5c12b0Sopenharmony_ci	}
2165e5c12b0Sopenharmony_ci	if (info->dqi_qtree.dqi_free_blk >= info->dqi_qtree.dqi_blocks) {
2175e5c12b0Sopenharmony_ci		log_err("Quota inode %u corrupted: free_blk %u;"
2185e5c12b0Sopenharmony_ci				" dqi_blocks %u",
2195e5c12b0Sopenharmony_ci				h->qh_qf.ino, info->dqi_qtree.dqi_free_blk,
2205e5c12b0Sopenharmony_ci				info->dqi_qtree.dqi_blocks);
2215e5c12b0Sopenharmony_ci		return -1;
2225e5c12b0Sopenharmony_ci	}
2235e5c12b0Sopenharmony_ci	if (info->dqi_qtree.dqi_free_entry >= info->dqi_qtree.dqi_blocks) {
2245e5c12b0Sopenharmony_ci		log_err("Quota inode %u corrupted: free_entry %u; "
2255e5c12b0Sopenharmony_ci				"dqi_blocks %u", h->qh_qf.ino,
2265e5c12b0Sopenharmony_ci				info->dqi_qtree.dqi_free_entry,
2275e5c12b0Sopenharmony_ci				info->dqi_qtree.dqi_blocks);
2285e5c12b0Sopenharmony_ci		return -1;
2295e5c12b0Sopenharmony_ci	}
2305e5c12b0Sopenharmony_ci	return 0;
2315e5c12b0Sopenharmony_ci}
2325e5c12b0Sopenharmony_ci
2335e5c12b0Sopenharmony_ci/*
2345e5c12b0Sopenharmony_ci * Initialize new quotafile
2355e5c12b0Sopenharmony_ci */
2365e5c12b0Sopenharmony_cistatic int v2_new_io(struct quota_handle *h)
2375e5c12b0Sopenharmony_ci{
2385e5c12b0Sopenharmony_ci	int file_magics[] = INITQMAGICS;
2395e5c12b0Sopenharmony_ci	struct v2_disk_dqheader ddqheader;
2405e5c12b0Sopenharmony_ci	struct v2_disk_dqinfo ddqinfo;
2415e5c12b0Sopenharmony_ci
2425e5c12b0Sopenharmony_ci	if (h->qh_fmt != QFMT_VFS_V1)
2435e5c12b0Sopenharmony_ci		return -1;
2445e5c12b0Sopenharmony_ci
2455e5c12b0Sopenharmony_ci	/* Write basic quota header */
2465e5c12b0Sopenharmony_ci	ddqheader.dqh_magic = cpu_to_le32(file_magics[h->qh_type]);
2475e5c12b0Sopenharmony_ci	ddqheader.dqh_version = cpu_to_le32(V2_VERSION);
2485e5c12b0Sopenharmony_ci	if (h->write(&h->qh_qf, 0, &ddqheader, sizeof(ddqheader)) !=
2495e5c12b0Sopenharmony_ci			sizeof(ddqheader))
2505e5c12b0Sopenharmony_ci		return -1;
2515e5c12b0Sopenharmony_ci
2525e5c12b0Sopenharmony_ci	/* Write information about quotafile */
2535e5c12b0Sopenharmony_ci	h->qh_info.dqi_bgrace = MAX_DQ_TIME;
2545e5c12b0Sopenharmony_ci	h->qh_info.dqi_igrace = MAX_IQ_TIME;
2555e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_flags = 0;
2565e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks = QT_TREEOFF + 1;
2575e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_free_blk = 0;
2585e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_free_entry = 0;
2595e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size =
2605e5c12b0Sopenharmony_ci				sizeof(struct v2r1_disk_dqblk);
2615e5c12b0Sopenharmony_ci	h->qh_info.u.v2_mdqi.dqi_qtree.dqi_ops = &v2r1_fmt_ops;
2625e5c12b0Sopenharmony_ci	v2_mem2diskdqinfo(&ddqinfo, &h->qh_info);
2635e5c12b0Sopenharmony_ci	if (h->write(&h->qh_qf, V2_DQINFOOFF, &ddqinfo,
2645e5c12b0Sopenharmony_ci			  sizeof(ddqinfo)) !=
2655e5c12b0Sopenharmony_ci	    sizeof(ddqinfo))
2665e5c12b0Sopenharmony_ci		return -1;
2675e5c12b0Sopenharmony_ci
2685e5c12b0Sopenharmony_ci	return 0;
2695e5c12b0Sopenharmony_ci}
2705e5c12b0Sopenharmony_ci
2715e5c12b0Sopenharmony_ci/*
2725e5c12b0Sopenharmony_ci * Write information (grace times to file)
2735e5c12b0Sopenharmony_ci */
2745e5c12b0Sopenharmony_cistatic int v2_write_info(struct quota_handle *h)
2755e5c12b0Sopenharmony_ci{
2765e5c12b0Sopenharmony_ci	struct v2_disk_dqinfo ddqinfo;
2775e5c12b0Sopenharmony_ci
2785e5c12b0Sopenharmony_ci	v2_mem2diskdqinfo(&ddqinfo, &h->qh_info);
2795e5c12b0Sopenharmony_ci	if (h->write(&h->qh_qf, V2_DQINFOOFF, &ddqinfo, sizeof(ddqinfo)) !=
2805e5c12b0Sopenharmony_ci			sizeof(ddqinfo))
2815e5c12b0Sopenharmony_ci		return -1;
2825e5c12b0Sopenharmony_ci
2835e5c12b0Sopenharmony_ci	return 0;
2845e5c12b0Sopenharmony_ci}
2855e5c12b0Sopenharmony_ci
2865e5c12b0Sopenharmony_ci/*
2875e5c12b0Sopenharmony_ci * Read dquot from disk
2885e5c12b0Sopenharmony_ci */
2895e5c12b0Sopenharmony_cistatic struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id)
2905e5c12b0Sopenharmony_ci{
2915e5c12b0Sopenharmony_ci	return qtree_read_dquot(h, id);
2925e5c12b0Sopenharmony_ci}
2935e5c12b0Sopenharmony_ci
2945e5c12b0Sopenharmony_ci/*
2955e5c12b0Sopenharmony_ci * Commit changes of dquot to disk - it might also mean deleting it when quota
2965e5c12b0Sopenharmony_ci * became fake one and user has no blocks.
2975e5c12b0Sopenharmony_ci * User can process use 'errno' to detect errstr.
2985e5c12b0Sopenharmony_ci */
2995e5c12b0Sopenharmony_cistatic int v2_commit_dquot(struct dquot *dquot)
3005e5c12b0Sopenharmony_ci{
3015e5c12b0Sopenharmony_ci	struct util_dqblk *b = &dquot->dq_dqb;
3025e5c12b0Sopenharmony_ci
3035e5c12b0Sopenharmony_ci	if (!b->dqb_curspace && !b->dqb_curinodes && !b->dqb_bsoftlimit &&
3045e5c12b0Sopenharmony_ci	    !b->dqb_isoftlimit && !b->dqb_bhardlimit && !b->dqb_ihardlimit)
3055e5c12b0Sopenharmony_ci	{
3065e5c12b0Sopenharmony_ci		qtree_delete_dquot(dquot);
3075e5c12b0Sopenharmony_ci	} else {
3085e5c12b0Sopenharmony_ci		return qtree_write_dquot(dquot);
3095e5c12b0Sopenharmony_ci	}
3105e5c12b0Sopenharmony_ci	return 0;
3115e5c12b0Sopenharmony_ci}
3125e5c12b0Sopenharmony_ci
3135e5c12b0Sopenharmony_cistatic int v2_scan_dquots(struct quota_handle *h,
3145e5c12b0Sopenharmony_ci			  int (*process_dquot) (struct dquot *, void *),
3155e5c12b0Sopenharmony_ci			  void *data)
3165e5c12b0Sopenharmony_ci{
3175e5c12b0Sopenharmony_ci	return qtree_scan_dquots(h, process_dquot, data);
3185e5c12b0Sopenharmony_ci}
3195e5c12b0Sopenharmony_ci
3205e5c12b0Sopenharmony_ci/* Report information about quotafile.
3215e5c12b0Sopenharmony_ci * TODO: Not used right now, but we should be able to use this when we add
3225e5c12b0Sopenharmony_ci * support to debugfs to read quota files.
3235e5c12b0Sopenharmony_ci */
3245e5c12b0Sopenharmony_cistatic int v2_report(struct quota_handle *UNUSED(h), int UNUSED(verbose))
3255e5c12b0Sopenharmony_ci{
3265e5c12b0Sopenharmony_ci	log_err("Not Implemented.");
3275e5c12b0Sopenharmony_ci	return -1;
3285e5c12b0Sopenharmony_ci}
329