/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will 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 version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/llite/llite_close.c
 *
 * Lustre Lite routines to issue a secondary close after writeback
 */

#include <linux/module.h>

#define DEBUG_SUBSYSTEM S_LLITE

#include "../include/lustre_lite.h"
#include "llite_internal.h"

/** records that a write is in flight */
void vvp_write_pending(struct ccc_object *club, struct ccc_page *page)
{
	struct ll_inode_info *lli = ll_i2info(club->cob_inode);

	spin_lock(&lli->lli_lock);
	lli->lli_flags |= LLIF_SOM_DIRTY;
	if (page != NULL && list_empty(&page->cpg_pending_linkage))
		list_add(&page->cpg_pending_linkage,
			     &club->cob_pending_list);
	spin_unlock(&lli->lli_lock);
}

/** records that a write has completed */
void vvp_write_complete(struct ccc_object *club, struct ccc_page *page)
{
	struct ll_inode_info *lli = ll_i2info(club->cob_inode);
	int rc = 0;

	spin_lock(&lli->lli_lock);
	if (page != NULL && !list_empty(&page->cpg_pending_linkage)) {
		list_del_init(&page->cpg_pending_linkage);
		rc = 1;
	}
	spin_unlock(&lli->lli_lock);
	if (rc)
		ll_queue_done_writing(club->cob_inode, 0);
}

/** Queues DONE_WRITING if
 * - done writing is allowed;
 * - inode has no no dirty pages; */
void ll_queue_done_writing(struct inode *inode, unsigned long flags)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob);

	spin_lock(&lli->lli_lock);
	lli->lli_flags |= flags;

	if ((lli->lli_flags & LLIF_DONE_WRITING) &&
	    list_empty(&club->cob_pending_list)) {
		struct ll_close_queue *lcq = ll_i2sbi(inode)->ll_lcq;

		if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
			CWARN("ino %lu/%u(flags %u) som valid it just after recovery\n",
			      inode->i_ino, inode->i_generation,
			      lli->lli_flags);
		/* DONE_WRITING is allowed and inode has no dirty page. */
		spin_lock(&lcq->lcq_lock);

		LASSERT(list_empty(&lli->lli_close_list));
		CDEBUG(D_INODE, "adding inode %lu/%u to close list\n",
		       inode->i_ino, inode->i_generation);
		list_add_tail(&lli->lli_close_list, &lcq->lcq_head);

		/* Avoid a concurrent insertion into the close thread queue:
		 * an inode is already in the close thread, open(), write(),
		 * close() happen, epoch is closed as the inode is marked as
		 * LLIF_EPOCH_PENDING. When pages are written inode should not
		 * be inserted into the queue again, clear this flag to avoid
		 * it. */
		lli->lli_flags &= ~LLIF_DONE_WRITING;

		wake_up(&lcq->lcq_waitq);
		spin_unlock(&lcq->lcq_lock);
	}
	spin_unlock(&lli->lli_lock);
}

/** Pack SOM attributes info @opdata for CLOSE, DONE_WRITING rpc. */
void ll_done_writing_attr(struct inode *inode, struct md_op_data *op_data)
{
	struct ll_inode_info *lli = ll_i2info(inode);

	op_data->op_flags |= MF_SOM_CHANGE;
	/* Check if Size-on-MDS attributes are valid. */
	if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
		CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n",
		       inode->i_ino, inode->i_generation,
		       lli->lli_flags);

	if (!cl_local_size(inode)) {
		/* Send Size-on-MDS Attributes if valid. */
		op_data->op_attr.ia_valid |= ATTR_MTIME_SET | ATTR_CTIME_SET |
				ATTR_ATIME_SET | ATTR_SIZE | ATTR_BLOCKS;
	}
}

