/*
 * 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.gnu.org/licenses/gpl-2.0.html
 *
 * 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.
 *
 * Client Extent Lock.
 *
 *   Author: Nikita Danilov <nikita.danilov@sun.com>
 *   Author: Jinshan Xiong <jinshan.xiong@intel.com>
 */

#define DEBUG_SUBSYSTEM S_CLASS

#include "../include/obd_class.h"
#include "../include/obd_support.h"
#include "../include/lustre_fid.h"
#include <linux/list.h>
#include "../include/cl_object.h"
#include "cl_internal.h"

static void cl_lock_trace0(int level, const struct lu_env *env,
			   const char *prefix, const struct cl_lock *lock,
			   const char *func, const int line)
{
	struct cl_object_header *h = cl_object_header(lock->cll_descr.cld_obj);

	CDEBUG(level, "%s: %p (%p/%d) at %s():%d\n",
	       prefix, lock, env, h->coh_nesting, func, line);
}
#define cl_lock_trace(level, env, prefix, lock)				\
	cl_lock_trace0(level, env, prefix, lock, __func__, __LINE__)

/**
 * Adds lock slice to the compound lock.
 *
 * This is called by cl_object_operations::coo_lock_init() methods to add a
 * per-layer state to the lock. New state is added at the end of
 * cl_lock::cll_layers list, that is, it is at the bottom of the stack.
 *
 * \see cl_req_slice_add(), cl_page_slice_add(), cl_io_slice_add()
 */
void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice,
		       struct cl_object *obj,
		       const struct cl_lock_operations *ops)
{
	slice->cls_lock = lock;
	list_add_tail(&slice->cls_linkage, &lock->cll_layers);
	slice->cls_obj = obj;
	slice->cls_ops = ops;
}
EXPORT_SYMBOL(cl_lock_slice_add);

void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock)
{
	cl_lock_trace(D_DLMTRACE, env, "destroy lock", lock);

	while (!list_empty(&lock->cll_layers)) {
		struct cl_lock_slice *slice;

		slice = list_entry(lock->cll_layers.next,
				   struct cl_lock_slice, cls_linkage);
		list_del_init(lock->cll_layers.next);
		slice->cls_ops->clo_fini(env, slice);
	}
	POISON(lock, 0x5a, sizeof(*lock));
}
EXPORT_SYMBOL(cl_lock_fini);

int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
		 const struct cl_io *io)
{
	struct cl_object *obj = lock->cll_descr.cld_obj;
	struct cl_object *scan;
	int result = 0;

	/* Make sure cl_lock::cll_descr is initialized. */
	LASSERT(obj);

	INIT_LIST_HEAD(&lock->cll_layers);
	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
			    co_lu.lo_linkage) {
		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
		if (result != 0) {
			cl_lock_fini(env, lock);
			break;
		}
	}

	return result;
}
EXPORT_SYMBOL(cl_lock_init);

/**
 * Returns a slice with a lock, corresponding to the given layer in the
 * device stack.
 *
 * \see cl_page_at()
 */
const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock,
				       const struct lu_device_type *dtype)
{
	const struct cl_lock_slice *slice;

	list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
		if (slice->cls_obj->co_lu.lo_dev->ld_type == dtype)
			return slice;
	}
	return NULL;
}
EXPORT_SYMBOL(cl_lock_at);

void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock)
{
	const struct cl_lock_slice *slice;

	cl_lock_trace(D_DLMTRACE, env, "cancel lock", lock);
	list_for_each_entry_reverse(slice, &lock->cll_layers, cls_linkage) {
		if (slice->cls_ops->clo_cancel)
			slice->cls_ops->clo_cancel(env, slice);
	}
}
EXPORT_SYMBOL(cl_lock_cancel);

/**
 * Enqueue a lock.
 * \param anchor: if we need to wait for resources before getting the lock,
 *		  use @anchor for the purpose.
 * \retval 0  enqueue successfully
 * \retval <0 error code
 */
