/*
 *  Implementation of operations over global quota file
 */
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/quota.h>
#include <linux/quotaops.h>
#include <linux/dqblk_qtree.h>
#include <linux/jiffies.h>
#include <linux/writeback.h>
#include <linux/workqueue.h>

#define MLOG_MASK_PREFIX ML_QUOTA
#include <cluster/masklog.h>

#include "ocfs2_fs.h"
#include "ocfs2.h"
#include "alloc.h"
#include "blockcheck.h"
#include "inode.h"
#include "journal.h"
#include "file.h"
#include "sysfile.h"
#include "dlmglue.h"
#include "uptodate.h"
#include "super.h"
#include "buffer_head_io.h"
#include "quota.h"

/*
 * Locking of quotas with OCFS2 is rather complex. Here are rules that
 * should be obeyed by all the functions:
 * - any write of quota structure (either to local or global file) is protected
 *   by dqio_mutex or dquot->dq_lock.
 * - any modification of global quota file holds inode cluster lock, i_mutex,
 *   and ip_alloc_sem of the global quota file (achieved by
 *   ocfs2_lock_global_qf). It also has to hold qinfo_lock.
 * - an allocation of new blocks for local quota file is protected by
 *   its ip_alloc_sem
 *
 * A rough sketch of locking dependencies (lf = local file, gf = global file):
 * Normal filesystem operation:
 *   start_trans -> dqio_mutex -> write to lf
 * Syncing of local and global file:
 *   ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock ->
 *     write to gf
 *						       -> write to lf
 * Acquire dquot for the first time:
 *   dq_lock -> ocfs2_lock_global_qf -> qinfo_lock -> read from gf
 *				     -> alloc space for gf
 *				     -> start_trans -> qinfo_lock -> write to gf
 *	     -> ip_alloc_sem of lf -> alloc space for lf
 *	     -> write to lf
 * Release last reference to dquot:
 *   dq_lock -> ocfs2_lock_global_qf -> start_trans -> qinfo_lock -> write to gf
 *	     -> write to lf
 * Note that all the above operations also hold the inode cluster lock of lf.
 * Recovery:
 *   inode cluster lock of recovered lf
 *     -> read bitmaps -> ip_alloc_sem of lf
 *     -> ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock ->
 *        write to gf
 */

static struct workqueue_struct *ocfs2_quota_wq = NULL;

static void qsync_work_fn(struct work_struct *work);

static void ocfs2_global_disk2memdqb(struct dquot *dquot, void *dp)
{
	struct ocfs2_global_disk_dqblk *d = dp;
	struct mem_dqblk *m = &dquot->dq_dqb;

	/* Update from disk only entries not set by the admin */
	if (!test_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags)) {
		m->dqb_ihardlimit = le64_to_cpu(d->dqb_ihardlimit);
		m->dqb_isoftlimit = le64_to_cpu(d->dqb_isoftlimit);
	}
	if (!test_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags))
		m->dqb_curinodes = le64_to_cpu(d->dqb_curinodes);
	if (!test_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags)) {
		m->dqb_bhardlimit = le64_to_cpu(d->dqb_bhardlimit);
		m->dqb_bsoftlimit = le64_to_cpu(d->dqb_bsoftlimit);
	}
	if (!test_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags))
		m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
	if (!test_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags))
		m->dqb_btime = le64_to_cpu(d->dqb_btime);
	if (!test_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags))
		m->dqb_itime = le64_to_cpu(d->dqb_itime);
	OCFS2_DQUOT(dquot)->dq_use_count = le32_to_cpu(d->dqb_use_count);
}

static void ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot)
{
	struct ocfs2_global_disk_dqblk *d = dp;
	struct mem_dqblk *m = &dquot->dq_dqb;

	d->dqb_id = cpu_to_le32(dquot->dq_id);
	d->dqb_use_count = cpu_to_le32(OCFS2_DQUOT(dquot)->dq_use_count);
	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
	d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
	d->dqb_bhardlimit = cpu_to_le64(m->dqb_bhardlimit);
	d->dqb_bsoftlimit = cpu_to_le64(m->dqb_bsoftlimit);
	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
	d->dqb_btime = cpu_to_le64(m->dqb_btime);
	d->dqb_itime = cpu_to_le64(m->dqb_itime);
	d->dqb_pad1 = d->dqb_pad2 = 0;
}

