/*
 * mkquota.c --- create quota files for a filesystem
 *
 * Aditya Kali <adityakali@google.com>
 */
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "e2p/e2p.h"

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

/* Needed for architectures where sizeof(int) != sizeof(void *) */
#define UINT_TO_VOIDPTR(val)  ((void *)(intptr_t)(val))
#define VOIDPTR_TO_UINT(ptr)  ((unsigned int)(intptr_t)(ptr))

#if DEBUG_QUOTA
static void print_inode(struct ext2_inode *inode)
{
	if (!inode)
		return;

	fprintf(stderr, "  i_mode = %d\n", inode->i_mode);
	fprintf(stderr, "  i_uid = %d\n", inode->i_uid);
	fprintf(stderr, "  i_size = %d\n", inode->i_size);
	fprintf(stderr, "  i_atime = %d\n", inode->i_atime);
	fprintf(stderr, "  i_ctime = %d\n", inode->i_ctime);
	fprintf(stderr, "  i_mtime = %d\n", inode->i_mtime);
	fprintf(stderr, "  i_dtime = %d\n", inode->i_dtime);
	fprintf(stderr, "  i_gid = %d\n", inode->i_gid);
	fprintf(stderr, "  i_links_count = %d\n", inode->i_links_count);
	fprintf(stderr, "  i_blocks = %d\n", inode->i_blocks);
	fprintf(stderr, "  i_flags = %d\n", inode->i_flags);

	return;
}

static void print_dquot(const char *desc, struct dquot *dq)
{
	if (desc)
		fprintf(stderr, "%s: ", desc);
	fprintf(stderr, "%u %lld:%lld:%lld %lld:%lld:%lld\n",
		dq->dq_id, dq->dq_dqb.dqb_curspace,
		dq->dq_dqb.dqb_bsoftlimit, dq->dq_dqb.dqb_bhardlimit,
		dq->dq_dqb.dqb_curinodes,
		dq->dq_dqb.dqb_isoftlimit, dq->dq_dqb.dqb_ihardlimit);
}
#else
static void print_dquot(const char *desc, struct dquot *dq)
{
}
#endif

/*
 * Returns 0 if not able to find the quota file, otherwise returns its
 * inode number.
 */
int quota_file_exists(ext2_filsys fs, int qtype, int fmt)
{
	char qf_name[256];
	errcode_t ret;
	ext2_ino_t ino;

	if (qtype >= MAXQUOTAS)
		return -EINVAL;

	quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);

	ret = ext2fs_lookup(fs, EXT2_ROOT_INO, qf_name, strlen(qf_name), 0,
			    &ino);
	if (ret)
		return 0;

	return ino;
}

/*
 * Set the value for reserved quota inode number field in superblock.
 */
void quota_set_sb_inum(ext2_filsys fs, ext2_ino_t ino, int qtype)
{
	ext2_ino_t *inump;

	inump = (qtype == USRQUOTA) ? &fs->super->s_usr_quota_inum :
		&fs->super->s_grp_quota_inum;

	log_debug("setting quota ino in superblock: ino=%u, type=%d", ino,
		 qtype);
	*inump = ino;
	ext2fs_mark_super_dirty(fs);
}

errcode_t quota_remove_inode(ext2_filsys fs, int qtype)
{
	ext2_ino_t qf_ino;
	errcode_t	retval;

	retval = ext2fs_read_bitmaps(fs);
	if (retval) {
		log_err("Couldn't read bitmaps: %s", error_message(retval));
		return retval;
	}
	qf_ino = (qtype == USRQUOTA) ? fs->super->s_usr_quota_inum :
		fs->super->s_grp_quota_inum;
	quota_set_sb_inum(fs, 0, qtype);
	/* Truncate the inode only if its a reserved one. */
	if (qf_ino < EXT2_FIRST_INODE(fs->super))
		quota_inode_truncate(fs, qf_ino);

	ext2fs_mark_super_dirty(fs);
	fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	retval = ext2fs_write_bitmaps(fs);
	if (retval) {
		log_err("Couldn't write bitmaps: %s", error_message(retval));
		return retval;
	}
	return 0;
}

static void write_dquots(dict_t *dict, struct quota_handle *qh)
{
	dnode_t		*n;
	struct dquot	*dq;

	for (n = dict_first(dict); n; n = dict_next(dict, n)) {
		dq = dnode_get(n);
		if (dq) {
			print_dquot("write", dq);
			dq->dq_h = qh;
			update_grace_times(dq);
			qh->qh_ops->commit_dquot(dq);
		}
	}
}

