/*
 *	vfsv0 quota IO operations on file
 */

#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/dqblk_v2.h>
#include <linux/quotaio_v2.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <asm/byteorder.h>

MODULE_AUTHOR("Jan Kara");
MODULE_DESCRIPTION("Quota format v2 support");
MODULE_LICENSE("GPL");

#define __QUOTA_V2_PARANOIA

typedef char *dqbuf_t;

#define GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
#define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))

/* Check whether given file is really vfsv0 quotafile */
static int v2_check_quota_file(struct super_block *sb, int type)
{
	struct v2_disk_dqheader dqhead;
	ssize_t size;
	static const uint quota_magics[] = V2_INITQMAGICS;
	static const uint quota_versions[] = V2_INITQVERSIONS;
 
	size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
	if (size != sizeof(struct v2_disk_dqheader)) {
		printk("failed read\n");
		return 0;
	}
	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
	    le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
		return 0;
	return 1;
}

/* Read information header from quota file */
static int v2_read_file_info(struct super_block *sb, int type)
{
	struct v2_disk_dqinfo dinfo;
	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
	ssize_t size;

	size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
	if (size != sizeof(struct v2_disk_dqinfo)) {
		printk(KERN_WARNING "Can't read info structure on device %s.\n",
			sb->s_id);
		return -1;
	}
	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
	info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
	info->u.v2_i.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
	info->u.v2_i.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
	info->u.v2_i.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
	return 0;
}

/* Write information header to quota file */
static int v2_write_file_info(struct super_block *sb, int type)
{
	struct v2_disk_dqinfo dinfo;
	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
	ssize_t size;

	spin_lock(&dq_data_lock);
	info->dqi_flags &= ~DQF_INFO_DIRTY;
	dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
	dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
	dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
	spin_unlock(&dq_data_lock);
	dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
	dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
	dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
	size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
	       sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
	if (size != sizeof(struct v2_disk_dqinfo)) {
		printk(KERN_WARNING "Can't write info structure on device %s.\n",
			sb->s_id);
		return -1;
	}
	return 0;
}

static void disk2memdqb(struct mem_dqblk *m, struct v2_disk_dqblk *d)
{
	m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
	m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
	m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
	m->dqb_itime = le64_to_cpu(d->dqb_itime);
	m->dqb_bhardlimit = le32_to_cpu(d->dqb_bhardlimit);
	m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit);
	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
	m->dqb_btime = le64_to_cpu(d->dqb_btime);
}

static void mem2diskdqb(struct v2_disk_dqblk *d, struct mem_dqblk *m, qid_t id)
{
	d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
	d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
	d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
	d->dqb_itime = cpu_to_le64(m->dqb_itime);
	d->dqb_bhardlimit = cpu_to_le32(m->dqb_bhardlimit);
	d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit);
	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
	d->dqb_btime = cpu_to_le64(m->dqb_btime);
	d->dqb_id = cpu_to_le32(id);
}

static dqbuf_t getdqbuf(void)
{
	dqbuf_t buf = kmalloc(V2_DQBLKSIZE, GFP_NOFS);
	if (!buf)
		printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
	return buf;
}

static inline void freedqbuf(dqbuf_t buf)
{
	kfree(buf);
}

static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
{
	memset(buf, 0, V2_DQBLKSIZE);
	return sb->s_op->quota_read(sb, type, (char *)buf,
	       V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
}

static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
{
	return sb->s_op->quota_write(sb, type, (char *)buf,
	       V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
}

/* Remove empty block from list and return it */
static int get_free_dqblk(struct super_block *sb, int type)
{
	dqbuf_t buf = getdqbuf();
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
	int ret, blk;

	if (!buf)
		return -ENOMEM;
	if (info->u.v2_i.dqi_free_blk) {
		blk = info->u.v2_i.dqi_free_blk;
		if ((ret = read_blk(sb, type, blk, buf)) < 0)
			goto out_buf;
		info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
	}
	else {
		memset(buf, 0, V2_DQBLKSIZE);
		/* Assure block allocation... */
		if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
			goto out_buf;
		blk = info->u.v2_i.dqi_blocks++;
	}
	mark_info_dirty(sb, type);
	ret = blk;
out_buf:
	freedqbuf(buf);
	return ret;
}

/* Insert empty block to the list */
static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
	int err;

	dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_blk);
	dh->dqdh_prev_free = cpu_to_le32(0);
	dh->dqdh_entries = cpu_to_le16(0);
	info->u.v2_i.dqi_free_blk = blk;
	mark_info_dirty(sb, type);
	/* Some strange block. We had better leave it... */
	if ((err = write_blk(sb, type, blk, buf)) < 0)
		return err;
	return 0;
}