static int ocfs2_global_is_id(void *dp, struct dquot *dquot)
{
	struct ocfs2_global_disk_dqblk *d = dp;
	struct ocfs2_mem_dqinfo *oinfo =
			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;

	if (qtree_entry_unused(&oinfo->dqi_gi, dp))
		return 0;
	return le32_to_cpu(d->dqb_id) == dquot->dq_id;
}

struct qtree_fmt_operations ocfs2_global_ops = {
	.mem2disk_dqblk = ocfs2_global_mem2diskdqb,
	.disk2mem_dqblk = ocfs2_global_disk2memdqb,
	.is_id = ocfs2_global_is_id,
};

int ocfs2_validate_quota_block(struct super_block *sb, struct buffer_head *bh)
{
	struct ocfs2_disk_dqtrailer *dqt =
		ocfs2_block_dqtrailer(sb->s_blocksize, bh->b_data);

	mlog(0, "Validating quota block %llu\n",
	     (unsigned long long)bh->b_blocknr);

	BUG_ON(!buffer_uptodate(bh));

	/*
	 * If the ecc fails, we return the error but otherwise
	 * leave the filesystem running.  We know any error is
	 * local to this block.
	 */
	return ocfs2_validate_meta_ecc(sb, bh->b_data, &dqt->dq_check);
}

int ocfs2_read_quota_phys_block(struct inode *inode, u64 p_block,
				struct buffer_head **bhp)
{
	int rc;

	*bhp = NULL;
	rc = ocfs2_read_blocks(INODE_CACHE(inode), p_block, 1, bhp, 0,
			       ocfs2_validate_quota_block);
	if (rc)
		mlog_errno(rc);
	return rc;
}

/* Read data from global quotafile - avoid pagecache and such because we cannot
 * afford acquiring the locks... We use quota cluster lock to serialize
 * operations. Caller is responsible for acquiring it. */
ssize_t ocfs2_quota_read(struct super_block *sb, int type, char *data,
			 size_t len, loff_t off)
{
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
	struct inode *gqinode = oinfo->dqi_gqinode;
	loff_t i_size = i_size_read(gqinode);
	int offset = off & (sb->s_blocksize - 1);
	sector_t blk = off >> sb->s_blocksize_bits;
	int err = 0;
	struct buffer_head *bh;
	size_t toread, tocopy;
	u64 pblock = 0, pcount = 0;

	if (off > i_size)
		return 0;
	if (off + len > i_size)
		len = i_size - off;
	toread = len;
	while (toread > 0) {
		tocopy = min_t(size_t, (sb->s_blocksize - offset), toread);
		if (!pcount) {
			err = ocfs2_extent_map_get_blocks(gqinode, blk, &pblock,
							  &pcount, NULL);
			if (err) {
				mlog_errno(err);
				return err;
			}
		} else {
			pcount--;
			pblock++;
		}
		bh = NULL;
		err = ocfs2_read_quota_phys_block(gqinode, pblock, &bh);
		if (err) {
			mlog_errno(err);
			return err;
		}
		memcpy(data, bh->b_data + offset, tocopy);
		brelse(bh);
		offset = 0;
		toread -= tocopy;
		data += tocopy;
		blk++;
	}
	return len;
}

/* Write to quotafile (we know the transaction is already started and has
 * enough credits) */
