/*
 * Implementation of new quotafile format
 *
 * Jan Kara <jack@suse.cz> - sponsored by SuSE CR
 */

#include "config.h"
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "common.h"
#include "quotaio_tree.h"
#include "quotaio.h"

typedef char *dqbuf_t;

#define freedqbuf(buf)		ext2fs_free_mem(&buf)

static inline dqbuf_t getdqbuf(void)
{
	dqbuf_t buf;
	if (ext2fs_get_memzero(QT_BLKSIZE, &buf)) {
		log_err("Failed to allocate dqbuf");
		return NULL;
	}

	return buf;
}

/* Is given dquot empty? */
int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk)
{
	unsigned int i;

	for (i = 0; i < info->dqi_entry_size; i++)
		if (disk[i])
			return 0;
	return 1;
}

int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
{
	return (QT_BLKSIZE - sizeof(struct qt_disk_dqdbheader)) /
		info->dqi_entry_size;
}

static int get_index(qid_t id, int depth)
{
	return (id >> ((QT_TREEDEPTH - depth - 1) * 8)) & 0xff;
}

static inline void mark_quotafile_info_dirty(struct quota_handle *h)
{
	h->qh_io_flags |= IOFL_INFODIRTY;
}

/* Read given block */
static void read_blk(struct quota_handle *h, unsigned int blk, dqbuf_t buf)
{
	int err;

	err = h->e2fs_read(&h->qh_qf, blk << QT_BLKSIZE_BITS, buf,
			QT_BLKSIZE);
	if (err < 0)
		log_err("Cannot read block %u: %s", blk, strerror(errno));
	else if (err != QT_BLKSIZE)
		memset(buf + err, 0, QT_BLKSIZE - err);
}

/* Write block */
static int write_blk(struct quota_handle *h, unsigned int blk, dqbuf_t buf)
{
	int err;

	err = h->e2fs_write(&h->qh_qf, blk << QT_BLKSIZE_BITS, buf,
			QT_BLKSIZE);
	if (err < 0 && errno != ENOSPC)
		log_err("Cannot write block (%u): %s", blk, strerror(errno));
	if (err != QT_BLKSIZE)
		return -ENOSPC;
	return 0;
}

/* Get free block in file (either from free list or create new one) */
static int get_free_dqblk(struct quota_handle *h)
{
	dqbuf_t buf = getdqbuf();
	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
	int blk;

	if (!buf)
		return -ENOMEM;

	if (info->dqi_free_blk) {
		blk = info->dqi_free_blk;
		read_blk(h, blk, buf);
		info->dqi_free_blk = ext2fs_le32_to_cpu(dh->dqdh_next_free);
	} else {
		memset(buf, 0, QT_BLKSIZE);
		/* Assure block allocation... */
		if (write_blk(h, info->dqi_blocks, buf) < 0) {
			freedqbuf(buf);
			log_err("Cannot allocate new quota block "
				"(out of disk space).");
			return -ENOSPC;
		}
		blk = info->dqi_blocks++;
	}
	mark_quotafile_info_dirty(h);
	freedqbuf(buf);
	return blk;
}

/* Put given block to free list */
static void put_free_dqblk(struct quota_handle *h, dqbuf_t buf,
			   unsigned int blk)
{
	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;

	dh->dqdh_next_free = ext2fs_cpu_to_le32(info->dqi_free_blk);
	dh->dqdh_prev_free = ext2fs_cpu_to_le32(0);
	dh->dqdh_entries = ext2fs_cpu_to_le16(0);
	info->dqi_free_blk = blk;
	mark_quotafile_info_dirty(h);
	write_blk(h, blk, buf);
}

/* Remove given block from the list of blocks with free entries */
static void remove_free_dqentry(struct quota_handle *h, dqbuf_t buf,
				unsigned int blk)
{
	dqbuf_t tmpbuf = getdqbuf();
	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
	unsigned int nextblk = ext2fs_le32_to_cpu(dh->dqdh_next_free), prevblk =

		ext2fs_le32_to_cpu(dh->dqdh_prev_free);

	if (!tmpbuf)
		return;

	if (nextblk) {
		read_blk(h, nextblk, tmpbuf);
		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
				dh->dqdh_prev_free;
		write_blk(h, nextblk, tmpbuf);
	}
	if (prevblk) {
		read_blk(h, prevblk, tmpbuf);
		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free =
				dh->dqdh_next_free;
		write_blk(h, prevblk, tmpbuf);
	} else {
		h->qh_info.u.v2_mdqi.dqi_qtree.dqi_free_entry = nextblk;
		mark_quotafile_info_dirty(h);
	}
	freedqbuf(tmpbuf);
	dh->dqdh_next_free = dh->dqdh_prev_free = ext2fs_cpu_to_le32(0);
	write_blk(h, blk, buf);	/* No matter whether write succeeds
				 * block is out of list */
}

