/*
 *  Implementation of operations over local quota file
 */

#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/quota.h>
#include <linux/quotaops.h>
#include <linux/module.h>

#include <cluster/masklog.h>

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

/* Number of local quota structures per block */
static inline unsigned int ol_quota_entries_per_block(struct super_block *sb)
{
	return ((sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) /
		sizeof(struct ocfs2_local_disk_dqblk));
}

/* Number of blocks with entries in one chunk */
static inline unsigned int ol_chunk_blocks(struct super_block *sb)
{
	return ((sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
		 OCFS2_QBLK_RESERVED_SPACE) << 3) /
	       ol_quota_entries_per_block(sb);
}

/* Number of entries in a chunk bitmap */
static unsigned int ol_chunk_entries(struct super_block *sb)
{
	return ol_chunk_blocks(sb) * ol_quota_entries_per_block(sb);
}

/* Offset of the chunk in quota file */
static unsigned int ol_quota_chunk_block(struct super_block *sb, int c)
{
	/* 1 block for local quota file info, 1 block per chunk for chunk info */
	return 1 + (ol_chunk_blocks(sb) + 1) * c;
}

static unsigned int ol_dqblk_block(struct super_block *sb, int c, int off)
{
	int epb = ol_quota_entries_per_block(sb);

	return ol_quota_chunk_block(sb, c) + 1 + off / epb;
}

static unsigned int ol_dqblk_block_off(struct super_block *sb, int c, int off)
{
	int epb = ol_quota_entries_per_block(sb);

	return (off % epb) * sizeof(struct ocfs2_local_disk_dqblk);
}

/* Offset of the dquot structure in the quota file */
static loff_t ol_dqblk_off(struct super_block *sb, int c, int off)
{
	return (ol_dqblk_block(sb, c, off) << sb->s_blocksize_bits) +
	       ol_dqblk_block_off(sb, c, off);
}

static inline unsigned int ol_dqblk_block_offset(struct super_block *sb, loff_t off)
{
	return off & ((1 << sb->s_blocksize_bits) - 1);
}

/* Compute offset in the chunk of a structure with the given offset */
static int ol_dqblk_chunk_off(struct super_block *sb, int c, loff_t off)
{
	int epb = ol_quota_entries_per_block(sb);

	return ((off >> sb->s_blocksize_bits) -
			ol_quota_chunk_block(sb, c) - 1) * epb
	       + ((unsigned int)(off & ((1 << sb->s_blocksize_bits) - 1))) /
		 sizeof(struct ocfs2_local_disk_dqblk);
}

/* Write bufferhead into the fs */
static int ocfs2_modify_bh(struct inode *inode, struct buffer_head *bh,
		void (*modify)(struct buffer_head *, void *), void *private)
{
	struct super_block *sb = inode->i_sb;
	handle_t *handle;
	int status;

	handle = ocfs2_start_trans(OCFS2_SB(sb),
				   OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		return status;
	}
	status = ocfs2_journal_access_dq(handle, INODE_CACHE(inode), bh,
					 OCFS2_JOURNAL_ACCESS_WRITE);
	if (status < 0) {
		mlog_errno(status);
		ocfs2_commit_trans(OCFS2_SB(sb), handle);
		return status;
	}
	lock_buffer(bh);
	modify(bh, private);
	unlock_buffer(bh);
	ocfs2_journal_dirty(handle, bh);

	status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
	if (status < 0) {
		mlog_errno(status);
		return status;
	}
	return 0;
}

/*
 * Read quota block from a given logical offset.
 *
 * This function acquires ip_alloc_sem and thus it must not be called with a
 * transaction started.
 */
static int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
				  struct buffer_head **bh)
{
	int rc = 0;
	struct buffer_head *tmp = *bh;

	if (i_size_read(inode) >> inode->i_sb->s_blocksize_bits <= v_block) {
		ocfs2_error(inode->i_sb,
			    "Quota file %llu is probably corrupted! Requested to read block %Lu but file has size only %Lu\n",
			    (unsigned long long)OCFS2_I(inode)->ip_blkno,
			    (unsigned long long)v_block,
			    (unsigned long long)i_size_read(inode));
		return -EIO;
	}
	rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0,
				    ocfs2_validate_quota_block);
	if (rc)
		mlog_errno(rc);

	/* If ocfs2_read_virt_blocks() got us a new bh, pass it up. */
	if (!rc && !*bh)
		*bh = tmp;

	return rc;
}