/* Remove given block from the list of blocks with free entries */
static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
{
	dqbuf_t tmpbuf = getdqbuf();
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
	uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
	int err;

	if (!tmpbuf)
		return -ENOMEM;
	if (nextblk) {
		if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
			goto out_buf;
		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
		if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
			goto out_buf;
	}
	if (prevblk) {
		if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
			goto out_buf;
		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
		if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
			goto out_buf;
	}
	else {
		info->u.v2_i.dqi_free_entry = nextblk;
		mark_info_dirty(sb, type);
	}
	freedqbuf(tmpbuf);
	dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
	/* No matter whether write succeeds block is out of list */
	if (write_blk(sb, type, blk, buf) < 0)
		printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
	return 0;
out_buf:
	freedqbuf(tmpbuf);
	return err;
}

/* Insert given block to the beginning of list with free entries */
static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
{
	dqbuf_t tmpbuf = getdqbuf();
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
	int err;

	if (!tmpbuf)
		return -ENOMEM;
	dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
	dh->dqdh_prev_free = cpu_to_le32(0);
	if ((err = write_blk(sb, type, blk, buf)) < 0)
		goto out_buf;
	if (info->u.v2_i.dqi_free_entry) {
		if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
			goto out_buf;
		((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
		if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
			goto out_buf;
	}
	freedqbuf(tmpbuf);
	info->u.v2_i.dqi_free_entry = blk;
	mark_info_dirty(sb, type);
	return 0;
out_buf:
	freedqbuf(tmpbuf);
	return err;
}

/* Find space for dquot */
static uint find_free_dqentry(struct dquot *dquot, int *err)
{
	struct super_block *sb = dquot->dq_sb;
	struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
	uint blk, i;
	struct v2_disk_dqdbheader *dh;
	struct v2_disk_dqblk *ddquot;
	struct v2_disk_dqblk fakedquot;
	dqbuf_t buf;

	*err = 0;
	if (!(buf = getdqbuf())) {
		*err = -ENOMEM;
		return 0;
	}
	dh = (struct v2_disk_dqdbheader *)buf;
	ddquot = GETENTRIES(buf);
	if (info->u.v2_i.dqi_free_entry) {
		blk = info->u.v2_i.dqi_free_entry;
		if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
			goto out_buf;
	}
	else {
		blk = get_free_dqblk(sb, dquot->dq_type);
		if ((int)blk < 0) {
			*err = blk;
			freedqbuf(buf);
			return 0;
		}
		memset(buf, 0, V2_DQBLKSIZE);
		/* This is enough as block is already zeroed and entry list is empty... */
		info->u.v2_i.dqi_free_entry = blk;
		mark_info_dirty(sb, dquot->dq_type);
	}
	if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK)	/* Block will be full? */
		if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
			printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
			goto out_buf;
		}
	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)+1);
	memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
	/* Find free structure in block */
	for (i = 0; i < V2_DQSTRINBLK && memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)); i++);
#ifdef __QUOTA_V2_PARANOIA
	if (i == V2_DQSTRINBLK) {
		printk(KERN_ERR "VFS: find_free_dqentry(): Data block full but it shouldn't.\n");
		*err = -EIO;
		goto out_buf;
	}
#endif
	if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
		printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
		goto out_buf;
	}
	dquot->dq_off = (blk<<V2_DQBLKSIZE_BITS)+sizeof(struct v2_disk_dqdbheader)+i*sizeof(struct v2_disk_dqblk);
	freedqbuf(buf);
	return blk;
out_buf:
	freedqbuf(buf);
	return 0;
}

/* Insert reference to structure into the trie */
static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
{
	struct super_block *sb = dquot->dq_sb;
	dqbuf_t buf;
	int ret = 0, newson = 0, newact = 0;
	__le32 *ref;
	uint newblk;

	if (!(buf = getdqbuf()))
		return -ENOMEM;
	if (!*treeblk) {
		ret = get_free_dqblk(sb, dquot->dq_type);
		if (ret < 0)
			goto out_buf;
		*treeblk = ret;
		memset(buf, 0, V2_DQBLKSIZE);
		newact = 1;
	}
	else {
		if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
			printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
			goto out_buf;
		}
	}
	ref = (__le32 *)buf;
	newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
	if (!newblk)
		newson = 1;
	if (depth == V2_DQTREEDEPTH-1) {
#ifdef __QUOTA_V2_PARANOIA
		if (newblk) {
			printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]));
			ret = -EIO;
			goto out_buf;
		}
#endif
		newblk = find_free_dqentry(dquot, &ret);
	}
	else
		ret = do_insert_tree(dquot, &newblk, depth+1);
	if (newson && ret >= 0) {
		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
		ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
	}
	else if (newact && ret < 0)
		put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
