/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License version 2.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/kmod.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/lm_interface.h>

struct lmh_wrapper {
	struct list_head lw_list;
	const struct lm_lockops *lw_ops;
};

/* List of registered low-level locking protocols.  A file system selects one
   of them by name at mount time, e.g. lock_nolock, lock_dlm. */

static LIST_HEAD(lmh_list);
static DEFINE_MUTEX(lmh_lock);

/**
 * gfs2_register_lockproto - Register a low-level locking protocol
 * @proto: the protocol definition
 *
 * Returns: 0 on success, -EXXX on failure
 */

int gfs2_register_lockproto(const struct lm_lockops *proto)
{
	struct lmh_wrapper *lw;

	mutex_lock(&lmh_lock);

	list_for_each_entry(lw, &lmh_list, lw_list) {
		if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
			mutex_unlock(&lmh_lock);
			printk(KERN_INFO "GFS2: protocol %s already exists\n",
			       proto->lm_proto_name);
			return -EEXIST;
		}
	}

	lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL);
	if (!lw) {
		mutex_unlock(&lmh_lock);
		return -ENOMEM;
	}

	lw->lw_ops = proto;
	list_add(&lw->lw_list, &lmh_list);

	mutex_unlock(&lmh_lock);

	return 0;
}

/**
 * gfs2_unregister_lockproto - Unregister a low-level locking protocol
 * @proto: the protocol definition
 *
 */

void gfs2_unregister_lockproto(const struct lm_lockops *proto)
{
	struct lmh_wrapper *lw;

	mutex_lock(&lmh_lock);

	list_for_each_entry(lw, &lmh_list, lw_list) {
		if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) {
			list_del(&lw->lw_list);
			mutex_unlock(&lmh_lock);
			kfree(lw);
			return;
		}
	}

	mutex_unlock(&lmh_lock);

	printk(KERN_WARNING "GFS2: can't unregister lock protocol %s\n",
	       proto->lm_proto_name);
}

/**
 * gfs2_mount_lockproto - Mount a lock protocol
 * @proto_name - the name of the protocol
 * @table_name - the name of the lock space
 * @host_data - data specific to this host
 * @cb - the callback to the code using the lock module
 * @sdp - The GFS2 superblock
 * @min_lvb_size - the mininum LVB size that the caller can deal with
 * @flags - LM_MFLAG_*
 * @lockstruct - a structure returned describing the mount
 *
 * Returns: 0 on success, -EXXX on failure
 */

int gfs2_mount_lockproto(char *proto_name, char *table_name, char *host_data,
			 lm_callback_t cb, void *cb_data,
			 unsigned int min_lvb_size, int flags,
			 struct lm_lockstruct *lockstruct,
			 struct kobject *fskobj)
{
	struct lmh_wrapper *lw = NULL;
	int try = 0;
	int error, found;

retry:
	mutex_lock(&lmh_lock);

	found = 0;
	list_for_each_entry(lw, &lmh_list, lw_list) {
		if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) {
			found = 1;
			break;
		}
	}

	if (!found) {
		if (!try && capable(CAP_SYS_MODULE)) {
			try = 1;
			mutex_unlock(&lmh_lock);
			request_module(proto_name);
			goto retry;
		}
		printk(KERN_INFO "GFS2: can't find protocol %s\n", proto_name);
		error = -ENOENT;
		goto out;
	}

	if (!try_module_get(lw->lw_ops->lm_owner)) {
		try = 0;
		mutex_unlock(&lmh_lock);
		msleep(1000);
		goto retry;
	}

	error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data,
				     min_lvb_size, flags, lockstruct, fskobj);
	if (error)
		module_put(lw->lw_ops->lm_owner);
out:
	mutex_unlock(&lmh_lock);
	return error;
}

void gfs2_unmount_lockproto(struct lm_lockstruct *lockstruct)
{
	mutex_lock(&lmh_lock);
	lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace);
	if (lockstruct->ls_ops->lm_owner)
		module_put(lockstruct->ls_ops->lm_owner);
	mutex_unlock(&lmh_lock);
}

/**
 * gfs2_withdraw_lockproto - abnormally unmount a lock module
 * @lockstruct: the lockstruct passed into mount
 *
 */

void gfs2_withdraw_lockproto(struct lm_lockstruct *lockstruct)
{
	mutex_lock(&lmh_lock);
	lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace);
	if (lockstruct->ls_ops->lm_owner)
		module_put(lockstruct->ls_ops->lm_owner);
	mutex_unlock(&lmh_lock);
}

EXPORT_SYMBOL_GPL(gfs2_register_lockproto);
EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto);