/* Check whether we understand format of quota files */
static int ocfs2_local_check_quota_file(struct super_block *sb, int type)
{
	unsigned int lmagics[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QMAGICS;
	unsigned int lversions[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QVERSIONS;
	unsigned int gmagics[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QMAGICS;
	unsigned int gversions[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QVERSIONS;
	unsigned int ino[OCFS2_MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
					      GROUP_QUOTA_SYSTEM_INODE };
	struct buffer_head *bh = NULL;
	struct inode *linode = sb_dqopt(sb)->files[type];
	struct inode *ginode = NULL;
	struct ocfs2_disk_dqheader *dqhead;
	int status, ret = 0;

	/* First check whether we understand local quota file */
	status = ocfs2_read_quota_block(linode, 0, &bh);
	if (status) {
		mlog_errno(status);
		mlog(ML_ERROR, "failed to read quota file header (type=%d)\n",
			type);
		goto out_err;
	}
	dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
	if (le32_to_cpu(dqhead->dqh_magic) != lmagics[type]) {
		mlog(ML_ERROR, "quota file magic does not match (%u != %u),"
			" type=%d\n", le32_to_cpu(dqhead->dqh_magic),
			lmagics[type], type);
		goto out_err;
	}
	if (le32_to_cpu(dqhead->dqh_version) != lversions[type]) {
		mlog(ML_ERROR, "quota file version does not match (%u != %u),"
			" type=%d\n", le32_to_cpu(dqhead->dqh_version),
			lversions[type], type);
		goto out_err;
	}
	brelse(bh);
	bh = NULL;

	/* Next check whether we understand global quota file */
	ginode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
						OCFS2_INVALID_SLOT);
	if (!ginode) {
		mlog(ML_ERROR, "cannot get global quota file inode "
				"(type=%d)\n", type);
		goto out_err;
	}
	/* Since the header is read only, we don't care about locking */
	status = ocfs2_read_quota_block(ginode, 0, &bh);
	if (status) {
		mlog_errno(status);
		mlog(ML_ERROR, "failed to read global quota file header "
				"(type=%d)\n", type);
		goto out_err;
	}
	dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
	if (le32_to_cpu(dqhead->dqh_magic) != gmagics[type]) {
		mlog(ML_ERROR, "global quota file magic does not match "
			"(%u != %u), type=%d\n",
			le32_to_cpu(dqhead->dqh_magic), gmagics[type], type);
		goto out_err;
	}
	if (le32_to_cpu(dqhead->dqh_version) != gversions[type]) {
		mlog(ML_ERROR, "global quota file version does not match "
			"(%u != %u), type=%d\n",
			le32_to_cpu(dqhead->dqh_version), gversions[type],
			type);
		goto out_err;
	}

	ret = 1;
out_err:
	brelse(bh);
	iput(ginode);
	return ret;
}

/* Release given list of quota file chunks */
static void ocfs2_release_local_quota_bitmaps(struct list_head *head)
{
	struct ocfs2_quota_chunk *pos, *next;

	list_for_each_entry_safe(pos, next, head, qc_chunk) {
		list_del(&pos->qc_chunk);
		brelse(pos->qc_headerbh);
		kmem_cache_free(ocfs2_qf_chunk_cachep, pos);
	}
}

/* Load quota bitmaps into memory */
static int ocfs2_load_local_quota_bitmaps(struct inode *inode,
			struct ocfs2_local_disk_dqinfo *ldinfo,
			struct list_head *head)
{
	struct ocfs2_quota_chunk *newchunk;
	int i, status;

	INIT_LIST_HEAD(head);
	for (i = 0; i < le32_to_cpu(ldinfo->dqi_chunks); i++) {
		newchunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
		if (!newchunk) {
			ocfs2_release_local_quota_bitmaps(head);
			return -ENOMEM;
		}
		newchunk->qc_num = i;
		newchunk->qc_headerbh = NULL;
		status = ocfs2_read_quota_block(inode,
				ol_quota_chunk_block(inode->i_sb, i),
				&newchunk->qc_headerbh);
		if (status) {
			mlog_errno(status);
			kmem_cache_free(ocfs2_qf_chunk_cachep, newchunk);
			ocfs2_release_local_quota_bitmaps(head);
			return status;
		}
		list_add_tail(&newchunk->qc_chunk, head);
	}
	return 0;
}

static void olq_update_info(struct buffer_head *bh, void *private)
{
	struct mem_dqinfo *info = private;
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct ocfs2_local_disk_dqinfo *ldinfo;

	ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
						OCFS2_LOCAL_INFO_OFF);
	spin_lock(&dq_data_lock);
	ldinfo->dqi_flags = cpu_to_le32(oinfo->dqi_flags);
	ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
	ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
	spin_unlock(&dq_data_lock);
}

static int ocfs2_add_recovery_chunk(struct super_block *sb,
				    struct ocfs2_local_disk_chunk *dchunk,
				    int chunk,
				    struct list_head *head)
{
	struct ocfs2_recovery_chunk *rc;

	rc = kmalloc(sizeof(struct ocfs2_recovery_chunk), GFP_NOFS);
	if (!rc)
		return -ENOMEM;
	rc->rc_chunk = chunk;
	rc->rc_bitmap = kmalloc(sb->s_blocksize, GFP_NOFS);
	if (!rc->rc_bitmap) {
		kfree(rc);
		return -ENOMEM;
	}
	memcpy(rc->rc_bitmap, dchunk->dqc_bitmap,
	       (ol_chunk_entries(sb) + 7) >> 3);
	list_add_tail(&rc->rc_list, head);
	return 0;
}

static void free_recovery_list(struct list_head *head)
{
	struct ocfs2_recovery_chunk *next;
	struct ocfs2_recovery_chunk *rchunk;

	list_for_each_entry_safe(rchunk, next, head, rc_list) {
		list_del(&rchunk->rc_list);
		kfree(rchunk->rc_bitmap);
		kfree(rchunk);
	}
}

void ocfs2_free_quota_recovery(struct ocfs2_quota_recovery *rec)
{
	int type;

	for (type = 0; type < OCFS2_MAXQUOTAS; type++)
		free_recovery_list(&(rec->r_list[type]));
	kfree(rec);
}

/* Load entries in our quota file we have to recover*/
static int ocfs2_recovery_load_quota(struct inode *lqinode,
				     struct ocfs2_local_disk_dqinfo *ldinfo,
				     int type,
				     struct list_head *head)
{
	struct super_block *sb = lqinode->i_sb;
	struct buffer_head *hbh;
	struct ocfs2_local_disk_chunk *dchunk;
	int i, chunks = le32_to_cpu(ldinfo->dqi_chunks);
	int status = 0;

	for (i = 0; i < chunks; i++) {
		hbh = NULL;
		status = ocfs2_read_quota_block(lqinode,
						ol_quota_chunk_block(sb, i),
						&hbh);
		if (status) {
			mlog_errno(status);
			break;
		}
		dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
		if (le32_to_cpu(dchunk->dqc_free) < ol_chunk_entries(sb))
			status = ocfs2_add_recovery_chunk(sb, dchunk, i, head);
		brelse(hbh);
		if (status < 0)
			break;
	}
	if (status < 0)
		free_recovery_list(head);
	return status;
}

static struct ocfs2_quota_recovery *ocfs2_alloc_quota_recovery(void)
{
	int type;
	struct ocfs2_quota_recovery *rec;

	rec = kmalloc(sizeof(struct ocfs2_quota_recovery), GFP_NOFS);
	if (!rec)
		return NULL;
	for (type = 0; type < OCFS2_MAXQUOTAS; type++)
		INIT_LIST_HEAD(&(rec->r_list[type]));
	return rec;
}

/* Load information we need for quota recovery into memory */
struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
						struct ocfs2_super *osb,
						int slot_num)
{
	unsigned int feature[OCFS2_MAXQUOTAS] = {
					OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
					OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
	unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
					      LOCAL_GROUP_QUOTA_SYSTEM_INODE };
	struct super_block *sb = osb->sb;
	struct ocfs2_local_disk_dqinfo *ldinfo;
	struct inode *lqinode;
	struct buffer_head *bh;
	int type;
	int status = 0;
	struct ocfs2_quota_recovery *rec;

	printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
	       "slot %u\n", osb->dev_str, slot_num);

	rec = ocfs2_alloc_quota_recovery();
	if (!rec)
		return ERR_PTR(-ENOMEM);
	/* First init... */

	for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
		if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
			continue;
		/* At this point, journal of the slot is already replayed so
		 * we can trust metadata and data of the quota file */
		lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
		if (!lqinode) {
			status = -ENOENT;
			goto out;
		}
		status = ocfs2_inode_lock_full(lqinode, NULL, 1,
					       OCFS2_META_LOCK_RECOVERY);
		if (status < 0) {
			mlog_errno(status);
			goto out_put;
		}
		/* Now read local header */
		bh = NULL;
		status = ocfs2_read_quota_block(lqinode, 0, &bh);
		if (status) {
			mlog_errno(status);
			mlog(ML_ERROR, "failed to read quota file info header "
				"(slot=%d type=%d)\n", slot_num, type);
			goto out_lock;
		}
		ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
							OCFS2_LOCAL_INFO_OFF);
		status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
						   &rec->r_list[type]);
		brelse(bh);
