/*
 * 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) 2008, 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.
 *
 * Implementation of cl_lock for LOVSUB layer.
 *
 *   Author: Nikita Danilov <nikita.danilov@sun.com>
 */

#define DEBUG_SUBSYSTEM S_LOV

#include "lov_cl_internal.h"

/** \addtogroup lov
 *  @{
 */

/*****************************************************************************
 *
 * Lovsub lock operations.
 *
 */

static void lovsub_lock_fini(const struct lu_env *env,
			     struct cl_lock_slice *slice)
{
	struct lovsub_lock   *lsl;

	lsl = cl2lovsub_lock(slice);
	LASSERT(list_empty(&lsl->lss_parents));
	OBD_SLAB_FREE_PTR(lsl, lovsub_lock_kmem);
}

static void lovsub_parent_lock(const struct lu_env *env, struct lov_lock *lov)
{
	struct cl_lock *parent;

	parent = lov->lls_cl.cls_lock;
	cl_lock_get(parent);
	lu_ref_add(&parent->cll_reference, "lovsub-parent", current);
	cl_lock_mutex_get(env, parent);
}

static void lovsub_parent_unlock(const struct lu_env *env, struct lov_lock *lov)
{
	struct cl_lock *parent;

	parent = lov->lls_cl.cls_lock;
	cl_lock_mutex_put(env, lov->lls_cl.cls_lock);
	lu_ref_del(&parent->cll_reference, "lovsub-parent", current);
	cl_lock_put(env, parent);
}

/**
 * Implements cl_lock_operations::clo_state() method for lovsub layer, which
 * method is called whenever sub-lock state changes. Propagates state change
 * to the top-locks.
 */
static void lovsub_lock_state(const struct lu_env *env,
			      const struct cl_lock_slice *slice,
			      enum cl_lock_state state)
{
	struct lovsub_lock   *sub = cl2lovsub_lock(slice);
	struct lov_lock_link *scan;

	LASSERT(cl_lock_is_mutexed(slice->cls_lock));

	list_for_each_entry(scan, &sub->lss_parents, lll_list) {
		struct lov_lock *lov    = scan->lll_super;
		struct cl_lock  *parent = lov->lls_cl.cls_lock;

		if (sub->lss_active != parent) {
			lovsub_parent_lock(env, lov);
			cl_lock_signal(env, parent);
			lovsub_parent_unlock(env, lov);
		}
	}
}

/**
 * Implementation of cl_lock_operation::clo_weigh() estimating lock weight by
 * asking parent lock.
 */
static unsigned long lovsub_lock_weigh(const struct lu_env *env,
				       const struct cl_lock_slice *slice)
{
	struct lovsub_lock *lock = cl2lovsub_lock(slice);
	struct lov_lock    *lov;
	unsigned long       dumbbell;

	LASSERT(cl_lock_is_mutexed(slice->cls_lock));

	if (!list_empty(&lock->lss_parents)) {
		/*
		 * It is not clear whether all parents have to be asked and
		 * their estimations summed, or it is enough to ask one. For
		 * the current usages, one is always enough.
		 */
		lov = container_of(lock->lss_parents.next,
				   struct lov_lock_link, lll_list)->lll_super;

		lovsub_parent_lock(env, lov);
		dumbbell = cl_lock_weigh(env, lov->lls_cl.cls_lock);
		lovsub_parent_unlock(env, lov);
	} else
		dumbbell = 0;

	return dumbbell;
}

/**
 * Maps start/end offsets within a stripe, to offsets within a file.
 */
static void lovsub_lock_descr_map(const struct cl_lock_descr *in,
				  struct lov_object *lov,
				  int stripe, struct cl_lock_descr *out)
{
	pgoff_t size; /* stripe size in pages */
	pgoff_t skip; /* how many pages in every stripe are occupied by
		       * "other" stripes */
	pgoff_t start;
	pgoff_t end;

	start = in->cld_start;
	end   = in->cld_end;

	if (lov->lo_lsm->lsm_stripe_count > 1) {
		size = cl_index(lov2cl(lov), lov->lo_lsm->lsm_stripe_size);
		skip = (lov->lo_lsm->lsm_stripe_count - 1) * size;

		/* XXX overflow check here? */
		start += start/size * skip + stripe * size;

		if (end != CL_PAGE_EOF) {
			end += end/size * skip + stripe * size;
			/*
			 * And check for overflow...
			 */
			if (end < in->cld_end)
				end = CL_PAGE_EOF;
		}
	}
	out->cld_start = start;
	out->cld_end   = end;
}

/**
 * Adjusts parent lock extent when a sub-lock is attached to a parent. This is
 * called in two ways:
 *
 *     - as part of receive call-back, when server returns granted extent to
 *       the client, and
 *
 *     - when top-lock finds existing sub-lock in the cache.
 *
 * Note, that lock mode is not propagated to the parent: i.e., if CLM_READ
 * top-lock matches CLM_WRITE sub-lock, top-lock is still CLM_READ.
 */
