/*
 * 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.
 */

#define DEBUG_SUBSYSTEM S_RPC

#include "../include/obd.h"
#include "../include/obd_support.h"
#include "../include/obd_class.h"
#include "../include/lustre_lib.h"
#include "../include/lustre_ha.h"
#include "../include/lustre_net.h"
#include "../include/lprocfs_status.h"

#define NIDS_MAX	32

struct uuid_nid_data {
	struct list_head       un_list;
	struct obd_uuid  un_uuid;
	int	      un_nid_count;
	lnet_nid_t       un_nids[NIDS_MAX];
};

/* FIXME: This should probably become more elegant than a global linked list */
static struct list_head	g_uuid_list;
static spinlock_t	g_uuid_lock;

void class_init_uuidlist(void)
{
	INIT_LIST_HEAD(&g_uuid_list);
	spin_lock_init(&g_uuid_lock);
}

void class_exit_uuidlist(void)
{
	/* delete all */
	class_del_uuid(NULL);
}

int lustre_uuid_to_peer(const char *uuid, lnet_nid_t *peer_nid, int index)
{
	struct uuid_nid_data *data;
	struct obd_uuid tmp;
	int rc = -ENOENT;

	obd_str2uuid(&tmp, uuid);
	spin_lock(&g_uuid_lock);
	list_for_each_entry(data, &g_uuid_list, un_list) {
		if (obd_uuid_equals(&data->un_uuid, &tmp)) {
			if (index >= data->un_nid_count)
				break;

			rc = 0;
			*peer_nid = data->un_nids[index];
			break;
		}
	}
	spin_unlock(&g_uuid_lock);
	return rc;
}
EXPORT_SYMBOL(lustre_uuid_to_peer);

/* Add a nid to a niduuid.  Multiple nids can be added to a single uuid;
   LNET will choose the best one. */
int class_add_uuid(const char *uuid, __u64 nid)
{
	struct uuid_nid_data *data, *entry;
	int found = 0;

	LASSERT(nid != 0);  /* valid newconfig NID is never zero */

	if (strlen(uuid) > UUID_MAX - 1)
		return -EOVERFLOW;

	OBD_ALLOC_PTR(data);
	if (data == NULL)
		return -ENOMEM;

	obd_str2uuid(&data->un_uuid, uuid);
	data->un_nids[0] = nid;
	data->un_nid_count = 1;

	spin_lock(&g_uuid_lock);
	list_for_each_entry(entry, &g_uuid_list, un_list) {
		if (obd_uuid_equals(&entry->un_uuid, &data->un_uuid)) {
			int i;

			found = 1;
			for (i = 0; i < entry->un_nid_count; i++)
				if (nid == entry->un_nids[i])
					break;

			if (i == entry->un_nid_count) {
				LASSERT(entry->un_nid_count < NIDS_MAX);
				entry->un_nids[entry->un_nid_count++] = nid;
			}
			break;
		}
	}
	if (!found)
		list_add(&data->un_list, &g_uuid_list);
	spin_unlock(&g_uuid_lock);

	if (found) {
		CDEBUG(D_INFO, "found uuid %s %s cnt=%d\n", uuid,
		       libcfs_nid2str(nid), entry->un_nid_count);
		OBD_FREE(data, sizeof(*data));
	} else {
		CDEBUG(D_INFO, "add uuid %s %s\n", uuid, libcfs_nid2str(nid));
	}
	return 0;
}
EXPORT_SYMBOL(class_add_uuid);

/* Delete the nids for one uuid if specified, otherwise delete all */
int class_del_uuid(const char *uuid)
{
	LIST_HEAD(deathrow);
	struct uuid_nid_data *data;

	spin_lock(&g_uuid_lock);
	if (uuid != NULL) {
		struct obd_uuid tmp;

		obd_str2uuid(&tmp, uuid);
		list_for_each_entry(data, &g_uuid_list, un_list) {
			if (obd_uuid_equals(&data->un_uuid, &tmp)) {
				list_move(&data->un_list, &deathrow);
				break;
			}
		}
	} else
		list_splice_init(&g_uuid_list, &deathrow);
	spin_unlock(&g_uuid_lock);

	if (uuid != NULL && list_empty(&deathrow)) {
		CDEBUG(D_INFO, "Try to delete a non-existent uuid %s\n", uuid);
		return -EINVAL;
	}

	while (!list_empty(&deathrow)) {
		data = list_entry(deathrow.next, struct uuid_nid_data,
				      un_list);
		list_del(&data->un_list);

		CDEBUG(D_INFO, "del uuid %s %s/%d\n",
		       obd_uuid2str(&data->un_uuid),
		       libcfs_nid2str(data->un_nids[0]),
		       data->un_nid_count);

		OBD_FREE(data, sizeof(*data));
	}

	return 0;
}

/* check if @nid exists in nid list of @uuid */
int class_check_uuid(struct obd_uuid *uuid, __u64 nid)
{
	struct uuid_nid_data *entry;
	int found = 0;

	CDEBUG(D_INFO, "check if uuid %s has %s.\n",
	       obd_uuid2str(uuid), libcfs_nid2str(nid));

	spin_lock(&g_uuid_lock);
	list_for_each_entry(entry, &g_uuid_list, un_list) {
		int i;

		if (!obd_uuid_equals(&entry->un_uuid, uuid))
			continue;

		/* found the uuid, check if it has @nid */
		for (i = 0; i < entry->un_nid_count; i++) {
			if (entry->un_nids[i] == nid) {
				found = 1;
				break;
			}
		}
		break;
	}
	spin_unlock(&g_uuid_lock);
	return found;
}
EXPORT_SYMBOL(class_check_uuid);