out_buf:
	freedqbuf(buf);
	return ret;
}

/* Wrapper for inserting quota structure into tree */
static inline int dq_insert_tree(struct dquot *dquot)
{
	int tmp = V2_DQTREEOFF;
	return do_insert_tree(dquot, &tmp, 0);
}

/*
 *	We don't have to be afraid of deadlocks as we never have quotas on quota files...
 */
static int v2_write_dquot(struct dquot *dquot)
{
	int type = dquot->dq_type;
	ssize_t ret;
	struct v2_disk_dqblk ddquot, empty;

	/* dq_off is guarded by dqio_sem */
	if (!dquot->dq_off)
		if ((ret = dq_insert_tree(dquot)) < 0) {
			printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret);
			return ret;
		}
	spin_lock(&dq_data_lock);
	mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
	/* Argh... We may need to write structure full of zeroes but that would be
	 * treated as an empty place by the rest of the code. Format change would
	 * be definitely cleaner but the problems probably are not worth it */
	memset(&empty, 0, sizeof(struct v2_disk_dqblk));
	if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
		ddquot.dqb_itime = cpu_to_le64(1);
	spin_unlock(&dq_data_lock);
	ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
	      (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
	if (ret != sizeof(struct v2_disk_dqblk)) {
		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
		if (ret >= 0)
			ret = -ENOSPC;
	}
	else
		ret = 0;
	dqstats.writes++;

	return ret;
}

/* Free dquot entry in data block */
static int free_dqentry(struct dquot *dquot, uint blk)
{
	struct super_block *sb = dquot->dq_sb;
	int type = dquot->dq_type;
	struct v2_disk_dqdbheader *dh;
	dqbuf_t buf = getdqbuf();
	int ret = 0;

	if (!buf)
		return -ENOMEM;
	if (dquot->dq_off >> V2_DQBLKSIZE_BITS != blk) {
		printk(KERN_ERR "VFS: Quota structure has offset to other "
		  "block (%u) than it should (%u).\n", blk,
		  (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
		goto out_buf;
	}
	if ((ret = read_blk(sb, type, blk, buf)) < 0) {
		printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
		goto out_buf;
	}
	dh = (struct v2_disk_dqdbheader *)buf;
	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
		if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
		    (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
			printk(KERN_ERR "VFS: Can't move quota data block (%u) "
			  "to free list.\n", blk);
			goto out_buf;
		}
	}
	else {
		memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0,
		  sizeof(struct v2_disk_dqblk));
		if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
			/* Insert will write block itself */
			if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
				printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
				goto out_buf;
			}
		}
		else
			if ((ret = write_blk(sb, type, blk, buf)) < 0) {
				printk(KERN_ERR "VFS: Can't write quota data "
				  "block %u\n", blk);
				goto out_buf;
			}
	}
	dquot->dq_off = 0;	/* Quota is now unattached */
out_buf:
	freedqbuf(buf);
	return ret;
}

/* Remove reference to dquot from tree */
static int remove_tree(struct dquot *dquot, uint *blk, int depth)
{
	struct super_block *sb = dquot->dq_sb;
	int type = dquot->dq_type;
	dqbuf_t buf = getdqbuf();
	int ret = 0;
	uint newblk;
	__le32 *ref = (__le32 *)buf;
	
	if (!buf)
		return -ENOMEM;
	if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
		printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
		goto out_buf;
	}
	newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
	if (depth == V2_DQTREEDEPTH-1) {
		ret = free_dqentry(dquot, newblk);
		newblk = 0;
	}
	else
		ret = remove_tree(dquot, &newblk, depth+1);
	if (ret >= 0 && !newblk) {
		int i;
		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0);
		for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++);	/* Block got empty? */
		/* Don't put the root block into the free block list */
		if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
			put_free_dqblk(sb, type, buf, *blk);
			*blk = 0;
		}
		else
			if ((ret = write_blk(sb, type, *blk, buf)) < 0)
				printk(KERN_ERR "VFS: Can't write quota tree "
				  "block %u.\n", *blk);
	}
out_buf:
	freedqbuf(buf);
	return ret;	
}

/* Delete dquot from tree */
static int v2_delete_dquot(struct dquot *dquot)
{
	uint tmp = V2_DQTREEOFF;

	if (!dquot->dq_off)	/* Even not allocated? */
		return 0;
	return remove_tree(dquot, &tmp, 0);
}