int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
		       struct lovsub_lock *sublock,
		       const struct cl_lock_descr *d, int idx)
{
	struct cl_lock       *parent;
	struct lovsub_object *subobj;
	struct cl_lock_descr *pd;
	struct cl_lock_descr *parent_descr;
	int		   result;

	parent       = lov->lls_cl.cls_lock;
	parent_descr = &parent->cll_descr;
	LASSERT(cl_lock_mode_match(d->cld_mode, parent_descr->cld_mode));

	subobj = cl2lovsub(sublock->lss_cl.cls_obj);
	pd     = &lov_env_info(env)->lti_ldescr;

	pd->cld_obj  = parent_descr->cld_obj;
	pd->cld_mode = parent_descr->cld_mode;
	pd->cld_gid  = parent_descr->cld_gid;
	lovsub_lock_descr_map(d, subobj->lso_super, subobj->lso_index, pd);
	lov->lls_sub[idx].sub_got = *d;
	/*
	 * Notify top-lock about modification, if lock description changes
	 * materially.
	 */
	if (!cl_lock_ext_match(parent_descr, pd))
		result = cl_lock_modify(env, parent, pd);
	else
		result = 0;
	return result;
}

static int lovsub_lock_modify(const struct lu_env *env,
			      const struct cl_lock_slice *s,
			      const struct cl_lock_descr *d)
{
	struct lovsub_lock   *lock   = cl2lovsub_lock(s);
	struct lov_lock_link *scan;
	struct lov_lock      *lov;
	int result		   = 0;

	LASSERT(cl_lock_mode_match(d->cld_mode,
				   s->cls_lock->cll_descr.cld_mode));
	list_for_each_entry(scan, &lock->lss_parents, lll_list) {
		int rc;

		lov = scan->lll_super;
		lovsub_parent_lock(env, lov);
		rc = lov_sublock_modify(env, lov, lock, d, scan->lll_idx);
		lovsub_parent_unlock(env, lov);
		result = result ?: rc;
	}
	return result;
}

static int lovsub_lock_closure(const struct lu_env *env,
			       const struct cl_lock_slice *slice,
			       struct cl_lock_closure *closure)
{
	struct lovsub_lock   *sub;
	struct cl_lock       *parent;
	struct lov_lock_link *scan;
	int		   result;

	LASSERT(cl_lock_is_mutexed(slice->cls_lock));

	sub    = cl2lovsub_lock(slice);
	result = 0;

	list_for_each_entry(scan, &sub->lss_parents, lll_list) {
		parent = scan->lll_super->lls_cl.cls_lock;
		result = cl_lock_closure_build(env, parent, closure);
		if (result != 0)
			break;
	}
	return result;
}

/**
 * A helper function for lovsub_lock_delete() that deals with a given parent
 * top-lock.
 */
static int lovsub_lock_delete_one(const struct lu_env *env,
				  struct cl_lock *child, struct lov_lock *lov)
{
	struct cl_lock *parent;
	int	     result;

	parent = lov->lls_cl.cls_lock;
	if (parent->cll_error)
		return 0;

	result = 0;
	switch (parent->cll_state) {
	case CLS_ENQUEUED:
		/* See LU-1355 for the case that a glimpse lock is
		 * interrupted by signal */
		LASSERT(parent->cll_flags & CLF_CANCELLED);
		break;
	case CLS_QUEUING:
	case CLS_FREEING:
		cl_lock_signal(env, parent);
		break;
	case CLS_INTRANSIT:
		/*
		 * Here lies a problem: a sub-lock is canceled while top-lock
		 * is being unlocked. Top-lock cannot be moved into CLS_NEW
		 * state, because unlocking has to succeed eventually by
		 * placing lock into CLS_CACHED (or failing it), see
		 * cl_unuse_try(). Nor can top-lock be left in CLS_CACHED
		 * state, because lov maintains an invariant that all
		 * sub-locks exist in CLS_CACHED (this allows cached top-lock
		 * to be reused immediately). Nor can we wait for top-lock
		 * state to change, because this can be synchronous to the
		 * current thread.
		 *
		 * We know for sure that lov_lock_unuse() will be called at
		 * least one more time to finish un-using, so leave a mark on
		 * the top-lock, that will be seen by the next call to
		 * lov_lock_unuse().
		 */
		if (cl_lock_is_intransit(parent))
			lov->lls_cancel_race = 1;
		break;
	case CLS_CACHED:
		/*
		 * if a sub-lock is canceled move its top-lock into CLS_NEW
		 * state to preserve an invariant that a top-lock in
		 * CLS_CACHED is immediately ready for re-use (i.e., has all
		 * sub-locks), and so that next attempt to re-use the top-lock
		 * enqueues missing sub-lock.
		 */
		cl_lock_state_set(env, parent, CLS_NEW);
		/* fall through */
	case CLS_NEW:
		/*
		 * if last sub-lock is canceled, destroy the top-lock (which
		 * is now `empty') proactively.
		 */
		if (lov->lls_nr_filled == 0) {
			/* ... but unfortunately, this cannot be done easily,
			 * as cancellation of a top-lock might acquire mutices
			 * of its other sub-locks, violating lock ordering,
			 * see cl_lock_{cancel,delete}() preconditions.
			 *
			 * To work around this, the mutex of this sub-lock is
			 * released, top-lock is destroyed, and sub-lock mutex
			 * acquired again. The list of parents has to be
			 * re-scanned from the beginning after this.
			 *
			 * Only do this if no mutices other than on @child and
			 * @parent are held by the current thread.
			 *
			 * TODO: The lock modal here is too complex, because
			 * the lock may be canceled and deleted by voluntarily:
			 *    cl_lock_request
			 *      -> osc_lock_enqueue_wait
			 *	-> osc_lock_cancel_wait
			 *	  -> cl_lock_delete
			 *	    -> lovsub_lock_delete
			 *	      -> cl_lock_cancel/delete
			 *		-> ...
			 *
			 * The better choice is to spawn a kernel thread for
			 * this purpose. -jay
			 */
			if (cl_lock_nr_mutexed(env) == 2) {
				cl_lock_mutex_put(env, child);
				cl_lock_cancel(env, parent);
				cl_lock_delete(env, parent);
				result = 1;
			}
		}
		break;
	case CLS_HELD:
		CL_LOCK_DEBUG(D_ERROR, env, parent, "Delete CLS_HELD lock\n");
	default:
		CERROR("Impossible state: %d\n", parent->cll_state);
		LBUG();
		break;
	}