ssize_t ocfs2_quota_write(struct super_block *sb, int type,
			  const char *data, size_t len, loff_t off)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct inode *gqinode = oinfo->dqi_gqinode;
	int offset = off & (sb->s_blocksize - 1);
	sector_t blk = off >> sb->s_blocksize_bits;
	int err = 0, new = 0, ja_type;
	struct buffer_head *bh = NULL;
	handle_t *handle = journal_current_handle();
	u64 pblock, pcount;

	if (!handle) {
		mlog(ML_ERROR, "Quota write (off=%llu, len=%llu) cancelled "
		     "because transaction was not started.\n",
		     (unsigned long long)off, (unsigned long long)len);
		return -EIO;
	}
	if (len > sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE - offset) {
		WARN_ON(1);
		len = sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE - offset;
	}

	if (gqinode->i_size < off + len) {
		loff_t rounded_end =
				ocfs2_align_bytes_to_blocks(sb, off + len);

		/* Space is already allocated in ocfs2_acquire_dquot() */
		err = ocfs2_simple_size_update(gqinode,
					       oinfo->dqi_gqi_bh,
					       rounded_end);
		if (err < 0)
			goto out;
		new = 1;
	}
	err = ocfs2_extent_map_get_blocks(gqinode, blk, &pblock, &pcount, NULL);
	if (err) {
		mlog_errno(err);
		goto out;
	}
	/* Not rewriting whole block? */
	if ((offset || len < sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) &&
	    !new) {
		err = ocfs2_read_quota_phys_block(gqinode, pblock, &bh);
		ja_type = OCFS2_JOURNAL_ACCESS_WRITE;
	} else {
		bh = sb_getblk(sb, pblock);
		if (!bh)
			err = -ENOMEM;
		ja_type = OCFS2_JOURNAL_ACCESS_CREATE;
	}
	if (err) {
		mlog_errno(err);
		goto out;
	}
	lock_buffer(bh);
	if (new)
		memset(bh->b_data, 0, sb->s_blocksize);
	memcpy(bh->b_data + offset, data, len);
	flush_dcache_page(bh->b_page);
	set_buffer_uptodate(bh);
	unlock_buffer(bh);
	ocfs2_set_buffer_uptodate(INODE_CACHE(gqinode), bh);
	err = ocfs2_journal_access_dq(handle, INODE_CACHE(gqinode), bh,
				      ja_type);
	if (err < 0) {
		brelse(bh);
		goto out;
	}
	ocfs2_journal_dirty(handle, bh);
	brelse(bh);
out:
	if (err) {
		mlog_errno(err);
		return err;
	}
	gqinode->i_version++;
	ocfs2_mark_inode_dirty(handle, gqinode, oinfo->dqi_gqi_bh);
	return len;
}