out_lock:
		ocfs2_inode_unlock(lqinode, 1);
out_put:
		iput(lqinode);
		if (status < 0)
			break;
	}
out:
	if (status < 0) {
		ocfs2_free_quota_recovery(rec);
		rec = ERR_PTR(status);
	}
	return rec;
}

/* Sync changes in local quota file into global quota file and
 * reinitialize local quota file.
 * The function expects local quota file to be already locked and
 * dqonoff_mutex locked. */
static int ocfs2_recover_local_quota_file(struct inode *lqinode,
					  int type,
					  struct ocfs2_quota_recovery *rec)
{
	struct super_block *sb = lqinode->i_sb;
	struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
	struct ocfs2_local_disk_chunk *dchunk;
	struct ocfs2_local_disk_dqblk *dqblk;
	struct dquot *dquot;
	handle_t *handle;
	struct buffer_head *hbh = NULL, *qbh = NULL;
	int status = 0;
	int bit, chunk;
	struct ocfs2_recovery_chunk *rchunk, *next;
	qsize_t spacechange, inodechange;

	trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type);

	list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) {
		chunk = rchunk->rc_chunk;
		hbh = NULL;
		status = ocfs2_read_quota_block(lqinode,
						ol_quota_chunk_block(sb, chunk),
						&hbh);
		if (status) {
			mlog_errno(status);
			break;
		}
		dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
		for_each_set_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
			qbh = NULL;
			status = ocfs2_read_quota_block(lqinode,
						ol_dqblk_block(sb, chunk, bit),
						&qbh);
			if (status) {
				mlog_errno(status);
				break;
			}
			dqblk = (struct ocfs2_local_disk_dqblk *)(qbh->b_data +
				ol_dqblk_block_off(sb, chunk, bit));
			dquot = dqget(sb,
				      make_kqid(&init_user_ns, type,
						le64_to_cpu(dqblk->dqb_id)));
			if (IS_ERR(dquot)) {
				status = PTR_ERR(dquot);
				mlog(ML_ERROR, "Failed to get quota structure "
				     "for id %u, type %d. Cannot finish quota "
				     "file recovery.\n",
				     (unsigned)le64_to_cpu(dqblk->dqb_id),
				     type);
				goto out_put_bh;
			}
			status = ocfs2_lock_global_qf(oinfo, 1);
			if (status < 0) {
				mlog_errno(status);
				goto out_put_dquot;
			}

			handle = ocfs2_start_trans(OCFS2_SB(sb),
						   OCFS2_QSYNC_CREDITS);
			if (IS_ERR(handle)) {
				status = PTR_ERR(handle);
				mlog_errno(status);
				goto out_drop_lock;
			}
			mutex_lock(&sb_dqopt(sb)->dqio_mutex);
			spin_lock(&dq_data_lock);
			/* Add usage from quota entry into quota changes
			 * of our node. Auxiliary variables are important
			 * due to signedness */
			spacechange = le64_to_cpu(dqblk->dqb_spacemod);
			inodechange = le64_to_cpu(dqblk->dqb_inodemod);
			dquot->dq_dqb.dqb_curspace += spacechange;
			dquot->dq_dqb.dqb_curinodes += inodechange;
			spin_unlock(&dq_data_lock);
			/* We want to drop reference held by the crashed
			 * node. Since we have our own reference we know
			 * global structure actually won't be freed. */
			status = ocfs2_global_release_dquot(dquot);
			if (status < 0) {
				mlog_errno(status);
				goto out_commit;
			}
			/* Release local quota file entry */
			status = ocfs2_journal_access_dq(handle,
					INODE_CACHE(lqinode),
					qbh, OCFS2_JOURNAL_ACCESS_WRITE);
			if (status < 0) {
				mlog_errno(status);
				goto out_commit;
			}
			lock_buffer(qbh);
			WARN_ON(!ocfs2_test_bit_unaligned(bit, dchunk->dqc_bitmap));
			ocfs2_clear_bit_unaligned(bit, dchunk->dqc_bitmap);
			le32_add_cpu(&dchunk->dqc_free, 1);
			unlock_buffer(qbh);
			ocfs2_journal_dirty(handle, qbh);
out_commit:
			mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
			ocfs2_commit_trans(OCFS2_SB(sb), handle);
out_drop_lock:
			ocfs2_unlock_global_qf(oinfo, 1);
out_put_dquot:
			dqput(dquot);
out_put_bh:
			brelse(qbh);
			if (status < 0)
				break;
		}
		brelse(hbh);
		list_del(&rchunk->rc_list);
		kfree(rchunk->rc_bitmap);
		kfree(rchunk);
		if (status < 0)
			break;
	}
	if (status < 0)
		free_recovery_list(&(rec->r_list[type]));
	if (status)
		mlog_errno(status);
	return status;
}