int cl_lock_enqueue(const struct lu_env *env, struct cl_io *io,
		    struct cl_lock *lock, struct cl_sync_io *anchor)
{
	const struct cl_lock_slice *slice;
	int rc = -ENOSYS;

	list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
		if (!slice->cls_ops->clo_enqueue)
			continue;

		rc = slice->cls_ops->clo_enqueue(env, slice, io, anchor);
		if (rc != 0)
			break;
		}
	return rc;
}
EXPORT_SYMBOL(cl_lock_enqueue);

/**
 * Main high-level entry point of cl_lock interface that finds existing or
 * enqueues new lock matching given description.
 */
int cl_lock_request(const struct lu_env *env, struct cl_io *io,
		    struct cl_lock *lock)
{
	struct cl_sync_io *anchor = NULL;
	__u32 enq_flags = lock->cll_descr.cld_enq_flags;
	int rc;

	rc = cl_lock_init(env, lock, io);
	if (rc < 0)
		return rc;

	if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) {
		anchor = &cl_env_info(env)->clt_anchor;
		cl_sync_io_init(anchor, 1, cl_sync_io_end);
	}

	rc = cl_lock_enqueue(env, io, lock, anchor);

	if (anchor) {
		int rc2;

		/* drop the reference count held at initialization time */
		cl_sync_io_note(env, anchor, 0);
		rc2 = cl_sync_io_wait(env, anchor, 0);
		if (rc2 < 0 && rc == 0)
			rc = rc2;
	}

	if (rc < 0)
		cl_lock_release(env, lock);

	return rc;
}
EXPORT_SYMBOL(cl_lock_request);

/**
 * Releases a hold and a reference on a lock, obtained by cl_lock_hold().
 */
void cl_lock_release(const struct lu_env *env, struct cl_lock *lock)
{
	cl_lock_trace(D_DLMTRACE, env, "release lock", lock);
	cl_lock_cancel(env, lock);
	cl_lock_fini(env, lock);
}
EXPORT_SYMBOL(cl_lock_release);

const char *cl_lock_mode_name(const enum cl_lock_mode mode)
{
	static const char *names[] = {
		[CLM_READ]    = "R",
		[CLM_WRITE]   = "W",
		[CLM_GROUP]   = "G"
	};
	if (0 <= mode && mode < ARRAY_SIZE(names))
		return names[mode];
	else
		return "U";
}
EXPORT_SYMBOL(cl_lock_mode_name);

/**
 * Prints human readable representation of a lock description.
 */
void cl_lock_descr_print(const struct lu_env *env, void *cookie,
			 lu_printer_t printer,
			 const struct cl_lock_descr *descr)
{
	const struct lu_fid  *fid;

	fid = lu_object_fid(&descr->cld_obj->co_lu);
	(*printer)(env, cookie, DDESCR"@"DFID, PDESCR(descr), PFID(fid));
}
EXPORT_SYMBOL(cl_lock_descr_print);

/**
 * Prints human readable representation of \a lock to the \a f.
 */
void cl_lock_print(const struct lu_env *env, void *cookie,
		   lu_printer_t printer, const struct cl_lock *lock)
{
	const struct cl_lock_slice *slice;

	(*printer)(env, cookie, "lock@%p", lock);
	cl_lock_descr_print(env, cookie, printer, &lock->cll_descr);
	(*printer)(env, cookie, " {\n");

	list_for_each_entry(slice, &lock->cll_layers, cls_linkage) {
		(*printer)(env, cookie, "    %s@%p: ",
			   slice->cls_obj->co_lu.lo_dev->ld_type->ldt_name,
			   slice);
		if (slice->cls_ops->clo_print)
			slice->cls_ops->clo_print(env, cookie, printer, slice);
		(*printer)(env, cookie, "\n");
	}
	(*printer)(env, cookie, "} lock@%p\n", lock);
}
EXPORT_SYMBOL(cl_lock_print);