int ocfs2_lock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
{
	int status;
	struct buffer_head *bh = NULL;

	status = ocfs2_inode_lock(oinfo->dqi_gqinode, &bh, ex);
	if (status < 0)
		return status;
	spin_lock(&dq_data_lock);
	if (!oinfo->dqi_gqi_count++)
		oinfo->dqi_gqi_bh = bh;
	else
		WARN_ON(bh != oinfo->dqi_gqi_bh);
	spin_unlock(&dq_data_lock);
	if (ex) {
		mutex_lock(&oinfo->dqi_gqinode->i_mutex);
		down_write(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
	} else {
		down_read(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
	}
	return 0;
}

void ocfs2_unlock_global_qf(struct ocfs2_mem_dqinfo *oinfo, int ex)
{
	if (ex) {
		up_write(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
		mutex_unlock(&oinfo->dqi_gqinode->i_mutex);
	} else {
		up_read(&OCFS2_I(oinfo->dqi_gqinode)->ip_alloc_sem);
	}
	ocfs2_inode_unlock(oinfo->dqi_gqinode, ex);
	brelse(oinfo->dqi_gqi_bh);
	spin_lock(&dq_data_lock);
	if (!--oinfo->dqi_gqi_count)
		oinfo->dqi_gqi_bh = NULL;
	spin_unlock(&dq_data_lock);
}

/* Read information header from global quota file */
int ocfs2_global_read_info(struct super_block *sb, int type)
{
	struct inode *gqinode = NULL;
	unsigned int ino[MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
					GROUP_QUOTA_SYSTEM_INODE };
	struct ocfs2_global_disk_dqinfo dinfo;
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	u64 pcount;
	int status;

	/* Read global header */
	gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
			OCFS2_INVALID_SLOT);
	if (!gqinode) {
		mlog(ML_ERROR, "failed to get global quota inode (type=%d)\n",
			type);
		status = -EINVAL;
		goto out_err;
	}
	oinfo->dqi_gi.dqi_sb = sb;
	oinfo->dqi_gi.dqi_type = type;
	ocfs2_qinfo_lock_res_init(&oinfo->dqi_gqlock, oinfo);
	oinfo->dqi_gi.dqi_entry_size = sizeof(struct ocfs2_global_disk_dqblk);
	oinfo->dqi_gi.dqi_ops = &ocfs2_global_ops;
	oinfo->dqi_gqi_bh = NULL;
	oinfo->dqi_gqi_count = 0;
	oinfo->dqi_gqinode = gqinode;
	status = ocfs2_lock_global_qf(oinfo, 0);
	if (status < 0) {
		mlog_errno(status);
		goto out_err;
	}

	status = ocfs2_extent_map_get_blocks(gqinode, 0, &oinfo->dqi_giblk,
					     &pcount, NULL);
	if (status < 0)
		goto out_unlock;

	status = ocfs2_qinfo_lock(oinfo, 0);
	if (status < 0)
		goto out_unlock;
	status = sb->s_op->quota_read(sb, type, (char *)&dinfo,
				      sizeof(struct ocfs2_global_disk_dqinfo),
				      OCFS2_GLOBAL_INFO_OFF);
	ocfs2_qinfo_unlock(oinfo, 0);
	ocfs2_unlock_global_qf(oinfo, 0);
	if (status != sizeof(struct ocfs2_global_disk_dqinfo)) {
		mlog(ML_ERROR, "Cannot read global quota info (%d).\n",
		     status);
		if (status >= 0)
			status = -EIO;
		mlog_errno(status);
		goto out_err;
	}
	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
	oinfo->dqi_syncms = le32_to_cpu(dinfo.dqi_syncms);
	oinfo->dqi_gi.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
	oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
	oinfo->dqi_gi.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
	oinfo->dqi_gi.dqi_blocksize_bits = sb->s_blocksize_bits;
	oinfo->dqi_gi.dqi_usable_bs = sb->s_blocksize -
						OCFS2_QBLK_RESERVED_SPACE;
	oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi);
	INIT_DELAYED_WORK(&oinfo->dqi_sync_work, qsync_work_fn);
	queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work,
			   msecs_to_jiffies(oinfo->dqi_syncms));

out_err:
	if (status)
		mlog_errno(status);
	return status;
out_unlock:
	ocfs2_unlock_global_qf(oinfo, 0);
	mlog_errno(status);
	goto out_err;
}

/* Write information to global quota file. Expects exlusive lock on quota
 * file inode and quota info */
static int __ocfs2_global_write_info(struct super_block *sb, int type)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct ocfs2_global_disk_dqinfo dinfo;
	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);
	spin_unlock(&dq_data_lock);
	dinfo.dqi_syncms = cpu_to_le32(oinfo->dqi_syncms);
	dinfo.dqi_blocks = cpu_to_le32(oinfo->dqi_gi.dqi_blocks);
	dinfo.dqi_free_blk = cpu_to_le32(oinfo->dqi_gi.dqi_free_blk);
	dinfo.dqi_free_entry = cpu_to_le32(oinfo->dqi_gi.dqi_free_entry);
	size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
				     sizeof(struct ocfs2_global_disk_dqinfo),
				     OCFS2_GLOBAL_INFO_OFF);
	if (size != sizeof(struct ocfs2_global_disk_dqinfo)) {
		mlog(ML_ERROR, "Cannot write global quota info structure\n");
		if (size >= 0)
			size = -EIO;
		return size;
	}
	return 0;
}

int ocfs2_global_write_info(struct super_block *sb, int type)
{
	int err;
	struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;

	err = ocfs2_qinfo_lock(info, 1);
	if (err < 0)
		return err;
	err = __ocfs2_global_write_info(sb, type);
	ocfs2_qinfo_unlock(info, 1);
	return err;
}