/** Closes ioepoch and packs Size-on-MDS attribute if needed into @op_data. */
void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
		      struct obd_client_handle **och, unsigned long flags)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct ccc_object *club = cl2ccc(ll_i2info(inode)->lli_clob);

	spin_lock(&lli->lli_lock);
	if (!(list_empty(&club->cob_pending_list))) {
		if (!(lli->lli_flags & LLIF_EPOCH_PENDING)) {
			LASSERT(*och != NULL);
			LASSERT(lli->lli_pending_och == NULL);
			/* Inode is dirty and there is no pending write done
			 * request yet, DONE_WRITE is to be sent later. */
			lli->lli_flags |= LLIF_EPOCH_PENDING;
			lli->lli_pending_och = *och;
			spin_unlock(&lli->lli_lock);

			inode = igrab(inode);
			LASSERT(inode);
			goto out;
		}
		if (flags & LLIF_DONE_WRITING) {
			/* Some pages are still dirty, it is early to send
			 * DONE_WRITE. Wait until all pages will be flushed
			 * and try DONE_WRITE again later. */
			LASSERT(!(lli->lli_flags & LLIF_DONE_WRITING));
			lli->lli_flags |= LLIF_DONE_WRITING;
			spin_unlock(&lli->lli_lock);

			inode = igrab(inode);
			LASSERT(inode);
			goto out;
		}
	}
	CDEBUG(D_INODE, "Epoch %llu closed on "DFID"\n",
	       ll_i2info(inode)->lli_ioepoch, PFID(&lli->lli_fid));
	op_data->op_flags |= MF_EPOCH_CLOSE;

	if (flags & LLIF_DONE_WRITING) {
		LASSERT(lli->lli_flags & LLIF_SOM_DIRTY);
		LASSERT(!(lli->lli_flags & LLIF_DONE_WRITING));
		*och = lli->lli_pending_och;
		lli->lli_pending_och = NULL;
		lli->lli_flags &= ~LLIF_EPOCH_PENDING;
	} else {
		/* Pack Size-on-MDS inode attributes only if they has changed */
		if (!(lli->lli_flags & LLIF_SOM_DIRTY)) {
			spin_unlock(&lli->lli_lock);
			goto out;
		}

		/* There is a pending DONE_WRITE -- close epoch with no
		 * attribute change. */
		if (lli->lli_flags & LLIF_EPOCH_PENDING) {
			spin_unlock(&lli->lli_lock);
			goto out;
		}
	}

	LASSERT(list_empty(&club->cob_pending_list));
	lli->lli_flags &= ~LLIF_SOM_DIRTY;
	spin_unlock(&lli->lli_lock);
	ll_done_writing_attr(inode, op_data);

out:
	return;
}

/**
 * Cliens updates SOM attributes on MDS (including llog cookies):
 * obd_getattr with no lock and md_setattr.
 */
int ll_som_update(struct inode *inode, struct md_op_data *op_data)
{
	struct ll_inode_info *lli = ll_i2info(inode);
	struct ptlrpc_request *request = NULL;
	__u32 old_flags;
	struct obdo *oa;
	int rc;

	LASSERT(op_data != NULL);
	if (lli->lli_flags & LLIF_MDS_SIZE_LOCK)
		CERROR("ino %lu/%u(flags %u) som valid it just after recovery\n",
		       inode->i_ino, inode->i_generation,
		       lli->lli_flags);

	oa = kmem_cache_alloc(obdo_cachep, GFP_NOFS | __GFP_ZERO);
	if (!oa) {
		CERROR("can't allocate memory for Size-on-MDS update.\n");
		return -ENOMEM;
	}

	old_flags = op_data->op_flags;
	op_data->op_flags = MF_SOM_CHANGE;

	/* If inode is already in another epoch, skip getattr from OSTs. */
	if (lli->lli_ioepoch == op_data->op_ioepoch) {
		rc = ll_inode_getattr(inode, oa, op_data->op_ioepoch,
				      old_flags & MF_GETATTR_LOCK);
		if (rc) {
			oa->o_valid = 0;
			if (rc != -ENOENT)
				CERROR("inode_getattr failed (%d): unable to send a Size-on-MDS attribute update for inode %lu/%u\n",
				       rc, inode->i_ino,
				       inode->i_generation);
		} else {
			CDEBUG(D_INODE, "Size-on-MDS update on "DFID"\n",
			       PFID(&lli->lli_fid));
		}
		/* Install attributes into op_data. */
		md_from_obdo(op_data, oa, oa->o_valid);
	}

	rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data,
			NULL, 0, NULL, 0, &request, NULL);
	ptlrpc_req_finished(request);

	kmem_cache_free(obdo_cachep, oa);
	return rc;
}

/**
 * Closes the ioepoch and packs all the attributes into @op_data for
 * DONE_WRITING rpc.
 */