	return result;
}

/**
 * An implementation of cl_lock_operations::clo_delete() method. This is
 * invoked in "bottom-to-top" delete, when lock destruction starts from the
 * sub-lock (e.g, as a result of ldlm lock LRU policy).
 */
static void lovsub_lock_delete(const struct lu_env *env,
			       const struct cl_lock_slice *slice)
{
	struct cl_lock     *child = slice->cls_lock;
	struct lovsub_lock *sub   = cl2lovsub_lock(slice);
	int restart;

	LASSERT(cl_lock_is_mutexed(child));

	/*
	 * Destruction of a sub-lock might take multiple iterations, because
	 * when the last sub-lock of a given top-lock is deleted, top-lock is
	 * canceled proactively, and this requires to release sub-lock
	 * mutex. Once sub-lock mutex has been released, list of its parents
	 * has to be re-scanned from the beginning.
	 */
	do {
		struct lov_lock      *lov;
		struct lov_lock_link *scan;
		struct lov_lock_link *temp;
		struct lov_lock_sub  *subdata;

		restart = 0;
		list_for_each_entry_safe(scan, temp,
					     &sub->lss_parents, lll_list) {
			lov     = scan->lll_super;
			subdata = &lov->lls_sub[scan->lll_idx];
			lovsub_parent_lock(env, lov);
			subdata->sub_got = subdata->sub_descr;
			lov_lock_unlink(env, scan, sub);
			restart = lovsub_lock_delete_one(env, child, lov);
			lovsub_parent_unlock(env, lov);

			if (restart) {
				cl_lock_mutex_get(env, child);
				break;
			}
	       }
	} while (restart);
}

static int lovsub_lock_print(const struct lu_env *env, void *cookie,
			     lu_printer_t p, const struct cl_lock_slice *slice)
{
	struct lovsub_lock   *sub = cl2lovsub_lock(slice);
	struct lov_lock      *lov;
	struct lov_lock_link *scan;

	list_for_each_entry(scan, &sub->lss_parents, lll_list) {
		lov = scan->lll_super;
		(*p)(env, cookie, "[%d %p ", scan->lll_idx, lov);
		if (lov != NULL)
			cl_lock_descr_print(env, cookie, p,
					    &lov->lls_cl.cls_lock->cll_descr);
		(*p)(env, cookie, "] ");
	}
	return 0;
}

static const struct cl_lock_operations lovsub_lock_ops = {
	.clo_fini    = lovsub_lock_fini,
	.clo_state   = lovsub_lock_state,
	.clo_delete  = lovsub_lock_delete,
	.clo_modify  = lovsub_lock_modify,
	.clo_closure = lovsub_lock_closure,
	.clo_weigh   = lovsub_lock_weigh,
	.clo_print   = lovsub_lock_print
};

int lovsub_lock_init(const struct lu_env *env, struct cl_object *obj,
		     struct cl_lock *lock, const struct cl_io *io)
{
	struct lovsub_lock *lsk;
	int result;

	OBD_SLAB_ALLOC_PTR_GFP(lsk, lovsub_lock_kmem, GFP_NOFS);
	if (lsk != NULL) {
		INIT_LIST_HEAD(&lsk->lss_parents);
		cl_lock_slice_add(lock, &lsk->lss_cl, obj, &lovsub_lock_ops);
		result = 0;
	} else
		result = -ENOMEM;
	return result;
}

/** @} lov */