static int ocfs2_global_qinit_alloc(struct super_block *sb, int type)
{
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;

	/*
	 * We may need to allocate tree blocks and a leaf block but not the
	 * root block
	 */
	return oinfo->dqi_gi.dqi_qtree_depth;
}

static int ocfs2_calc_global_qinit_credits(struct super_block *sb, int type)
{
	/* We modify all the allocated blocks, tree root, info block and
	 * the inode */
	return (ocfs2_global_qinit_alloc(sb, type) + 2) *
			OCFS2_QUOTA_BLOCK_UPDATE_CREDITS + 1;
}

/* Sync local information about quota modifications with global quota file.
 * Caller must have started the transaction and obtained exclusive lock for
 * global quota file inode */
int __ocfs2_sync_dquot(struct dquot *dquot, int freeing)
{
	int err, err2;
	struct super_block *sb = dquot->dq_sb;
	int type = dquot->dq_type;
	struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;
	struct ocfs2_global_disk_dqblk dqblk;
	s64 spacechange, inodechange;
	time_t olditime, oldbtime;

	err = sb->s_op->quota_read(sb, type, (char *)&dqblk,
				   sizeof(struct ocfs2_global_disk_dqblk),
				   dquot->dq_off);
	if (err != sizeof(struct ocfs2_global_disk_dqblk)) {
		if (err >= 0) {
			mlog(ML_ERROR, "Short read from global quota file "
				       "(%u read)\n", err);
			err = -EIO;
		}
		goto out;
	}

	/* Update space and inode usage. Get also other information from
	 * global quota file so that we don't overwrite any changes there.
	 * We are */
	spin_lock(&dq_data_lock);
	spacechange = dquot->dq_dqb.dqb_curspace -
					OCFS2_DQUOT(dquot)->dq_origspace;
	inodechange = dquot->dq_dqb.dqb_curinodes -
					OCFS2_DQUOT(dquot)->dq_originodes;
	olditime = dquot->dq_dqb.dqb_itime;
	oldbtime = dquot->dq_dqb.dqb_btime;
	ocfs2_global_disk2memdqb(dquot, &dqblk);
	mlog(0, "Syncing global dquot %u space %lld+%lld, inodes %lld+%lld\n",
	     dquot->dq_id, dquot->dq_dqb.dqb_curspace, (long long)spacechange,
	     dquot->dq_dqb.dqb_curinodes, (long long)inodechange);
	if (!test_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags))
		dquot->dq_dqb.dqb_curspace += spacechange;
	if (!test_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags))
		dquot->dq_dqb.dqb_curinodes += inodechange;
	/* Set properly space grace time... */
	if (dquot->dq_dqb.dqb_bsoftlimit &&
	    dquot->dq_dqb.dqb_curspace > dquot->dq_dqb.dqb_bsoftlimit) {
		if (!test_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags) &&
		    oldbtime > 0) {
			if (dquot->dq_dqb.dqb_btime > 0)
				dquot->dq_dqb.dqb_btime =
					min(dquot->dq_dqb.dqb_btime, oldbtime);
			else
				dquot->dq_dqb.dqb_btime = oldbtime;
		}
	} else {
		dquot->dq_dqb.dqb_btime = 0;
		clear_bit(DQ_BLKS_B, &dquot->dq_flags);
	}
	/* Set properly inode grace time... */
	if (dquot->dq_dqb.dqb_isoftlimit &&
	    dquot->dq_dqb.dqb_curinodes > dquot->dq_dqb.dqb_isoftlimit) {
		if (!test_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags) &&
		    olditime > 0) {
			if (dquot->dq_dqb.dqb_itime > 0)
				dquot->dq_dqb.dqb_itime =
					min(dquot->dq_dqb.dqb_itime, olditime);
			else
				dquot->dq_dqb.dqb_itime = olditime;
		}
	} else {
		dquot->dq_dqb.dqb_itime = 0;
		clear_bit(DQ_INODES_B, &dquot->dq_flags);
	}
	/* All information is properly updated, clear the flags */
	__clear_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
	__clear_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
	__clear_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
	__clear_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
	__clear_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
	__clear_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
	OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace;
	OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes;
	spin_unlock(&dq_data_lock);
	err = ocfs2_qinfo_lock(info, freeing);
	if (err < 0) {
		mlog(ML_ERROR, "Failed to lock quota info, loosing quota write"
			       " (type=%d, id=%u)\n", dquot->dq_type,
			       (unsigned)dquot->dq_id);
		goto out;
	}
	if (freeing)
		OCFS2_DQUOT(dquot)->dq_use_count--;
	err = qtree_write_dquot(&info->dqi_gi, dquot);
	if (err < 0)
		goto out_qlock;
	if (freeing && !OCFS2_DQUOT(dquot)->dq_use_count) {
		err = qtree_release_dquot(&info->dqi_gi, dquot);
		if (info_dirty(sb_dqinfo(sb, type))) {
			err2 = __ocfs2_global_write_info(sb, type);
			if (!err)
				err = err2;
		}
	}