/* Insert given block to the beginning of list with free entries */
static void insert_free_dqentry(struct quota_handle *h, dqbuf_t buf,
				unsigned int blk)
{
	dqbuf_t tmpbuf = getdqbuf();
	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;

	if (!tmpbuf)
		return;

	dh->dqdh_next_free = ext2fs_cpu_to_le32(info->dqi_free_entry);
	dh->dqdh_prev_free = ext2fs_cpu_to_le32(0);
	write_blk(h, blk, buf);
	if (info->dqi_free_entry) {
		read_blk(h, info->dqi_free_entry, tmpbuf);
		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
				ext2fs_cpu_to_le32(blk);
		write_blk(h, info->dqi_free_entry, tmpbuf);
	}
	freedqbuf(tmpbuf);
	info->dqi_free_entry = blk;
	mark_quotafile_info_dirty(h);
}

/* Find space for dquot */
static unsigned int find_free_dqentry(struct quota_handle *h,
				      struct dquot *dquot, int *err)
{
	int blk, i;
	struct qt_disk_dqdbheader *dh;
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
	char *ddquot;
	dqbuf_t buf;

	*err = 0;
	buf = getdqbuf();
	if (!buf) {
		*err = -ENOMEM;
		return 0;
	}

	dh = (struct qt_disk_dqdbheader *)buf;
	if (info->dqi_free_entry) {
		blk = info->dqi_free_entry;
		read_blk(h, blk, buf);
	} else {
		blk = get_free_dqblk(h);
		if (blk < 0) {
			freedqbuf(buf);
			*err = blk;
			return 0;
		}
		memset(buf, 0, QT_BLKSIZE);
		info->dqi_free_entry = blk;
		mark_quotafile_info_dirty(h);
	}

	/* Block will be full? */
	if (ext2fs_le16_to_cpu(dh->dqdh_entries) + 1 >=
	    qtree_dqstr_in_blk(info))
		remove_free_dqentry(h, buf, blk);

	dh->dqdh_entries =
		ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(dh->dqdh_entries) + 1);
	/* Find free structure in block */
	ddquot = buf + sizeof(struct qt_disk_dqdbheader);
	for (i = 0;
	     i < qtree_dqstr_in_blk(info) && !qtree_entry_unused(info, ddquot);
	     i++)
		ddquot += info->dqi_entry_size;

	if (i == qtree_dqstr_in_blk(info))
		log_err("find_free_dqentry(): Data block full unexpectedly.");

	write_blk(h, blk, buf);
	dquot->dq_dqb.u.v2_mdqb.dqb_off =
		(blk << QT_BLKSIZE_BITS) + sizeof(struct qt_disk_dqdbheader) +
		i * info->dqi_entry_size;
	freedqbuf(buf);
	return blk;
}

/* Insert reference to structure into the trie */
static int do_insert_tree(struct quota_handle *h, struct dquot *dquot,
			  unsigned int * treeblk, int depth)
{
	dqbuf_t buf;
	int newson = 0, newact = 0;
	__le32 *ref;
	unsigned int newblk;
	int ret = 0;

	log_debug("inserting in tree: treeblk=%u, depth=%d", *treeblk, depth);
	buf = getdqbuf();
	if (!buf)
		return -ENOMEM;

	if (!*treeblk) {
		ret = get_free_dqblk(h);
		if (ret < 0)
			goto out_buf;
		*treeblk = ret;
		memset(buf, 0, QT_BLKSIZE);
		newact = 1;
	} else {
		read_blk(h, *treeblk, buf);
	}

	ref = (__le32 *) buf;
	newblk = ext2fs_le32_to_cpu(ref[get_index(dquot->dq_id, depth)]);
	if (!newblk)
		newson = 1;
	if (depth == QT_TREEDEPTH - 1) {
		if (newblk)
			log_err("Inserting already present quota entry "
				"(block %u).",
				ref[get_index(dquot->dq_id, depth)]);
		newblk = find_free_dqentry(h, dquot, &ret);
	} else {
		ret = do_insert_tree(h, dquot, &newblk, depth + 1);
	}

	if (newson && ret >= 0) {
		ref[get_index(dquot->dq_id, depth)] =
			ext2fs_cpu_to_le32(newblk);
		write_blk(h, *treeblk, buf);
	} else if (newact && ret < 0) {
		put_free_dqblk(h, buf, *treeblk);
	}

out_buf:
	freedqbuf(buf);
	return ret;
}