errcode_t quota_write_inode(quota_ctx_t qctx, int qtype)
{
	int		retval = 0, i;
	dict_t		*dict;
	ext2_filsys	fs;
	struct quota_handle *h = NULL;
	int		fmt = QFMT_VFS_V1;

	if (!qctx)
		return 0;

	fs = qctx->fs;
	retval = ext2fs_get_mem(sizeof(struct quota_handle), &h);
	if (retval) {
		log_err("Unable to allocate quota handle: %s",
			error_message(retval));
		goto out;
	}

	retval = ext2fs_read_bitmaps(fs);
	if (retval) {
		log_err("Couldn't read bitmaps: %s", error_message(retval));
		goto out;
	}

	for (i = 0; i < MAXQUOTAS; i++) {
		if ((qtype != -1) && (i != qtype))
			continue;

		dict = qctx->quota_dict[i];
		if (!dict)
			continue;

		retval = quota_file_create(h, fs, i, fmt);
		if (retval < 0) {
			log_err("Cannot initialize io on quotafile");
			continue;
		}

		write_dquots(dict, h);
		retval = quota_file_close(qctx, h);
		if (retval < 0) {
			log_err("Cannot finish IO on new quotafile: %s",
				strerror(errno));
			if (h->qh_qf.e2_file)
				ext2fs_file_close(h->qh_qf.e2_file);
			quota_inode_truncate(fs, h->qh_qf.ino);
			continue;
		}

		/* Set quota inode numbers in superblock. */
		quota_set_sb_inum(fs, h->qh_qf.ino, i);
		ext2fs_mark_super_dirty(fs);
		ext2fs_mark_bb_dirty(fs);
		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	}

	retval = ext2fs_write_bitmaps(fs);
	if (retval) {
		log_err("Couldn't write bitmaps: %s", error_message(retval));
		goto out;
	}
out:
	if (h)
		ext2fs_free_mem(&h);
	return retval;
}

/******************************************************************/
/* Helper functions for computing quota in memory.                */
/******************************************************************/

static int dict_uint_cmp(const void *a, const void *b)
{
	unsigned int	c, d;

	c = VOIDPTR_TO_UINT(a);
	d = VOIDPTR_TO_UINT(b);

	if (c == d)
		return 0;
	else if (c > d)
		return 1;
	else
		return -1;
}

static inline qid_t get_qid(struct ext2_inode *inode, int qtype)
{
	if (qtype == USRQUOTA)
		return inode_uid(*inode);
	return inode_gid(*inode);
}

static void quota_dnode_free(dnode_t *node,
			     void *context EXT2FS_ATTR((unused)))
{
	void *ptr = node ? dnode_get(node) : 0;

	ext2fs_free_mem(&ptr);
	free(node);
}

/*
 * Set up the quota tracking data structures.
 */
errcode_t quota_init_context(quota_ctx_t *qctx, ext2_filsys fs, int qtype)
{
	errcode_t err;
	dict_t	*dict;
	quota_ctx_t ctx;
	int	i;

	err = ext2fs_get_mem(sizeof(struct quota_ctx), &ctx);
	if (err) {
		log_err("Failed to allocate quota context");
		return err;
	}

	memset(ctx, 0, sizeof(struct quota_ctx));
	for (i = 0; i < MAXQUOTAS; i++) {
		ctx->quota_file[i] = NULL;
		if ((qtype != -1) && (i != qtype))
			continue;
		err = ext2fs_get_mem(sizeof(dict_t), &dict);
		if (err) {
			log_err("Failed to allocate dictionary");
			quota_release_context(&ctx);
			return err;
		}
		ctx->quota_dict[i] = dict;
		dict_init(dict, DICTCOUNT_T_MAX, dict_uint_cmp);
		dict_set_allocator(dict, NULL, quota_dnode_free, NULL);
	}

	ctx->fs = fs;
	*qctx = ctx;
	return 0;
}

void quota_release_context(quota_ctx_t *qctx)
{
	errcode_t err;
	dict_t	*dict;
	int	i;
	quota_ctx_t ctx;

	if (!qctx)
		return;

	ctx = *qctx;
	for (i = 0; i < MAXQUOTAS; i++) {
		dict = ctx->quota_dict[i];
		ctx->quota_dict[i] = 0;
		if (dict) {
			dict_free_nodes(dict);
			free(dict);
		}
		if (ctx->quota_file[i]) {
			err = quota_file_close(ctx, ctx->quota_file[i]);
			if (err) {
				log_err("Cannot close quotafile: %s",
					strerror(errno));
				ext2fs_free_mem(&ctx->quota_file[i]);
			}
		}
	}
	*qctx = NULL;
	free(ctx);
}

static struct dquot *get_dq(dict_t *dict, __u32 key)
{
	struct dquot	*dq;
	dnode_t		*n;