out_qlock:
	ocfs2_qinfo_unlock(info, freeing);
out:
	if (err < 0)
		mlog_errno(err);
	return err;
}

/*
 *  Functions for periodic syncing of dquots with global file
 */
static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
{
	handle_t *handle;
	struct super_block *sb = dquot->dq_sb;
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
	struct ocfs2_super *osb = OCFS2_SB(sb);
	int status = 0;

	mlog(0, "id=%u qtype=%u type=%lu device=%s\n", dquot->dq_id,
		   dquot->dq_type, type, sb->s_id);
	if (type != dquot->dq_type)
		goto out;
	status = ocfs2_lock_global_qf(oinfo, 1);
	if (status < 0)
		goto out;

	handle = ocfs2_start_trans(osb, OCFS2_QSYNC_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out_ilock;
	}
	mutex_lock(&sb_dqopt(sb)->dqio_mutex);
	status = ocfs2_sync_dquot(dquot);
	if (status < 0)
		mlog_errno(status);
	/* We have to write local structure as well... */
	status = ocfs2_local_write_dquot(dquot);
	if (status < 0)
		mlog_errno(status);
	mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
	ocfs2_commit_trans(osb, handle);
out_ilock:
	ocfs2_unlock_global_qf(oinfo, 1);
out:
	return status;
}

static void qsync_work_fn(struct work_struct *work)
{
	struct ocfs2_mem_dqinfo *oinfo = container_of(work,
						      struct ocfs2_mem_dqinfo,
						      dqi_sync_work.work);
	struct super_block *sb = oinfo->dqi_gqinode->i_sb;

	dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
	queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work,
			   msecs_to_jiffies(oinfo->dqi_syncms));
}

/*
 *  Wrappers for generic quota functions
 */

static int ocfs2_write_dquot(struct dquot *dquot)
{
	handle_t *handle;
	struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
	int status = 0;

	mlog(0, "id=%u, type=%d", dquot->dq_id, dquot->dq_type);

	handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out;
	}
	mutex_lock(&sb_dqopt(dquot->dq_sb)->dqio_mutex);
	status = ocfs2_local_write_dquot(dquot);
	mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex);
	ocfs2_commit_trans(osb, handle);
out:
	return status;
}

static int ocfs2_calc_qdel_credits(struct super_block *sb, int type)
{
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
	/*
	 * We modify tree, leaf block, global info, local chunk header,
	 * global and local inode; OCFS2_QINFO_WRITE_CREDITS already
	 * accounts for inode update
	 */
	return (oinfo->dqi_gi.dqi_qtree_depth + 2) *
	       OCFS2_QUOTA_BLOCK_UPDATE_CREDITS +
	       OCFS2_QINFO_WRITE_CREDITS +
	       OCFS2_INODE_UPDATE_CREDITS;
}