/* Recover local quota files for given node different from us */
int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
				struct ocfs2_quota_recovery *rec,
				int slot_num)
{
	unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
					      LOCAL_GROUP_QUOTA_SYSTEM_INODE };
	struct super_block *sb = osb->sb;
	struct ocfs2_local_disk_dqinfo *ldinfo;
	struct buffer_head *bh;
	handle_t *handle;
	int type;
	int status = 0;
	struct inode *lqinode;
	unsigned int flags;

	printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
	       "slot %u\n", osb->dev_str, slot_num);

	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
	for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
		if (list_empty(&(rec->r_list[type])))
			continue;
		trace_ocfs2_finish_quota_recovery(slot_num);
		lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
		if (!lqinode) {
			status = -ENOENT;
			goto out;
		}
		status = ocfs2_inode_lock_full(lqinode, NULL, 1,
						       OCFS2_META_LOCK_NOQUEUE);
		/* Someone else is holding the lock? Then he must be
		 * doing the recovery. Just skip the file... */
		if (status == -EAGAIN) {
			printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
			       "device (%s) for slot %d because quota file is "
			       "locked.\n", osb->dev_str, slot_num);
			status = 0;
			goto out_put;
		} else if (status < 0) {
			mlog_errno(status);
			goto out_put;
		}
		/* Now read local header */
		bh = NULL;
		status = ocfs2_read_quota_block(lqinode, 0, &bh);
		if (status) {
			mlog_errno(status);
			mlog(ML_ERROR, "failed to read quota file info header "
				"(slot=%d type=%d)\n", slot_num, type);
			goto out_lock;
		}
		ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
							OCFS2_LOCAL_INFO_OFF);
		/* Is recovery still needed? */
		flags = le32_to_cpu(ldinfo->dqi_flags);
		if (!(flags & OLQF_CLEAN))
			status = ocfs2_recover_local_quota_file(lqinode,
								type,
								rec);
		/* We don't want to mark file as clean when it is actually
		 * active */
		if (slot_num == osb->slot_num)
			goto out_bh;
		/* Mark quota file as clean if we are recovering quota file of
		 * some other node. */
		handle = ocfs2_start_trans(osb,
					   OCFS2_LOCAL_QINFO_WRITE_CREDITS);
		if (IS_ERR(handle)) {
			status = PTR_ERR(handle);
			mlog_errno(status);
			goto out_bh;
		}
		status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
						 bh,
						 OCFS2_JOURNAL_ACCESS_WRITE);
		if (status < 0) {
			mlog_errno(status);
			goto out_trans;
		}
		lock_buffer(bh);
		ldinfo->dqi_flags = cpu_to_le32(flags | OLQF_CLEAN);
		unlock_buffer(bh);
		ocfs2_journal_dirty(handle, bh);