static void ll_prepare_done_writing(struct inode *inode,
				    struct md_op_data *op_data,
				    struct obd_client_handle **och)
{
	ll_ioepoch_close(inode, op_data, och, LLIF_DONE_WRITING);
	/* If there is no @och, we do not do D_W yet. */
	if (*och == NULL)
		return;

	ll_pack_inode2opdata(inode, op_data, &(*och)->och_fh);
	ll_prep_md_op_data(op_data, inode, NULL, NULL,
			   0, 0, LUSTRE_OPC_ANY, NULL);
}

/** Send a DONE_WRITING rpc. */
static void ll_done_writing(struct inode *inode)
{
	struct obd_client_handle *och = NULL;
	struct md_op_data *op_data;
	int rc;

	LASSERT(exp_connect_som(ll_i2mdexp(inode)));

	op_data = kzalloc(sizeof(*op_data), GFP_NOFS);
	if (!op_data)
		return;

	ll_prepare_done_writing(inode, op_data, &och);
	/* If there is no @och, we do not do D_W yet. */
	if (och == NULL)
		goto out;

	rc = md_done_writing(ll_i2sbi(inode)->ll_md_exp, op_data, NULL);
	if (rc == -EAGAIN)
		/* MDS has instructed us to obtain Size-on-MDS attribute from
		 * OSTs and send setattr to back to MDS. */
		rc = ll_som_update(inode, op_data);
	else if (rc)
		CERROR("inode %lu mdc done_writing failed: rc = %d\n",
		       inode->i_ino, rc);
out:
	ll_finish_md_op_data(op_data);
	if (och) {
		md_clear_open_replay_data(ll_i2sbi(inode)->ll_md_exp, och);
		kfree(och);
	}
}

static struct ll_inode_info *ll_close_next_lli(struct ll_close_queue *lcq)
{
	struct ll_inode_info *lli = NULL;

	spin_lock(&lcq->lcq_lock);

	if (!list_empty(&lcq->lcq_head)) {
		lli = list_entry(lcq->lcq_head.next, struct ll_inode_info,
				     lli_close_list);
		list_del_init(&lli->lli_close_list);
	} else if (atomic_read(&lcq->lcq_stop))
		lli = ERR_PTR(-EALREADY);

	spin_unlock(&lcq->lcq_lock);
	return lli;
}

static int ll_close_thread(void *arg)
{
	struct ll_close_queue *lcq = arg;

	complete(&lcq->lcq_comp);

	while (1) {
		struct l_wait_info lwi = { 0 };
		struct ll_inode_info *lli;
		struct inode *inode;

		l_wait_event_exclusive(lcq->lcq_waitq,
				       (lli = ll_close_next_lli(lcq)) != NULL,
				       &lwi);
		if (IS_ERR(lli))
			break;

		inode = ll_info2i(lli);
		CDEBUG(D_INFO, "done_writing for inode %lu/%u\n",
		       inode->i_ino, inode->i_generation);
		ll_done_writing(inode);
		iput(inode);
	}

	CDEBUG(D_INFO, "ll_close exiting\n");
	complete(&lcq->lcq_comp);
	return 0;
}

int ll_close_thread_start(struct ll_close_queue **lcq_ret)
{
	struct ll_close_queue *lcq;
	struct task_struct *task;

	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CLOSE_THREAD))
		return -EINTR;

	lcq = kzalloc(sizeof(*lcq), GFP_NOFS);
	if (!lcq)
		return -ENOMEM;

	spin_lock_init(&lcq->lcq_lock);
	INIT_LIST_HEAD(&lcq->lcq_head);
	init_waitqueue_head(&lcq->lcq_waitq);
	init_completion(&lcq->lcq_comp);

	task = kthread_run(ll_close_thread, lcq, "ll_close");
	if (IS_ERR(task)) {
		kfree(lcq);
		return PTR_ERR(task);
	}

	wait_for_completion(&lcq->lcq_comp);
	*lcq_ret = lcq;
	return 0;
}

void ll_close_thread_shutdown(struct ll_close_queue *lcq)
{
	init_completion(&lcq->lcq_comp);
	atomic_inc(&lcq->lcq_stop);
	wake_up(&lcq->lcq_waitq);
	wait_for_completion(&lcq->lcq_comp);
	kfree(lcq);
}
