11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	vfsv0 quota IO operations on file
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mount.h>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/dqblk_v2.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
1374abb9890dafb12a50dc140de215ed477beb1b88Jan Kara#include <linux/quotaops.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara#include "quota_tree.h"
18cf770c137122b78470a67ebd5498947869a09197Jan Kara#include "quotaio_v2.h"
19cf770c137122b78470a67ebd5498947869a09197Jan Kara
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Jan Kara");
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Quota format v2 support");
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __QUOTA_V2_PARANOIA
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r0_mem2diskdqb(void *dp, struct dquot *dquot);
27498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r0_disk2memdqb(struct dquot *dquot, void *dp);
28498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic int v2r0_is_id(void *dp, struct dquot *dquot);
29498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
30498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
31498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic int v2r1_is_id(void *dp, struct dquot *dquot);
32498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
33498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic struct qtree_fmt_operations v2r0_qtree_ops = {
34498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.mem2disk_dqblk = v2r0_mem2diskdqb,
35498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.disk2mem_dqblk = v2r0_disk2memdqb,
36498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.is_id = v2r0_is_id,
37498c60153ebb8889d8944591383c5c12af1127d4Jan Kara};
38498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
39498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic struct qtree_fmt_operations v2r1_qtree_ops = {
40498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.mem2disk_dqblk = v2r1_mem2diskdqb,
41498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.disk2mem_dqblk = v2r1_disk2memdqb,
42498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.is_id = v2r1_is_id,
431ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara};
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4512095460f7f315f8ef67a55b2194195d325d48d7Jan Kara#define QUOTABLOCK_BITS 10
4612095460f7f315f8ef67a55b2194195d325d48d7Jan Kara#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
4712095460f7f315f8ef67a55b2194195d325d48d7Jan Kara
4812095460f7f315f8ef67a55b2194195d325d48d7Jan Karastatic inline qsize_t v2_stoqb(qsize_t space)
4912095460f7f315f8ef67a55b2194195d325d48d7Jan Kara{
5012095460f7f315f8ef67a55b2194195d325d48d7Jan Kara	return (space + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS;
5112095460f7f315f8ef67a55b2194195d325d48d7Jan Kara}
5212095460f7f315f8ef67a55b2194195d325d48d7Jan Kara
5312095460f7f315f8ef67a55b2194195d325d48d7Jan Karastatic inline qsize_t v2_qbtos(qsize_t blocks)
5412095460f7f315f8ef67a55b2194195d325d48d7Jan Kara{
5512095460f7f315f8ef67a55b2194195d325d48d7Jan Kara	return blocks << QUOTABLOCK_BITS;
5612095460f7f315f8ef67a55b2194195d325d48d7Jan Kara}
5712095460f7f315f8ef67a55b2194195d325d48d7Jan Kara
58498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic int v2_read_header(struct super_block *sb, int type,
59498c60153ebb8889d8944591383c5c12af1127d4Jan Kara			  struct v2_disk_dqheader *dqhead)
60498c60153ebb8889d8944591383c5c12af1127d4Jan Kara{
61498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	ssize_t size;
62498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
63498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	size = sb->s_op->quota_read(sb, type, (char *)dqhead,
64498c60153ebb8889d8944591383c5c12af1127d4Jan Kara				    sizeof(struct v2_disk_dqheader), 0);
65498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (size != sizeof(struct v2_disk_dqheader)) {
66fb5ffb0e160c93c3fe08ab83845eb9a2768af812Jiaying Zhang		quota_error(sb, "Failed header read: expected=%zd got=%zd",
67fb5ffb0e160c93c3fe08ab83845eb9a2768af812Jiaying Zhang			    sizeof(struct v2_disk_dqheader), size);
68498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		return 0;
69498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	}
70498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	return 1;
71498c60153ebb8889d8944591383c5c12af1127d4Jan Kara}
72498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Check whether given file is really vfsv0 quotafile */
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v2_check_quota_file(struct super_block *sb, int type)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct v2_disk_dqheader dqhead;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static const uint quota_magics[] = V2_INITQMAGICS;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static const uint quota_versions[] = V2_INITQVERSIONS;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (!v2_read_header(sb, type, &dqhead))
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
83498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	    le32_to_cpu(dqhead.dqh_version) > quota_versions[type])
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Read information header from quota file */
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v2_read_file_info(struct super_block *sb, int type)
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct v2_disk_dqinfo dinfo;
92498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2_disk_dqheader dqhead;
931ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct mem_dqinfo *info = sb_dqinfo(sb, type);
94e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	struct qtree_mem_dqinfo *qinfo;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ssize_t size;
96498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	unsigned int version;
97498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
98498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (!v2_read_header(sb, type, &dqhead))
99869835dfad3eb6f7d90c3255a24b084fea82f30dJan Kara		return -1;
100498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	version = le32_to_cpu(dqhead.dqh_version);
101869835dfad3eb6f7d90c3255a24b084fea82f30dJan Kara	if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) ||
102869835dfad3eb6f7d90c3255a24b084fea82f30dJan Kara	    (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1))
103869835dfad3eb6f7d90c3255a24b084fea82f30dJan Kara		return -1;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (size != sizeof(struct v2_disk_dqinfo)) {
108fb5ffb0e160c93c3fe08ab83845eb9a2768af812Jiaying Zhang		quota_error(sb, "Can't read info structure");
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
111e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS);
112e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	if (!info->dqi_priv) {
113e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara		printk(KERN_WARNING
114e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara		       "Not enough memory for quota information structure.\n");
1157a39de1510a3fd07a77530440292735d305fe510Davidlohr Bueso		return -ENOMEM;
116e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	}
117e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo = info->dqi_priv;
118498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (version == 0) {
119498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		/* limits are stored as unsigned 32-bit data */
120498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		info->dqi_maxblimit = 0xffffffff;
121498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		info->dqi_maxilimit = 0xffffffff;
122498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	} else {
123498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		/* used space is stored as unsigned 64-bit value */
12482fdfa928cfa19d9627526b2ce164a27f8e9d34bJan Kara		info->dqi_maxblimit = 0xffffffffffffffffULL;	/* 2^64-1 */
12582fdfa928cfa19d9627526b2ce164a27f8e9d34bJan Kara		info->dqi_maxilimit = 0xffffffffffffffffULL;
126498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
130e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_sb = sb;
131e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_type = type;
132e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
133e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
134e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
135e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_blocksize_bits = V2_DQBLKSIZE_BITS;
136e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_usable_bs = 1 << V2_DQBLKSIZE_BITS;
137e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	qinfo->dqi_qtree_depth = qtree_depth(qinfo);
138498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (version == 0) {
139498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		qinfo->dqi_entry_size = sizeof(struct v2r0_disk_dqblk);
140498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		qinfo->dqi_ops = &v2r0_qtree_ops;
141498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	} else {
142498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
143498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		qinfo->dqi_ops = &v2r1_qtree_ops;
144498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	}
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Write information header to quota file */
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v2_write_file_info(struct super_block *sb, int type)
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct v2_disk_dqinfo dinfo;
1521ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct mem_dqinfo *info = sb_dqinfo(sb, type);
153e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	struct qtree_mem_dqinfo *qinfo = info->dqi_priv;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ssize_t size;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock(&dq_data_lock);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->dqi_flags &= ~DQF_INFO_DIRTY;
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock(&dq_data_lock);
162e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	dinfo.dqi_blocks = cpu_to_le32(qinfo->dqi_blocks);
163e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	dinfo.dqi_free_blk = cpu_to_le32(qinfo->dqi_free_blk);
164e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	dinfo.dqi_free_entry = cpu_to_le32(qinfo->dqi_free_entry);
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (size != sizeof(struct v2_disk_dqinfo)) {
168fb5ffb0e160c93c3fe08ab83845eb9a2768af812Jiaying Zhang		quota_error(sb, "Can't write info structure");
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
174498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r0_disk2memdqb(struct dquot *dquot, void *dp)
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
176498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r0_disk_dqblk *d = dp, empty;
1771ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct mem_dqblk *m = &dquot->dq_dqb;
1781ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_itime = le64_to_cpu(d->dqb_itime);
18312095460f7f315f8ef67a55b2194195d325d48d7Jan Kara	m->dqb_bhardlimit = v2_qbtos(le32_to_cpu(d->dqb_bhardlimit));
18412095460f7f315f8ef67a55b2194195d325d48d7Jan Kara	m->dqb_bsoftlimit = v2_qbtos(le32_to_cpu(d->dqb_bsoftlimit));
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	m->dqb_btime = le64_to_cpu(d->dqb_btime);
1871ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	/* We need to escape back all-zero structure */
188498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	memset(&empty, 0, sizeof(struct v2r0_disk_dqblk));
1891ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	empty.dqb_itime = cpu_to_le64(1);
190498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (!memcmp(&empty, dp, sizeof(struct v2r0_disk_dqblk)))
1911ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara		m->dqb_itime = 0;
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
194498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r0_mem2diskdqb(void *dp, struct dquot *dquot)
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
196498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r0_disk_dqblk *d = dp;
1971ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct mem_dqblk *m = &dquot->dq_dqb;
1981ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct qtree_mem_dqinfo *info =
1994c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
2001ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_itime = cpu_to_le64(m->dqb_itime);
205cf770c137122b78470a67ebd5498947869a09197Jan Kara	d->dqb_bhardlimit = cpu_to_le32(v2_stoqb(m->dqb_bhardlimit));
206cf770c137122b78470a67ebd5498947869a09197Jan Kara	d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit));
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d->dqb_btime = cpu_to_le64(m->dqb_btime);
2094c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
2101ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	if (qtree_entry_unused(info, dp))
2111ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara		d->dqb_itime = cpu_to_le64(1);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
214498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic int v2r0_is_id(void *dp, struct dquot *dquot)
215498c60153ebb8889d8944591383c5c12af1127d4Jan Kara{
216498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r0_disk_dqblk *d = dp;
217498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct qtree_mem_dqinfo *info =
2184c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
219498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
220498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (qtree_entry_unused(info, dp))
221498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		return 0;
2224c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
2234c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman				le32_to_cpu(d->dqb_id)),
2244c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman		      dquot->dq_id);
225498c60153ebb8889d8944591383c5c12af1127d4Jan Kara}
226498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
227498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r1_disk2memdqb(struct dquot *dquot, void *dp)
228498c60153ebb8889d8944591383c5c12af1127d4Jan Kara{
229498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r1_disk_dqblk *d = dp, empty;
230498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct mem_dqblk *m = &dquot->dq_dqb;
231498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
232498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
233498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
234498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
235498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_itime = le64_to_cpu(d->dqb_itime);
236498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_bhardlimit = v2_qbtos(le64_to_cpu(d->dqb_bhardlimit));
237498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_bsoftlimit = v2_qbtos(le64_to_cpu(d->dqb_bsoftlimit));
238498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
239498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	m->dqb_btime = le64_to_cpu(d->dqb_btime);
240498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	/* We need to escape back all-zero structure */
241498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	memset(&empty, 0, sizeof(struct v2r1_disk_dqblk));
242498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	empty.dqb_itime = cpu_to_le64(1);
243498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (!memcmp(&empty, dp, sizeof(struct v2r1_disk_dqblk)))
244498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		m->dqb_itime = 0;
245498c60153ebb8889d8944591383c5c12af1127d4Jan Kara}
246498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
247498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
248498c60153ebb8889d8944591383c5c12af1127d4Jan Kara{
249498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r1_disk_dqblk *d = dp;
250498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct mem_dqblk *m = &dquot->dq_dqb;
251498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct qtree_mem_dqinfo *info =
2524c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
253498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
254498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
255498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
256498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
257498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_itime = cpu_to_le64(m->dqb_itime);
258498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
259498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
260498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
261498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	d->dqb_btime = cpu_to_le64(m->dqb_btime);
2624c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
263498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (qtree_entry_unused(info, dp))
264498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		d->dqb_itime = cpu_to_le64(1);
265498c60153ebb8889d8944591383c5c12af1127d4Jan Kara}
266498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
267498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic int v2r1_is_id(void *dp, struct dquot *dquot)
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
269498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	struct v2r1_disk_dqblk *d = dp;
2701ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	struct qtree_mem_dqinfo *info =
2714c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Kara	if (qtree_entry_unused(info, dp))
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2754c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
2764c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman				le32_to_cpu(d->dqb_id)),
2774c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman		      dquot->dq_id);
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801ccd14b9c271c1ac6eec5c5ec5def433100e7248Jan Karastatic int v2_read_dquot(struct dquot *dquot)
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2824c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	return qtree_read_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot);
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v2_write_dquot(struct dquot *dquot)
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2874c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot);
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int v2_release_dquot(struct dquot *dquot)
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2924c376dcae892e5b5daf8576c864061d076d4e4dcEric W. Biederman	return qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot);
293e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara}
294e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara
295e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Karastatic int v2_free_file_info(struct super_block *sb, int type)
296e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara{
297e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	kfree(sb_dqinfo(sb, type)->dqi_priv);
298e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	return 0;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3011472da5fdc65f0cd286c655758d629346001e126Alexey Dobriyanstatic const struct quota_format_ops v2_format_ops = {
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.check_quota_file	= v2_check_quota_file,
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.read_file_info		= v2_read_file_info,
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.write_file_info	= v2_write_file_info,
305e3d4d56b9715e40ded2a84d0d4fa7f3b6c58983cJan Kara	.free_file_info		= v2_free_file_info,
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.read_dqblk		= v2_read_dquot,
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.commit_dqblk		= v2_write_dquot,
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.release_dqblk		= v2_release_dquot,
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic struct quota_format_type v2r0_quota_format = {
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.qf_fmt_id	= QFMT_VFS_V0,
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.qf_ops		= &v2_format_ops,
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.qf_owner	= THIS_MODULE
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
317498c60153ebb8889d8944591383c5c12af1127d4Jan Karastatic struct quota_format_type v2r1_quota_format = {
318498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.qf_fmt_id	= QFMT_VFS_V1,
319498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.qf_ops		= &v2_format_ops,
320498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	.qf_owner	= THIS_MODULE
321498c60153ebb8889d8944591383c5c12af1127d4Jan Kara};
322498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init init_v2_quota_format(void)
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
325498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	int ret;
326498c60153ebb8889d8944591383c5c12af1127d4Jan Kara
327498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	ret = register_quota_format(&v2r0_quota_format);
328498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	if (ret)
329498c60153ebb8889d8944591383c5c12af1127d4Jan Kara		return ret;
330498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	return register_quota_format(&v2r1_quota_format);
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit exit_v2_quota_format(void)
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
335498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	unregister_quota_format(&v2r0_quota_format);
336498c60153ebb8889d8944591383c5c12af1127d4Jan Kara	unregister_quota_format(&v2r1_quota_format);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(init_v2_quota_format);
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(exit_v2_quota_format);
341