static int ocfs2_release_dquot(struct dquot *dquot)
{
	handle_t *handle;
	struct ocfs2_mem_dqinfo *oinfo =
			sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
	struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
	int status = 0;

	mlog(0, "id=%u, type=%d", dquot->dq_id, dquot->dq_type);

	mutex_lock(&dquot->dq_lock);
	/* Check whether we are not racing with some other dqget() */
	if (atomic_read(&dquot->dq_count) > 1)
		goto out;
	status = ocfs2_lock_global_qf(oinfo, 1);
	if (status < 0)
		goto out;
	handle = ocfs2_start_trans(osb,
		ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_type));
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out_ilock;
	}

	status = ocfs2_global_release_dquot(dquot);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	status = ocfs2_local_release_dquot(handle, dquot);
	/*
	 * If we fail here, we cannot do much as global structure is
	 * already released. So just complain...
	 */
	if (status < 0)
		mlog_errno(status);
	clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
out_trans:
	ocfs2_commit_trans(osb, handle);
out_ilock:
	ocfs2_unlock_global_qf(oinfo, 1);
out:
	mutex_unlock(&dquot->dq_lock);
	if (status)
		mlog_errno(status);
	return status;
}

/*
 * Read global dquot structure from disk or create it if it does
 * not exist. Also update use count of the global structure and
 * create structure in node-local quota file.
 */
static int ocfs2_acquire_dquot(struct dquot *dquot)
{
	int status = 0, err;
	int ex = 0;
	struct super_block *sb = dquot->dq_sb;
	struct ocfs2_super *osb = OCFS2_SB(sb);
	int type = dquot->dq_type;
	struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;
	struct inode *gqinode = info->dqi_gqinode;
	int need_alloc = ocfs2_global_qinit_alloc(sb, type);
	handle_t *handle;

	mlog(0, "id=%u, type=%d", dquot->dq_id, type);
	mutex_lock(&dquot->dq_lock);
	/*
	 * We need an exclusive lock, because we're going to update use count
	 * and instantiate possibly new dquot structure
	 */
	status = ocfs2_lock_global_qf(info, 1);
	if (status < 0)
		goto out;
	if (!test_bit(DQ_READ_B, &dquot->dq_flags)) {
		status = ocfs2_qinfo_lock(info, 0);
		if (status < 0)
			goto out_dq;
		status = qtree_read_dquot(&info->dqi_gi, dquot);
		ocfs2_qinfo_unlock(info, 0);
		if (status < 0)
			goto out_dq;
	}
	set_bit(DQ_READ_B, &dquot->dq_flags);

	OCFS2_DQUOT(dquot)->dq_use_count++;
	OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace;
	OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes;
	if (!dquot->dq_off) {	/* No real quota entry? */
		ex = 1;
		/*
		 * Add blocks to quota file before we start a transaction since
		 * locking allocators ranks above a transaction start
		 */
		WARN_ON(journal_current_handle());
		status = ocfs2_extend_no_holes(gqinode, NULL,
			gqinode->i_size + (need_alloc << sb->s_blocksize_bits),
			gqinode->i_size);
		if (status < 0)
			goto out_dq;
	}

	handle = ocfs2_start_trans(osb,
				   ocfs2_calc_global_qinit_credits(sb, type));
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		goto out_dq;
	}
	status = ocfs2_qinfo_lock(info, ex);
	if (status < 0)
		goto out_trans;
	status = qtree_write_dquot(&info->dqi_gi, dquot);
	if (ex && info_dirty(sb_dqinfo(sb, type))) {
		err = __ocfs2_global_write_info(sb, type);
		if (!status)
			status = err;
	}
	ocfs2_qinfo_unlock(info, ex);
out_trans:
	ocfs2_commit_trans(osb, handle);
out_dq:
	ocfs2_unlock_global_qf(info, 1);
	if (status < 0)
		goto out;

	status = ocfs2_create_local_dquot(dquot);
	if (status < 0)
		goto out;
	set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
out:
	mutex_unlock(&dquot->dq_lock);
	if (status)
		mlog_errno(status);
	return status;
}