/* Wrapper for inserting quota structure into tree */
static void dq_insert_tree(struct quota_handle *h, struct dquot *dquot)
{
	unsigned int tmp = QT_TREEOFF;

	if (do_insert_tree(h, dquot, &tmp, 0) < 0)
		log_err("Cannot write quota (id %u): %s",
			(unsigned int) dquot->dq_id, strerror(errno));
}

/* Write dquot to file */
void qtree_write_dquot(struct dquot *dquot)
{
	errcode_t retval;
	unsigned int ret;
	char *ddquot;
	struct quota_handle *h = dquot->dq_h;
	struct qtree_mem_dqinfo *info =
			&dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree;
	log_debug("writing ddquot 1: off=%llu, info->dqi_entry_size=%u",
			dquot->dq_dqb.u.v2_mdqb.dqb_off,
			info->dqi_entry_size);
	retval = ext2fs_get_mem(info->dqi_entry_size, &ddquot);
	if (retval) {
		errno = ENOMEM;
		log_err("Quota write failed (id %u): %s",
			(unsigned int)dquot->dq_id, strerror(errno));
		return;
	}
	memset(ddquot, 0, info->dqi_entry_size);

	if (!dquot->dq_dqb.u.v2_mdqb.dqb_off)
		dq_insert_tree(dquot->dq_h, dquot);
	info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
	log_debug("writing ddquot 2: off=%llu, info->dqi_entry_size=%u",
			dquot->dq_dqb.u.v2_mdqb.dqb_off,
			info->dqi_entry_size);
	ret = h->e2fs_write(&h->qh_qf, dquot->dq_dqb.u.v2_mdqb.dqb_off, ddquot,
			info->dqi_entry_size);

	if (ret != info->dqi_entry_size) {
		if (ret > 0)
			errno = ENOSPC;
		log_err("Quota write failed (id %u): %s",
			(unsigned int)dquot->dq_id, strerror(errno));
	}
	ext2fs_free_mem(&ddquot);
}

/* Free dquot entry in data block */
static void free_dqentry(struct quota_handle *h, struct dquot *dquot,
			 unsigned int blk)
{
	struct qt_disk_dqdbheader *dh;
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
	dqbuf_t buf = getdqbuf();

	if (!buf)
		return;

	if (dquot->dq_dqb.u.v2_mdqb.dqb_off >> QT_BLKSIZE_BITS != blk)
		log_err("Quota structure has offset to other block (%u) "
			"than it should (%u).", blk,
			  (unsigned int) (dquot->dq_dqb.u.v2_mdqb.dqb_off >>
				  QT_BLKSIZE_BITS));

	read_blk(h, blk, buf);
	dh = (struct qt_disk_dqdbheader *)buf;
	dh->dqdh_entries =
		ext2fs_cpu_to_le16(ext2fs_le16_to_cpu(dh->dqdh_entries) - 1);

	if (!ext2fs_le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
		remove_free_dqentry(h, buf, blk);
		put_free_dqblk(h, buf, blk);
	} else {
		memset(buf + (dquot->dq_dqb.u.v2_mdqb.dqb_off &
			      ((1 << QT_BLKSIZE_BITS) - 1)),
		       0, info->dqi_entry_size);

		/* First free entry? */
		if (ext2fs_le16_to_cpu(dh->dqdh_entries) ==
				qtree_dqstr_in_blk(info) - 1)
			/* This will also write data block */
			insert_free_dqentry(h, buf, blk);
		else
			write_blk(h, blk, buf);
	}
	dquot->dq_dqb.u.v2_mdqb.dqb_off = 0;
	freedqbuf(buf);
}