out_trans:
		ocfs2_commit_trans(osb, handle);
out_bh:
		brelse(bh);
out_lock:
		ocfs2_inode_unlock(lqinode, 1);
out_put:
		iput(lqinode);
		if (status < 0)
			break;
	}
out:
	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
	kfree(rec);
	return status;
}

/* Read information header from quota file */
static int ocfs2_local_read_info(struct super_block *sb, int type)
{
	struct ocfs2_local_disk_dqinfo *ldinfo;
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo;
	struct inode *lqinode = sb_dqopt(sb)->files[type];
	int status;
	struct buffer_head *bh = NULL;
	struct ocfs2_quota_recovery *rec;
	int locked = 0;

	/* We don't need the lock and we have to acquire quota file locks
	 * which will later depend on this lock */
	mutex_unlock(&sb_dqopt(sb)->dqio_mutex);
	info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
	info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
	oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
	if (!oinfo) {
		mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
			       " info.");
		goto out_err;
	}
	info->dqi_priv = oinfo;
	oinfo->dqi_type = type;
	INIT_LIST_HEAD(&oinfo->dqi_chunk);
	oinfo->dqi_rec = NULL;
	oinfo->dqi_lqi_bh = NULL;
	oinfo->dqi_libh = NULL;

	status = ocfs2_global_read_info(sb, type);
	if (status < 0)
		goto out_err;

	status = ocfs2_inode_lock(lqinode, &oinfo->dqi_lqi_bh, 1);
	if (status < 0) {
		mlog_errno(status);
		goto out_err;
	}
	locked = 1;

	/* Now read local header */
	status = ocfs2_read_quota_block(lqinode, 0, &bh);
	if (status) {
		mlog_errno(status);
		mlog(ML_ERROR, "failed to read quota file info header "
			"(type=%d)\n", type);
		goto out_err;
	}
	ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
						OCFS2_LOCAL_INFO_OFF);
	oinfo->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
	oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
	oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
	oinfo->dqi_libh = bh;

	/* We crashed when using local quota file? */
	if (!(oinfo->dqi_flags & OLQF_CLEAN)) {
		rec = OCFS2_SB(sb)->quota_rec;
		if (!rec) {
			rec = ocfs2_alloc_quota_recovery();
			if (!rec) {
				status = -ENOMEM;
				mlog_errno(status);
				goto out_err;
			}
			OCFS2_SB(sb)->quota_rec = rec;
		}

		status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
                                                   &rec->r_list[type]);
		if (status < 0) {
			mlog_errno(status);
			goto out_err;
		}
	}

	status = ocfs2_load_local_quota_bitmaps(lqinode,
						ldinfo,
						&oinfo->dqi_chunk);
	if (status < 0) {
		mlog_errno(status);
		goto out_err;
	}

	/* Now mark quota file as used */
	oinfo->dqi_flags &= ~OLQF_CLEAN;
	status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
	if (status < 0) {
		mlog_errno(status);
		goto out_err;
	}

	mutex_lock(&sb_dqopt(sb)->dqio_mutex);
	return 0;