/* Find entry in block */
static loff_t find_block_dqentry(struct dquot *dquot, uint blk)
{
	dqbuf_t buf = getdqbuf();
	loff_t ret = 0;
	int i;
	struct v2_disk_dqblk *ddquot = GETENTRIES(buf);

	if (!buf)
		return -ENOMEM;
	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
		goto out_buf;
	}
	if (dquot->dq_id)
		for (i = 0; i < V2_DQSTRINBLK &&
		     le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
	else {	/* ID 0 as a bit more complicated searching... */
		struct v2_disk_dqblk fakedquot;

		memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
		for (i = 0; i < V2_DQSTRINBLK; i++)
			if (!le32_to_cpu(ddquot[i].dqb_id) &&
			    memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))
				break;
	}
	if (i == V2_DQSTRINBLK) {
		printk(KERN_ERR "VFS: Quota for id %u referenced "
		  "but not present.\n", dquot->dq_id);
		ret = -EIO;
		goto out_buf;
	}
	else
		ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct
		  v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);
out_buf:
	freedqbuf(buf);
	return ret;
}

/* Find entry for given id in the tree */
static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
{
	dqbuf_t buf = getdqbuf();
	loff_t ret = 0;
	__le32 *ref = (__le32 *)buf;

	if (!buf)
		return -ENOMEM;
	if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
		goto out_buf;
	}
	ret = 0;
	blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
	if (!blk)	/* No reference? */
		goto out_buf;
	if (depth < V2_DQTREEDEPTH-1)
		ret = find_tree_dqentry(dquot, blk, depth+1);
	else
		ret = find_block_dqentry(dquot, blk);
out_buf:
	freedqbuf(buf);
	return ret;
}

/* Find entry for given id in the tree - wrapper function */
static inline loff_t find_dqentry(struct dquot *dquot)
{
	return find_tree_dqentry(dquot, V2_DQTREEOFF, 0);
}

static int v2_read_dquot(struct dquot *dquot)
{
	int type = dquot->dq_type;
	loff_t offset;
	struct v2_disk_dqblk ddquot, empty;
	int ret = 0;

#ifdef __QUOTA_V2_PARANOIA
	/* Invalidated quota? */
	if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
		printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
		return -EIO;
	}
#endif
	offset = find_dqentry(dquot);
	if (offset <= 0) {	/* Entry not present? */
		if (offset < 0)
			printk(KERN_ERR "VFS: Can't read quota "
			  "structure for id %u.\n", dquot->dq_id);
		dquot->dq_off = 0;
		set_bit(DQ_FAKE_B, &dquot->dq_flags);
		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
		ret = offset;
	}
	else {
		dquot->dq_off = offset;
		if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
		    (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
		    != sizeof(struct v2_disk_dqblk)) {
			if (ret >= 0)
				ret = -EIO;
			printk(KERN_ERR "VFS: Error while reading quota "
			  "structure for id %u.\n", dquot->dq_id);
			memset(&ddquot, 0, sizeof(struct v2_disk_dqblk));
		}
		else {
			ret = 0;
			/* We need to escape back all-zero structure */
			memset(&empty, 0, sizeof(struct v2_disk_dqblk));
			empty.dqb_itime = cpu_to_le64(1);
			if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
				ddquot.dqb_itime = 0;
		}
		disk2memdqb(&dquot->dq_dqb, &ddquot);
		if (!dquot->dq_dqb.dqb_bhardlimit &&
			!dquot->dq_dqb.dqb_bsoftlimit &&
			!dquot->dq_dqb.dqb_ihardlimit &&
			!dquot->dq_dqb.dqb_isoftlimit)
			set_bit(DQ_FAKE_B, &dquot->dq_flags);
	}
	dqstats.reads++;

	return ret;
}

/* Check whether dquot should not be deleted. We know we are
 * the only one operating on dquot (thanks to dq_lock) */
static int v2_release_dquot(struct dquot *dquot)
{
	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
		return v2_delete_dquot(dquot);
	return 0;
}

static struct quota_format_ops v2_format_ops = {
	.check_quota_file	= v2_check_quota_file,
	.read_file_info		= v2_read_file_info,
	.write_file_info	= v2_write_file_info,
	.free_file_info		= NULL,
	.read_dqblk		= v2_read_dquot,
	.commit_dqblk		= v2_write_dquot,
	.release_dqblk		= v2_release_dquot,
};

static struct quota_format_type v2_quota_format = {
	.qf_fmt_id	= QFMT_VFS_V0,
	.qf_ops		= &v2_format_ops,
	.qf_owner	= THIS_MODULE
};

static int __init init_v2_quota_format(void)
{
	return register_quota_format(&v2_quota_format);
}

static void __exit exit_v2_quota_format(void)
{
	unregister_quota_format(&v2_quota_format);
}

module_init(init_v2_quota_format);
module_exit(exit_v2_quota_format);