/* Remove reference to dquot from tree */
static void remove_tree(struct quota_handle *h, struct dquot *dquot,
			unsigned int * blk, int depth)
{
	dqbuf_t buf = getdqbuf();
	unsigned int newblk;
	__le32 *ref = (__le32 *) buf;

	if (!buf)
		return;

	read_blk(h, *blk, buf);
	newblk = ext2fs_le32_to_cpu(ref[get_index(dquot->dq_id, depth)]);
	if (depth == QT_TREEDEPTH - 1) {
		free_dqentry(h, dquot, newblk);
		newblk = 0;
	} else {
		remove_tree(h, dquot, &newblk, depth + 1);
	}

	if (!newblk) {
		int i;

		ref[get_index(dquot->dq_id, depth)] = ext2fs_cpu_to_le32(0);

		/* Block got empty? */
		for (i = 0; i < QT_BLKSIZE && !buf[i]; i++);

		/* Don't put the root block into the free block list */
		if (i == QT_BLKSIZE && *blk != QT_TREEOFF) {
			put_free_dqblk(h, buf, *blk);
			*blk = 0;
		} else {
			write_blk(h, *blk, buf);
		}
	}
	freedqbuf(buf);
}

/* Delete dquot from tree */
void qtree_delete_dquot(struct dquot *dquot)
{
	unsigned int tmp = QT_TREEOFF;

	if (!dquot->dq_dqb.u.v2_mdqb.dqb_off)	/* Even not allocated? */
		return;
	remove_tree(dquot->dq_h, dquot, &tmp, 0);
}

/* Find entry in block */
static ext2_loff_t find_block_dqentry(struct quota_handle *h,
				      struct dquot *dquot, unsigned int blk)
{
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
	dqbuf_t buf = getdqbuf();
	int i;
	char *ddquot = buf + sizeof(struct qt_disk_dqdbheader);

	if (!buf)
		return -ENOMEM;

	read_blk(h, blk, buf);
	for (i = 0;
	     i < qtree_dqstr_in_blk(info) && !info->dqi_ops->is_id(ddquot, dquot);
	     i++)
		ddquot += info->dqi_entry_size;

	if (i == qtree_dqstr_in_blk(info))
		log_err("Quota for id %u referenced but not present.",
			dquot->dq_id);
	freedqbuf(buf);
	return (blk << QT_BLKSIZE_BITS) + sizeof(struct qt_disk_dqdbheader) +
		i * info->dqi_entry_size;
}

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

	if (!buf)
		return -ENOMEM;

	read_blk(h, blk, buf);
	ret = 0;
	blk = ext2fs_le32_to_cpu(ref[get_index(dquot->dq_id, depth)]);
	if (!blk)	/* No reference? */
		goto out_buf;
	if (depth < QT_TREEDEPTH - 1)
		ret = find_tree_dqentry(h, dquot, blk, depth + 1);
	else
		ret = find_block_dqentry(h, dquot, blk);
out_buf:
	freedqbuf(buf);
	return ret;
}

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

/*
 *  Read dquot from disk.
 */
struct dquot *qtree_read_dquot(struct quota_handle *h, qid_t id)
{
	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
	ext2_loff_t offset;
	unsigned int ret;
	char *ddquot;
	struct dquot *dquot = get_empty_dquot();

	if (!dquot)
		return NULL;
	if (ext2fs_get_mem(info->dqi_entry_size, &ddquot)) {
		ext2fs_free_mem(&dquot);
		return NULL;
	}

	dquot->dq_id = id;
	dquot->dq_h = h;
	dquot->dq_dqb.u.v2_mdqb.dqb_off = 0;
	memset(&dquot->dq_dqb, 0, sizeof(struct util_dqblk));

	offset = find_dqentry(h, dquot);
	if (offset > 0) {
		dquot->dq_dqb.u.v2_mdqb.dqb_off = offset;
		ret = h->e2fs_read(&h->qh_qf, offset, ddquot,
			info->dqi_entry_size);
		if (ret != info->dqi_entry_size) {
			if (ret > 0)
				errno = EIO;
			log_err("Cannot read quota structure for id %u: %s",
				dquot->dq_id, strerror(errno));
		}
		info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
	}
	ext2fs_free_mem(&ddquot);
	return dquot;
}

/*
 * Scan all dquots in file and call callback on each
 */