out_err:
	if (oinfo) {
		iput(oinfo->dqi_gqinode);
		ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
		ocfs2_lock_res_free(&oinfo->dqi_gqlock);
		brelse(oinfo->dqi_lqi_bh);
		if (locked)
			ocfs2_inode_unlock(lqinode, 1);
		ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
		kfree(oinfo);
	}
	brelse(bh);
	mutex_lock(&sb_dqopt(sb)->dqio_mutex);
	return -1;
}

/* Write local info to quota file */
static int ocfs2_local_write_info(struct super_block *sb, int type)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv)
						->dqi_libh;
	int status;

	status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info,
				 info);
	if (status < 0) {
		mlog_errno(status);
		return -1;
	}

	return 0;
}

/* Release info from memory */
static int ocfs2_local_free_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_quota_chunk *chunk;
	struct ocfs2_local_disk_chunk *dchunk;
	int mark_clean = 1, len;
	int status;

	iput(oinfo->dqi_gqinode);
	ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
	ocfs2_lock_res_free(&oinfo->dqi_gqlock);
	list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) {
		dchunk = (struct ocfs2_local_disk_chunk *)
					(chunk->qc_headerbh->b_data);
		if (chunk->qc_num < oinfo->dqi_chunks - 1) {
			len = ol_chunk_entries(sb);
		} else {
			len = (oinfo->dqi_blocks -
			       ol_quota_chunk_block(sb, chunk->qc_num) - 1)
			      * ol_quota_entries_per_block(sb);
		}
		/* Not all entries free? Bug! */
		if (le32_to_cpu(dchunk->dqc_free) != len) {
			mlog(ML_ERROR, "releasing quota file with used "
					"entries (type=%d)\n", type);
			mark_clean = 0;
		}
	}
	ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);

	/* dqonoff_mutex protects us against racing with recovery thread... */
	if (oinfo->dqi_rec) {
		ocfs2_free_quota_recovery(oinfo->dqi_rec);
		mark_clean = 0;
	}

	if (!mark_clean)
		goto out;

	/* Mark local file as clean */
	oinfo->dqi_flags |= OLQF_CLEAN;
	status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
				 oinfo->dqi_libh,
				 olq_update_info,
				 info);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}

out:
	ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
	brelse(oinfo->dqi_libh);
	brelse(oinfo->dqi_lqi_bh);
	kfree(oinfo);
	return 0;
}

static void olq_set_dquot(struct buffer_head *bh, void *private)
{
	struct ocfs2_dquot *od = private;
	struct ocfs2_local_disk_dqblk *dqblk;
	struct super_block *sb = od->dq_dquot.dq_sb;

	dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data
		+ ol_dqblk_block_offset(sb, od->dq_local_off));

	dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns,
					      od->dq_dquot.dq_id));
	spin_lock(&dq_data_lock);
	dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace -
					  od->dq_origspace);
	dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes -
					  od->dq_originodes);
	spin_unlock(&dq_data_lock);
	trace_olq_set_dquot(
		(unsigned long long)le64_to_cpu(dqblk->dqb_spacemod),
		(unsigned long long)le64_to_cpu(dqblk->dqb_inodemod),
		from_kqid(&init_user_ns, od->dq_dquot.dq_id));
}

/* Write dquot to local quota file */
int ocfs2_local_write_dquot(struct dquot *dquot)
{
	struct super_block *sb = dquot->dq_sb;
	struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
	struct buffer_head *bh;
	struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_id.type];
	int status;

	status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
					     &bh);
	if (status) {
		mlog_errno(status);
		goto out;
	}
	status = ocfs2_modify_bh(lqinode, bh, olq_set_dquot, od);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
out:
	brelse(bh);
	return status;
}

/* Find free entry in local quota file */
static struct ocfs2_quota_chunk *ocfs2_find_free_entry(struct super_block *sb,
						       int type,
						       int *offset)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct ocfs2_quota_chunk *chunk;
	struct ocfs2_local_disk_chunk *dchunk;
	int found = 0, len;

	list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) {
		dchunk = (struct ocfs2_local_disk_chunk *)
						chunk->qc_headerbh->b_data;
		if (le32_to_cpu(dchunk->dqc_free) > 0) {
			found = 1;
			break;
		}
	}
	if (!found)
		return NULL;

	if (chunk->qc_num < oinfo->dqi_chunks - 1) {
		len = ol_chunk_entries(sb);
	} else {
		len = (oinfo->dqi_blocks -
		       ol_quota_chunk_block(sb, chunk->qc_num) - 1)
		      * ol_quota_entries_per_block(sb);
	}

	found = ocfs2_find_next_zero_bit_unaligned(dchunk->dqc_bitmap, len, 0);
	/* We failed? */
	if (found == len) {
		mlog(ML_ERROR, "Did not find empty entry in chunk %d with %u"
		     " entries free (type=%d)\n", chunk->qc_num,
		     le32_to_cpu(dchunk->dqc_free), type);
		return ERR_PTR(-EIO);
	}
	*offset = found;
	return chunk;
}