	n = dict_lookup(dict, UINT_TO_VOIDPTR(key));
	if (n)
		dq = dnode_get(n);
	else {
		if (ext2fs_get_mem(sizeof(struct dquot), &dq)) {
			log_err("Unable to allocate dquot");
			return NULL;
		}
		memset(dq, 0, sizeof(struct dquot));
		dict_alloc_insert(dict, UINT_TO_VOIDPTR(key), dq);
		dq->dq_id = key;
	}
	return dq;
}


/*
 * Called to update the blocks used by a particular inode
 */
void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
		    qsize_t space)
{
	struct dquot	*dq;
	dict_t		*dict;
	int		i;

	if (!qctx)
		return;

	log_debug("ADD_DATA: Inode: %u, UID/GID: %u/%u, space: %ld", ino,
			inode_uid(*inode),
			inode_gid(*inode), space);
	for (i = 0; i < MAXQUOTAS; i++) {
		dict = qctx->quota_dict[i];
		if (dict) {
			dq = get_dq(dict, get_qid(inode, i));
			if (dq)
				dq->dq_dqb.dqb_curspace += space;
		}
	}
}

/*
 * Called to remove some blocks used by a particular inode
 */
void quota_data_sub(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
		    qsize_t space)
{
	struct dquot	*dq;
	dict_t		*dict;
	int		i;

	if (!qctx)
		return;

	log_debug("SUB_DATA: Inode: %u, UID/GID: %u/%u, space: %ld", ino,
			inode_uid(*inode),
			inode_gid(*inode), space);
	for (i = 0; i < MAXQUOTAS; i++) {
		dict = qctx->quota_dict[i];
		if (dict) {
			dq = get_dq(dict, get_qid(inode, i));
			dq->dq_dqb.dqb_curspace -= space;
		}
	}
}

/*
 * Called to count the files used by an inode's user/group
 */
void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode *inode,
		       ext2_ino_t ino, int adjust)
{
	struct dquot	*dq;
	dict_t		*dict;
	int		i;

	if (!qctx)
		return;

	log_debug("ADJ_INODE: Inode: %u, UID/GID: %u/%u, adjust: %d", ino,
			inode_uid(*inode),
			inode_gid(*inode), adjust);
	for (i = 0; i < MAXQUOTAS; i++) {
		dict = qctx->quota_dict[i];
		if (dict) {
			dq = get_dq(dict, get_qid(inode, i));
			dq->dq_dqb.dqb_curinodes += adjust;
		}
	}
}

errcode_t quota_compute_usage(quota_ctx_t qctx)
{
	ext2_filsys fs;
	ext2_ino_t ino;
	errcode_t ret;
	struct ext2_inode inode;
	qsize_t space;
	ext2_inode_scan scan;

	if (!qctx)
		return 0;

	fs = qctx->fs;
	ret = ext2fs_open_inode_scan(fs, 0, &scan);
	if (ret) {
		log_err("while opening inode scan. ret=%ld", ret);
		return ret;
	}

	while (1) {
		ret = ext2fs_get_next_inode(scan, &ino, &inode);
		if (ret) {
			log_err("while getting next inode. ret=%ld", ret);
			ext2fs_close_inode_scan(scan);
			return ret;
		}
		if (ino == 0)
			break;
		if (inode.i_links_count &&
		    (ino == EXT2_ROOT_INO ||
		     ino >= EXT2_FIRST_INODE(fs->super))) {
			space = ext2fs_inode_i_blocks(fs, &inode) << 9;
			quota_data_add(qctx, &inode, ino, space);
			quota_data_inodes(qctx, &inode, ino, +1);
		}
	}

	ext2fs_close_inode_scan(scan);

	return 0;
}

struct scan_dquots_data {
	dict_t		*quota_dict;
	int             update_limits; /* update limits from disk */
	int		update_usage;
	int		usage_is_inconsistent;
};

static int scan_dquots_callback(struct dquot *dquot, void *cb_data)
{
	struct scan_dquots_data *scan_data = cb_data;
	dict_t *quota_dict = scan_data->quota_dict;
	struct dquot *dq;

	dq = get_dq(quota_dict, dquot->dq_id);
	dq->dq_id = dquot->dq_id;
	dq->dq_flags |= DQF_SEEN;

	print_dquot("mem", dq);
	print_dquot("dsk", dquot);

	/* Check if there is inconsistancy. */
	if (dq->dq_dqb.dqb_curspace != dquot->dq_dqb.dqb_curspace ||
	    dq->dq_dqb.dqb_curinodes != dquot->dq_dqb.dqb_curinodes) {
		scan_data->usage_is_inconsistent = 1;
		fprintf(stderr, "[QUOTA WARNING] Usage inconsistent for ID %d:"
			"actual (%llu, %llu) != expected (%llu, %llu)\n",
			dq->dq_id, (long long)dq->dq_dqb.dqb_curspace,
			(long long)dq->dq_dqb.dqb_curinodes,
			(long long)dquot->dq_dqb.dqb_curspace,
			(long long)dquot->dq_dqb.dqb_curinodes);
	}

	if (scan_data->update_limits) {
		dq->dq_dqb.dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit;
		dq->dq_dqb.dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit;
		dq->dq_dqb.dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit;
		dq->dq_dqb.dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit;
	}

	if (scan_data->update_usage) {
		dq->dq_dqb.dqb_curspace = dquot->dq_dqb.dqb_curspace;
		dq->dq_dqb.dqb_curinodes = dquot->dq_dqb.dqb_curinodes;
	}

	return 0;
}