static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
{
	unsigned long mask = (1 << (DQ_LASTSET_B + QIF_ILIMITS_B)) |
			     (1 << (DQ_LASTSET_B + QIF_BLIMITS_B)) |
			     (1 << (DQ_LASTSET_B + QIF_INODES_B)) |
			     (1 << (DQ_LASTSET_B + QIF_SPACE_B)) |
			     (1 << (DQ_LASTSET_B + QIF_BTIME_B)) |
			     (1 << (DQ_LASTSET_B + QIF_ITIME_B));
	int sync = 0;
	int status;
	struct super_block *sb = dquot->dq_sb;
	int type = dquot->dq_type;
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
	handle_t *handle;
	struct ocfs2_super *osb = OCFS2_SB(sb);

	mlog(0, "id=%u, type=%d", dquot->dq_id, type);

	/* In case user set some limits, sync dquot immediately to global
	 * quota file so that information propagates quicker */
	spin_lock(&dq_data_lock);
	if (dquot->dq_flags & mask)
		sync = 1;
	spin_unlock(&dq_data_lock);
	/* This is a slight hack but we can't afford getting global quota
	 * lock if we already have a transaction started. */
	if (!sync || journal_current_handle()) {
		status = ocfs2_write_dquot(dquot);
		goto out;
	}
	status = ocfs2_lock_global_qf(oinfo, 1);
	if (status < 0)
		goto out;
	handle = ocfs2_start_trans(osb, OCFS2_QSYNC_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out_ilock;
	}
	mutex_lock(&sb_dqopt(sb)->dqio_mutex);
	status = ocfs2_sync_dquot(dquot);
	if (status < 0) {
		mlog_errno(status);
		goto out_dlock;
	}
	/* Now write updated local dquot structure */
	status = ocfs2_local_write_dquot(dquot);
out_dlock:
	mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
	ocfs2_commit_trans(osb, handle);
out_ilock:
	ocfs2_unlock_global_qf(oinfo, 1);
out:
	if (status)
		mlog_errno(status);
	return status;
}

/* This should happen only after set_dqinfo(). */
static int ocfs2_write_info(struct super_block *sb, int type)
{
	handle_t *handle;
	int status = 0;
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;

	status = ocfs2_lock_global_qf(oinfo, 1);
	if (status < 0)
		goto out;
	handle = ocfs2_start_trans(OCFS2_SB(sb), OCFS2_QINFO_WRITE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out_ilock;
	}
	status = dquot_commit_info(sb, type);
	ocfs2_commit_trans(OCFS2_SB(sb), handle);
out_ilock:
	ocfs2_unlock_global_qf(oinfo, 1);
out:
	if (status)
		mlog_errno(status);
	return status;
}

static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type)
{
	struct ocfs2_dquot *dquot =
				kmem_cache_zalloc(ocfs2_dquot_cachep, GFP_NOFS);

	if (!dquot)
		return NULL;
	return &dquot->dq_dquot;
}

static void ocfs2_destroy_dquot(struct dquot *dquot)
{
	kmem_cache_free(ocfs2_dquot_cachep, dquot);
}

const struct dquot_operations ocfs2_quota_operations = {
	/* We never make dquot dirty so .write_dquot is never called */
	.acquire_dquot	= ocfs2_acquire_dquot,
	.release_dquot	= ocfs2_release_dquot,
	.mark_dirty	= ocfs2_mark_dquot_dirty,
	.write_info	= ocfs2_write_info,
	.alloc_dquot	= ocfs2_alloc_dquot,
	.destroy_dquot	= ocfs2_destroy_dquot,
};

int ocfs2_quota_setup(void)
{
	ocfs2_quota_wq = create_workqueue("o2quot");
	if (!ocfs2_quota_wq)
		return -ENOMEM;
	return 0;
}

void ocfs2_quota_shutdown(void)
{
	if (ocfs2_quota_wq) {
		flush_workqueue(ocfs2_quota_wq);
		destroy_workqueue(ocfs2_quota_wq);
		ocfs2_quota_wq = NULL;
	}
}