/* Add new chunk to the local quota file */
static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
							struct super_block *sb,
							int type,
							int *offset)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct inode *lqinode = sb_dqopt(sb)->files[type];
	struct ocfs2_quota_chunk *chunk = NULL;
	struct ocfs2_local_disk_chunk *dchunk;
	int status;
	handle_t *handle;
	struct buffer_head *bh = NULL, *dbh = NULL;
	u64 p_blkno;

	/* We are protected by dqio_sem so no locking needed */
	status = ocfs2_extend_no_holes(lqinode, NULL,
				       i_size_read(lqinode) + 2 * sb->s_blocksize,
				       i_size_read(lqinode));
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
	status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
					  i_size_read(lqinode) + 2 * sb->s_blocksize);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}

	chunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
	if (!chunk) {
		status = -ENOMEM;
		mlog_errno(status);
		goto out;
	}
	/* Local quota info and two new blocks we initialize */
	handle = ocfs2_start_trans(OCFS2_SB(sb),
			OCFS2_LOCAL_QINFO_WRITE_CREDITS +
			2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out;
	}

	/* Initialize chunk header */
	status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
					     &p_blkno, NULL, NULL);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	bh = sb_getblk(sb, p_blkno);
	if (!bh) {
		status = -ENOMEM;
		mlog_errno(status);
		goto out_trans;
	}
	dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
	ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
	status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
					 OCFS2_JOURNAL_ACCESS_CREATE);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	lock_buffer(bh);
	dchunk->dqc_free = cpu_to_le32(ol_quota_entries_per_block(sb));
	memset(dchunk->dqc_bitmap, 0,
	       sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
	       OCFS2_QBLK_RESERVED_SPACE);
	unlock_buffer(bh);
	ocfs2_journal_dirty(handle, bh);

	/* Initialize new block with structures */
	status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1,
					     &p_blkno, NULL, NULL);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	dbh = sb_getblk(sb, p_blkno);
	if (!dbh) {
		status = -ENOMEM;
		mlog_errno(status);
		goto out_trans;
	}
	ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), dbh);
	status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), dbh,
					 OCFS2_JOURNAL_ACCESS_CREATE);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	lock_buffer(dbh);
	memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE);
	unlock_buffer(dbh);
	ocfs2_journal_dirty(handle, dbh);

	/* Update local quotafile info */
	oinfo->dqi_blocks += 2;
	oinfo->dqi_chunks++;
	status = ocfs2_local_write_info(sb, type);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}

	list_add_tail(&chunk->qc_chunk, &oinfo->dqi_chunk);
	chunk->qc_num = list_entry(chunk->qc_chunk.prev,
				   struct ocfs2_quota_chunk,
				   qc_chunk)->qc_num + 1;
	chunk->qc_headerbh = bh;
	*offset = 0;
	return chunk;
out_trans:
	ocfs2_commit_trans(OCFS2_SB(sb), handle);
out:
	brelse(bh);
	brelse(dbh);
	kmem_cache_free(ocfs2_qf_chunk_cachep, chunk);
	return ERR_PTR(status);
}

/* Find free entry in local quota file */
static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
						       struct super_block *sb,
						       int type,
						       int *offset)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct ocfs2_quota_chunk *chunk;
	struct inode *lqinode = sb_dqopt(sb)->files[type];
	struct ocfs2_local_disk_chunk *dchunk;
	int epb = ol_quota_entries_per_block(sb);
	unsigned int chunk_blocks;
	struct buffer_head *bh;
	u64 p_blkno;
	int status;
	handle_t *handle;

	if (list_empty(&oinfo->dqi_chunk))
		return ocfs2_local_quota_add_chunk(sb, type, offset);
	/* Is the last chunk full? */
	chunk = list_entry(oinfo->dqi_chunk.prev,
			struct ocfs2_quota_chunk, qc_chunk);
	chunk_blocks = oinfo->dqi_blocks -
			ol_quota_chunk_block(sb, chunk->qc_num) - 1;
	if (ol_chunk_blocks(sb) == chunk_blocks)
		return ocfs2_local_quota_add_chunk(sb, type, offset);

	/* We are protected by dqio_sem so no locking needed */
	status = ocfs2_extend_no_holes(lqinode, NULL,
				       i_size_read(lqinode) + sb->s_blocksize,
				       i_size_read(lqinode));
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
	status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
					  i_size_read(lqinode) + sb->s_blocksize);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}

	/* Get buffer from the just added block */
	status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
					     &p_blkno, NULL, NULL);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
	bh = sb_getblk(sb, p_blkno);
	if (!bh) {
		status = -ENOMEM;
		mlog_errno(status);
		goto out;
	}
	ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);

	/* Local quota info, chunk header and the new block we initialize */
	handle = ocfs2_start_trans(OCFS2_SB(sb),
			OCFS2_LOCAL_QINFO_WRITE_CREDITS +
			2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
	if (IS_ERR(handle)) {
		status = PTR_ERR(handle);
		mlog_errno(status);
		goto out;
	}
	/* Zero created block */
	status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
				 OCFS2_JOURNAL_ACCESS_CREATE);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}
	lock_buffer(bh);
	memset(bh->b_data, 0, sb->s_blocksize);
	unlock_buffer(bh);
	ocfs2_journal_dirty(handle, bh);

	/* Update chunk header */
	status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
					 chunk->qc_headerbh,
				 OCFS2_JOURNAL_ACCESS_WRITE);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}

	dchunk = (struct ocfs2_local_disk_chunk *)chunk->qc_headerbh->b_data;
	lock_buffer(chunk->qc_headerbh);
	le32_add_cpu(&dchunk->dqc_free, ol_quota_entries_per_block(sb));
	unlock_buffer(chunk->qc_headerbh);
	ocfs2_journal_dirty(handle, chunk->qc_headerbh);

	/* Update file header */
	oinfo->dqi_blocks++;
	status = ocfs2_local_write_info(sb, type);
	if (status < 0) {
		mlog_errno(status);
		goto out_trans;
	}

	status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
	*offset = chunk_blocks * epb;
	return chunk;