#define set_bit(bmp, ind) ((bmp)[(ind) >> 3] |= (1 << ((ind) & 7)))
#define get_bit(bmp, ind) ((bmp)[(ind) >> 3] & (1 << ((ind) & 7)))

static int report_block(struct dquot *dquot, unsigned int blk, char *bitmap,
			int (*process_dquot) (struct dquot *, void *),
			void *data)
{
	struct qtree_mem_dqinfo *info =
			&dquot->dq_h->qh_info.u.v2_mdqi.dqi_qtree;
	dqbuf_t buf = getdqbuf();
	struct qt_disk_dqdbheader *dh;
	char *ddata;
	int entries, i;

	if (!buf)
		return 0;

	set_bit(bitmap, blk);
	read_blk(dquot->dq_h, blk, buf);
	dh = (struct qt_disk_dqdbheader *)buf;
	ddata = buf + sizeof(struct qt_disk_dqdbheader);
	entries = ext2fs_le16_to_cpu(dh->dqdh_entries);
	for (i = 0; i < qtree_dqstr_in_blk(info);
			i++, ddata += info->dqi_entry_size)
		if (!qtree_entry_unused(info, ddata)) {
			dquot->dq_dqb.u.v2_mdqb.dqb_off =
				(blk << QT_BLKSIZE_BITS) +
				sizeof(struct qt_disk_dqdbheader) +
				i * info->dqi_entry_size;
			info->dqi_ops->disk2mem_dqblk(dquot, ddata);
			if (process_dquot(dquot, data) < 0)
				break;
		}
	freedqbuf(buf);
	return entries;
}

static void check_reference(struct quota_handle *h, unsigned int blk)
{
	if (blk >= h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks)
		log_err("Illegal reference (%u >= %u) in %s quota file. "
			"Quota file is probably corrupted.\n"
			"Please run e2fsck (8) to fix it.",
			blk,
			h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks,
			quota_type2name(h->qh_type));
}

static int report_tree(struct dquot *dquot, unsigned int blk, int depth,
		       char *bitmap,
		       int (*process_dquot) (struct dquot *, void *),
		       void *data)
{
	int entries = 0, i;
	dqbuf_t buf = getdqbuf();
	__le32 *ref = (__le32 *) buf;

	if (!buf)
		return 0;

	read_blk(dquot->dq_h, blk, buf);
	if (depth == QT_TREEDEPTH - 1) {
		for (i = 0; i < QT_BLKSIZE >> 2; i++) {
			blk = ext2fs_le32_to_cpu(ref[i]);
			check_reference(dquot->dq_h, blk);
			if (blk && !get_bit(bitmap, blk))
				entries += report_block(dquot, blk, bitmap,
							process_dquot, data);
		}
	} else {
		for (i = 0; i < QT_BLKSIZE >> 2; i++) {
			blk = ext2fs_le32_to_cpu(ref[i]);
			if (blk) {
				check_reference(dquot->dq_h, blk);
				entries += report_tree(dquot, blk, depth + 1,
						       bitmap, process_dquot,
						       data);
			}
		}
	}
	freedqbuf(buf);
	return entries;
}

static unsigned int find_set_bits(char *bmp, int blocks)
{
	unsigned int	used = 0;
	int		i;

	for (i = 0; i < blocks; i++)
		if (get_bit(bmp, i))
			used++;
	return used;
}

int qtree_scan_dquots(struct quota_handle *h,
		      int (*process_dquot) (struct dquot *, void *),
		      void *data)
{
	char *bitmap;
	struct v2_mem_dqinfo *v2info = &h->qh_info.u.v2_mdqi;
	struct qtree_mem_dqinfo *info = &v2info->dqi_qtree;
	struct dquot *dquot = get_empty_dquot();

	if (!dquot)
		return -1;

	dquot->dq_h = h;
	if (ext2fs_get_memzero((info->dqi_blocks + 7) >> 3, &bitmap)) {
		ext2fs_free_mem(&dquot);
		return -1;
	}
	v2info->dqi_used_entries = report_tree(dquot, QT_TREEOFF, 0, bitmap,
					       process_dquot, data);
	v2info->dqi_data_blocks = find_set_bits(bitmap, info->dqi_blocks);
	ext2fs_free_mem(&bitmap);
	ext2fs_free_mem(&dquot);
	return 0;
}
