/*
 * Copyright (c) 2008-2010, 2013 Dave Chinner
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_types.h"
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_error.h"
#include "xfs_icreate_item.h"

kmem_zone_t	*xfs_icreate_zone;		/* inode create item zone */

static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip)
{
	return container_of(lip, struct xfs_icreate_item, ic_item);
}

/*
 * This returns the number of iovecs needed to log the given inode item.
 *
 * We only need one iovec for the icreate log structure.
 */
STATIC uint
xfs_icreate_item_size(
	struct xfs_log_item	*lip)
{
	return 1;
}

/*
 * This is called to fill in the vector of log iovecs for the
 * given inode create log item.
 */
STATIC void
xfs_icreate_item_format(
	struct xfs_log_item	*lip,
	struct xfs_log_iovec	*log_vector)
{
	struct xfs_icreate_item	*icp = ICR_ITEM(lip);

	log_vector->i_addr = (xfs_caddr_t)&icp->ic_format;
	log_vector->i_len  = sizeof(struct xfs_icreate_log);
	log_vector->i_type = XLOG_REG_TYPE_ICREATE;
}


/* Pinning has no meaning for the create item, so just return. */
STATIC void
xfs_icreate_item_pin(
	struct xfs_log_item	*lip)
{
}


/* pinning has no meaning for the create item, so just return. */
STATIC void
xfs_icreate_item_unpin(
	struct xfs_log_item	*lip,
	int			remove)
{
}

STATIC void
xfs_icreate_item_unlock(
	struct xfs_log_item	*lip)
{
	struct xfs_icreate_item	*icp = ICR_ITEM(lip);

	if (icp->ic_item.li_flags & XFS_LI_ABORTED)
		kmem_zone_free(xfs_icreate_zone, icp);
	return;
}

/*
 * Because we have ordered buffers being tracked in the AIL for the inode
 * creation, we don't need the create item after this. Hence we can free
 * the log item and return -1 to tell the caller we're done with the item.
 */
STATIC xfs_lsn_t
xfs_icreate_item_committed(
	struct xfs_log_item	*lip,
	xfs_lsn_t		lsn)
{
	struct xfs_icreate_item	*icp = ICR_ITEM(lip);

	kmem_zone_free(xfs_icreate_zone, icp);
	return (xfs_lsn_t)-1;
}

/* item can never get into the AIL */
STATIC uint
xfs_icreate_item_push(
	struct xfs_log_item	*lip,
	struct list_head	*buffer_list)
{
	ASSERT(0);
	return XFS_ITEM_SUCCESS;
}

/* Ordered buffers do the dependency tracking here, so this does nothing. */
STATIC void
xfs_icreate_item_committing(
	struct xfs_log_item	*lip,
	xfs_lsn_t		lsn)
{
}

/*
 * This is the ops vector shared by all buf log items.
 */
static struct xfs_item_ops xfs_icreate_item_ops = {
	.iop_size	= xfs_icreate_item_size,
	.iop_format	= xfs_icreate_item_format,
	.iop_pin	= xfs_icreate_item_pin,
	.iop_unpin	= xfs_icreate_item_unpin,
	.iop_push	= xfs_icreate_item_push,
	.iop_unlock	= xfs_icreate_item_unlock,
	.iop_committed	= xfs_icreate_item_committed,
	.iop_committing = xfs_icreate_item_committing,
};


/*
 * Initialize the inode log item for a newly allocated (in-core) inode.
 *
 * Inode extents can only reside within an AG. Hence specify the starting
 * block for the inode chunk by offset within an AG as well as the
 * length of the allocated extent.
 *
 * This joins the item to the transaction and marks it dirty so
 * that we don't need a separate call to do this, nor does the
 * caller need to know anything about the icreate item.
 */
void
xfs_icreate_log(
	struct xfs_trans	*tp,
	xfs_agnumber_t		agno,
	xfs_agblock_t		agbno,
	unsigned int		count,
	unsigned int		inode_size,
	xfs_agblock_t		length,
	unsigned int		generation)
{
	struct xfs_icreate_item	*icp;

	icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP);

	xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE,
			  &xfs_icreate_item_ops);

	icp->ic_format.icl_type = XFS_LI_ICREATE;
	icp->ic_format.icl_size = 1;	/* single vector */
	icp->ic_format.icl_ag = cpu_to_be32(agno);
	icp->ic_format.icl_agbno = cpu_to_be32(agbno);
	icp->ic_format.icl_count = cpu_to_be32(count);
	icp->ic_format.icl_isize = cpu_to_be32(inode_size);
	icp->ic_format.icl_length = cpu_to_be32(length);
	icp->ic_format.icl_gen = cpu_to_be32(generation);

	xfs_trans_add_item(tp, &icp->ic_item);
	tp->t_flags |= XFS_TRANS_DIRTY;
	icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY;
}