out_trans:
	ocfs2_commit_trans(OCFS2_SB(sb), handle);
out:
	return ERR_PTR(status);
}

static void olq_alloc_dquot(struct buffer_head *bh, void *private)
{
	int *offset = private;
	struct ocfs2_local_disk_chunk *dchunk;

	dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
	ocfs2_set_bit_unaligned(*offset, dchunk->dqc_bitmap);
	le32_add_cpu(&dchunk->dqc_free, -1);
}

/* Create dquot in the local file for given id */
int ocfs2_create_local_dquot(struct dquot *dquot)
{
	struct super_block *sb = dquot->dq_sb;
	int type = dquot->dq_id.type;
	struct inode *lqinode = sb_dqopt(sb)->files[type];
	struct ocfs2_quota_chunk *chunk;
	struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
	int offset;
	int status;
	u64 pcount;

	down_write(&OCFS2_I(lqinode)->ip_alloc_sem);
	chunk = ocfs2_find_free_entry(sb, type, &offset);
	if (!chunk) {
		chunk = ocfs2_extend_local_quota_file(sb, type, &offset);
		if (IS_ERR(chunk)) {
			status = PTR_ERR(chunk);
			goto out;
		}
	} else if (IS_ERR(chunk)) {
		status = PTR_ERR(chunk);
		goto out;
	}
	od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset);
	od->dq_chunk = chunk;
	status = ocfs2_extent_map_get_blocks(lqinode,
				     ol_dqblk_block(sb, chunk->qc_num, offset),
				     &od->dq_local_phys_blk,
				     &pcount,
				     NULL);

	/* Initialize dquot structure on disk */
	status = ocfs2_local_write_dquot(dquot);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}

	/* Mark structure as allocated */
	status = ocfs2_modify_bh(lqinode, chunk->qc_headerbh, olq_alloc_dquot,
				 &offset);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
out:
	up_write(&OCFS2_I(lqinode)->ip_alloc_sem);
	return status;
}

/*
 * Release dquot structure from local quota file. ocfs2_release_dquot() has
 * already started a transaction and written all changes to global quota file
 */
int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
{
	int status;
	int type = dquot->dq_id.type;
	struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
	struct super_block *sb = dquot->dq_sb;
	struct ocfs2_local_disk_chunk *dchunk;
	int offset;

	status = ocfs2_journal_access_dq(handle,
			INODE_CACHE(sb_dqopt(sb)->files[type]),
			od->dq_chunk->qc_headerbh, OCFS2_JOURNAL_ACCESS_WRITE);
	if (status < 0) {
		mlog_errno(status);
		goto out;
	}
	offset = ol_dqblk_chunk_off(sb, od->dq_chunk->qc_num,
					     od->dq_local_off);
	dchunk = (struct ocfs2_local_disk_chunk *)
			(od->dq_chunk->qc_headerbh->b_data);
	/* Mark structure as freed */
	lock_buffer(od->dq_chunk->qc_headerbh);
	ocfs2_clear_bit_unaligned(offset, dchunk->dqc_bitmap);
	le32_add_cpu(&dchunk->dqc_free, 1);
	unlock_buffer(od->dq_chunk->qc_headerbh);
	ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh);

out:
	return status;
}

static const struct quota_format_ops ocfs2_format_ops = {
	.check_quota_file	= ocfs2_local_check_quota_file,
	.read_file_info		= ocfs2_local_read_info,
	.write_file_info	= ocfs2_global_write_info,
	.free_file_info		= ocfs2_local_free_info,
};

struct quota_format_type ocfs2_quota_format = {
	.qf_fmt_id = QFMT_OCFS2,
	.qf_ops = &ocfs2_format_ops,
	.qf_owner = THIS_MODULE
};