/*
 * Read all dquots from quota file into memory
 */
static errcode_t quota_read_all_dquots(struct quota_handle *qh,
                                       quota_ctx_t qctx, int update_limits)
{
	struct scan_dquots_data scan_data;

	scan_data.quota_dict = qctx->quota_dict[qh->qh_type];
	scan_data.update_limits = update_limits;
	scan_data.update_usage = 0;

	return qh->qh_ops->scan_dquots(qh, scan_dquots_callback, &scan_data);
}

/*
 * Write all memory dquots into quota file
 */
#if 0 /* currently unused, but may be useful in the future? */
static errcode_t quota_write_all_dquots(struct quota_handle *qh,
                                        quota_ctx_t qctx)
{
	errcode_t err;

	err = ext2fs_read_bitmaps(qctx->fs);
	if (err)
		return err;
	write_dquots(qctx->quota_dict[qh->qh_type], qh);
	ext2fs_mark_bb_dirty(qctx->fs);
	qctx->fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
	ext2fs_write_bitmaps(qctx->fs);
	return 0;
}
#endif

/*
 * Updates the in-memory quota limits from the given quota inode.
 */
errcode_t quota_update_limits(quota_ctx_t qctx, ext2_ino_t qf_ino, int type)
{
	struct quota_handle *qh;
	errcode_t err;

	if (!qctx)
		return 0;

	err = ext2fs_get_mem(sizeof(struct quota_handle), &qh);
	if (err) {
		log_err("Unable to allocate quota handle");
		return err;
	}

	err = quota_file_open(qctx, qh, qf_ino, type, -1, 0);
	if (err) {
		log_err("Open quota file failed");
		goto out;
	}

	quota_read_all_dquots(qh, qctx, 1);

	err = quota_file_close(qctx, qh);
	if (err) {
		log_err("Cannot finish IO on new quotafile: %s",
			strerror(errno));
		if (qh->qh_qf.e2_file)
			ext2fs_file_close(qh->qh_qf.e2_file);
	}
out:
	ext2fs_free_mem(&qh);
	return err;
}

/*
 * Compares the measured quota in qctx->quota_dict with that in the quota inode
 * on disk and updates the limits in qctx->quota_dict. 'usage_inconsistent' is
 * set to 1 if the supplied and on-disk quota usage values are not identical.
 */
errcode_t quota_compare_and_update(quota_ctx_t qctx, int qtype,
				   int *usage_inconsistent)
{
	struct quota_handle qh;
	struct scan_dquots_data scan_data;
	struct dquot *dq;
	dnode_t *n;
	dict_t *dict = qctx->quota_dict[qtype];
	errcode_t err = 0;

	if (!dict)
		goto out;

	err = quota_file_open(qctx, &qh, 0, qtype, -1, 0);
	if (err) {
		log_err("Open quota file failed");
		goto out;
	}

	scan_data.quota_dict = qctx->quota_dict[qtype];
	scan_data.update_limits = 1;
	scan_data.update_usage = 0;
	scan_data.usage_is_inconsistent = 0;
	err = qh.qh_ops->scan_dquots(&qh, scan_dquots_callback, &scan_data);
	if (err) {
		log_err("Error scanning dquots");
		goto out_close_qh;
	}

	for (n = dict_first(dict); n; n = dict_next(dict, n)) {
		dq = dnode_get(n);
		if (!dq)
			continue;
		if ((dq->dq_flags & DQF_SEEN) == 0) {
			fprintf(stderr, "[QUOTA WARNING] "
				"Missing quota entry ID %d\n", dq->dq_id);
			scan_data.usage_is_inconsistent = 1;
		}
	}
	*usage_inconsistent = scan_data.usage_is_inconsistent;

out_close_qh:
	err = quota_file_close(qctx, &qh);
	if (err) {
		log_err("Cannot close quotafile: %s", error_message(errno));
		if (qh.qh_qf.e2_file)
			ext2fs_file_close(qh.qh_qf.e2_file);
	}
out:
	return err;
}
