/*
 * 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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2015, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/obdclass/obd_config.c
 *
 * Config API
 */

#define DEBUG_SUBSYSTEM S_CLASS
#include "../include/obd_class.h"
#include <linux/string.h>
#include "../include/lustre_log.h"
#include "../include/lprocfs_status.h"
#include "../include/lustre_param.h"

#include "llog_internal.h"

static struct cfs_hash_ops uuid_hash_ops;

/*********** string parsing utils *********/

/* returns 0 if we find this key in the buffer, else 1 */
int class_find_param(char *buf, char *key, char **valp)
{
	char *ptr;

	if (!buf)
		return 1;

	ptr = strstr(buf, key);
	if (!ptr)
		return 1;

	if (valp)
		*valp = ptr + strlen(key);

	return 0;
}
EXPORT_SYMBOL(class_find_param);

/* returns 0 if this is the first key in the buffer, else 1.
 * valp points to first char after key.
 */
static int class_match_param(char *buf, const char *key, char **valp)
{
	if (!buf)
		return 1;

	if (memcmp(buf, key, strlen(key)) != 0)
		return 1;

	if (valp)
		*valp = buf + strlen(key);

	return 0;
}

static int parse_nid(char *buf, void *value, int quiet)
{
	lnet_nid_t *nid = value;

	*nid = libcfs_str2nid(buf);
	if (*nid != LNET_NID_ANY)
		return 0;

	if (!quiet)
		LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
	return -EINVAL;
}

static int parse_net(char *buf, void *value)
{
	__u32 *net = value;

	*net = libcfs_str2net(buf);
	CDEBUG(D_INFO, "Net %s\n", libcfs_net2str(*net));
	return 0;
}

enum {
	CLASS_PARSE_NID = 1,
	CLASS_PARSE_NET,
};

/* 0 is good nid,
 * 1 not found
 * < 0 error
 * endh is set to next separator
 */
static int class_parse_value(char *buf, int opc, void *value, char **endh,
			     int quiet)
{
	char *endp;
	char  tmp;
	int   rc = 0;

	if (!buf)
		return 1;
	while (*buf == ',' || *buf == ':')
		buf++;
	if (*buf == ' ' || *buf == '/' || *buf == '\0')
		return 1;

	/* nid separators or end of nids */
	endp = strpbrk(buf, ",: /");
	if (!endp)
		endp = buf + strlen(buf);

	tmp = *endp;
	*endp = '\0';
	switch (opc) {
	default:
		LBUG();
	case CLASS_PARSE_NID:
		rc = parse_nid(buf, value, quiet);
		break;
	case CLASS_PARSE_NET:
		rc = parse_net(buf, value);
		break;
	}
	*endp = tmp;
	if (rc != 0)
		return rc;
	if (endh)
		*endh = endp;
	return 0;
}

int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
{
	return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
}
EXPORT_SYMBOL(class_parse_nid);

int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
{
	return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
}
EXPORT_SYMBOL(class_parse_nid_quiet);

/********************** class fns **********************/

/**
 * Create a new obd device and set the type, name and uuid.  If successful,
 * the new device can be accessed by either name or uuid.
 */
static int class_attach(struct lustre_cfg *lcfg)
{
	struct obd_device *obd = NULL;
	char *typename, *name, *uuid;
	int rc, len;

	if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
		CERROR("No type passed!\n");
		return -EINVAL;
	}
	typename = lustre_cfg_string(lcfg, 1);

	if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
		CERROR("No name passed!\n");
		return -EINVAL;
	}
	name = lustre_cfg_string(lcfg, 0);

	if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
		CERROR("No UUID passed!\n");
		return -EINVAL;
	}
	uuid = lustre_cfg_string(lcfg, 2);

	CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
	       MKSTR(typename), MKSTR(name), MKSTR(uuid));

	obd = class_newdev(typename, name);
	if (IS_ERR(obd)) {
		/* Already exists or out of obds */
		rc = PTR_ERR(obd);
		obd = NULL;
		CERROR("Cannot create device %s of type %s : %d\n",
		       name, typename, rc);
		goto out;
	}
	LASSERTF(obd, "Cannot get obd device %s of type %s\n",
		 name, typename);
	LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
		 "obd %p obd_magic %08X != %08X\n",
		 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
	LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
		 "%p obd_name %s != %s\n", obd, obd->obd_name, name);

	rwlock_init(&obd->obd_pool_lock);
	obd->obd_pool_limit = 0;
	obd->obd_pool_slv = 0;

	INIT_LIST_HEAD(&obd->obd_exports);
	INIT_LIST_HEAD(&obd->obd_unlinked_exports);
	INIT_LIST_HEAD(&obd->obd_delayed_exports);
	spin_lock_init(&obd->obd_nid_lock);
	spin_lock_init(&obd->obd_dev_lock);
	mutex_init(&obd->obd_dev_mutex);
	spin_lock_init(&obd->obd_osfs_lock);
	/* obd->obd_osfs_age must be set to a value in the distant
	 * past to guarantee a fresh statfs is fetched on mount.
	 */
	obd->obd_osfs_age = cfs_time_shift_64(-1000);

	/* XXX belongs in setup not attach  */
	init_rwsem(&obd->obd_observer_link_sem);
	/* recovery data */
	init_waitqueue_head(&obd->obd_evict_inprogress_waitq);

	llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);

	obd->obd_conn_inprogress = 0;

	len = strlen(uuid);
	if (len >= sizeof(obd->obd_uuid)) {
		CERROR("uuid must be < %d bytes long\n",
		       (int)sizeof(obd->obd_uuid));
		rc = -EINVAL;
		goto out;
	}
	memcpy(obd->obd_uuid.uuid, uuid, len);

	/* do the attach */
	if (OBP(obd, attach)) {
		rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
		if (rc) {
			rc = -EINVAL;
			goto out;
		}
	}

	/* Detach drops this */
	spin_lock(&obd->obd_dev_lock);
	atomic_set(&obd->obd_refcount, 1);
	spin_unlock(&obd->obd_dev_lock);
	lu_ref_init(&obd->obd_reference);
	lu_ref_add(&obd->obd_reference, "attach", obd);

	obd->obd_attached = 1;
	CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
	       obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
	return 0;
 out:
	if (obd)
		class_release_dev(obd);

	return rc;
}

/** Create hashes, self-export, and call type-specific setup.
 * Setup is effectively the "start this obd" call.
 */
static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	int err = 0;
	struct obd_export *exp;

	LASSERT(obd);
	LASSERTF(obd == class_num2obd(obd->obd_minor),
		 "obd %p != obd_devs[%d] %p\n",
		 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
	LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
		 "obd %p obd_magic %08x != %08x\n",
		 obd, obd->obd_magic, OBD_DEVICE_MAGIC);

	/* have we attached a type to this device? */
	if (!obd->obd_attached) {
		CERROR("Device %d not attached\n", obd->obd_minor);
		return -ENODEV;
	}

	if (obd->obd_set_up) {
		CERROR("Device %d already setup (type %s)\n",
		       obd->obd_minor, obd->obd_type->typ_name);
		return -EEXIST;
	}

	/* is someone else setting us up right now? (attach inits spinlock) */
	spin_lock(&obd->obd_dev_lock);
	if (obd->obd_starting) {
		spin_unlock(&obd->obd_dev_lock);
		CERROR("Device %d setup in progress (type %s)\n",
		       obd->obd_minor, obd->obd_type->typ_name);
		return -EEXIST;
	}
	/* just leave this on forever.  I can't use obd_set_up here because
	 * other fns check that status, and we're not actually set up yet.
	 */
	obd->obd_starting = 1;
	obd->obd_uuid_hash = NULL;
	spin_unlock(&obd->obd_dev_lock);

	/* create an uuid-export lustre hash */
	obd->obd_uuid_hash = cfs_hash_create("UUID_HASH",
					     HASH_UUID_CUR_BITS,
					     HASH_UUID_MAX_BITS,
					     HASH_UUID_BKT_BITS, 0,
					     CFS_HASH_MIN_THETA,
					     CFS_HASH_MAX_THETA,
					     &uuid_hash_ops, CFS_HASH_DEFAULT);
	if (!obd->obd_uuid_hash) {
		err = -ENOMEM;
		goto err_hash;
	}

	exp = class_new_export(obd, &obd->obd_uuid);
	if (IS_ERR(exp)) {
		err = PTR_ERR(exp);
		goto err_hash;
	}

	obd->obd_self_export = exp;
	class_export_put(exp);

	err = obd_setup(obd, lcfg);
	if (err)
		goto err_exp;

	obd->obd_set_up = 1;

	spin_lock(&obd->obd_dev_lock);
	/* cleanup drops this */
	class_incref(obd, "setup", obd);
	spin_unlock(&obd->obd_dev_lock);

	CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
	       obd->obd_name, obd->obd_uuid.uuid);

	return 0;
err_exp:
	if (obd->obd_self_export) {
		class_unlink_export(obd->obd_self_export);
		obd->obd_self_export = NULL;
	}
err_hash:
	if (obd->obd_uuid_hash) {
		cfs_hash_putref(obd->obd_uuid_hash);
		obd->obd_uuid_hash = NULL;
	}
	obd->obd_starting = 0;
	CERROR("setup %s failed (%d)\n", obd->obd_name, err);
	return err;
}

/** We have finished using this obd and are ready to destroy it.
 * There can be no more references to this obd.
 */
static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	if (obd->obd_set_up) {
		CERROR("OBD device %d still set up\n", obd->obd_minor);
		return -EBUSY;
	}

	spin_lock(&obd->obd_dev_lock);
	if (!obd->obd_attached) {
		spin_unlock(&obd->obd_dev_lock);
		CERROR("OBD device %d not attached\n", obd->obd_minor);
		return -ENODEV;
	}
	obd->obd_attached = 0;
	spin_unlock(&obd->obd_dev_lock);

	CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
	       obd->obd_name, obd->obd_uuid.uuid);

	class_decref(obd, "attach", obd);
	return 0;
}

/** Start shutting down the obd.  There may be in-progress ops when
 * this is called.  We tell them to start shutting down with a call
 * to class_disconnect_exports().
 */
static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	int err = 0;
	char *flag;

	OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);

	if (!obd->obd_set_up) {
		CERROR("Device %d not setup\n", obd->obd_minor);
		return -ENODEV;
	}

	spin_lock(&obd->obd_dev_lock);
	if (obd->obd_stopping) {
		spin_unlock(&obd->obd_dev_lock);
		CERROR("OBD %d already stopping\n", obd->obd_minor);
		return -ENODEV;
	}
	/* Leave this on forever */
	obd->obd_stopping = 1;

	/* wait for already-arrived-connections to finish. */
	while (obd->obd_conn_inprogress > 0) {
		spin_unlock(&obd->obd_dev_lock);

		cond_resched();

		spin_lock(&obd->obd_dev_lock);
	}
	spin_unlock(&obd->obd_dev_lock);

	if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
		for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
			switch (*flag) {
			case 'F':
				obd->obd_force = 1;
				break;
			case 'A':
				LCONSOLE_WARN("Failing over %s\n",
					      obd->obd_name);
				obd->obd_fail = 1;
				obd->obd_no_transno = 1;
				obd->obd_no_recov = 1;
				if (OBP(obd, iocontrol)) {
					obd_iocontrol(OBD_IOC_SYNC,
						      obd->obd_self_export,
						      0, NULL, NULL);
				}
				break;
			default:
				CERROR("Unrecognised flag '%c'\n", *flag);
			}
	}

	LASSERT(obd->obd_self_export);

	/* Precleanup, we must make sure all exports get destroyed. */
	err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
	if (err)
		CERROR("Precleanup %s returned %d\n",
		       obd->obd_name, err);

	/* destroy an uuid-export hash body */
	if (obd->obd_uuid_hash) {
		cfs_hash_putref(obd->obd_uuid_hash);
		obd->obd_uuid_hash = NULL;
	}

	class_decref(obd, "setup", obd);
	obd->obd_set_up = 0;

	return 0;
}

struct obd_device *class_incref(struct obd_device *obd,
				const char *scope, const void *source)
{
	lu_ref_add_atomic(&obd->obd_reference, scope, source);
	atomic_inc(&obd->obd_refcount);
	CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
	       atomic_read(&obd->obd_refcount));

	return obd;
}
EXPORT_SYMBOL(class_incref);

void class_decref(struct obd_device *obd, const char *scope, const void *source)
{
	int err;
	int refs;

	spin_lock(&obd->obd_dev_lock);
	atomic_dec(&obd->obd_refcount);
	refs = atomic_read(&obd->obd_refcount);
	spin_unlock(&obd->obd_dev_lock);
	lu_ref_del(&obd->obd_reference, scope, source);

	CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);

	if ((refs == 1) && obd->obd_stopping) {
		/* All exports have been destroyed; there should
		 * be no more in-progress ops by this point.
		 */

		spin_lock(&obd->obd_self_export->exp_lock);
		obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
		spin_unlock(&obd->obd_self_export->exp_lock);

		/* note that we'll recurse into class_decref again */
		class_unlink_export(obd->obd_self_export);
		return;
	}

	if (refs == 0) {
		CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
		       obd->obd_name, obd->obd_uuid.uuid);
		LASSERT(!obd->obd_attached);
		if (obd->obd_stopping) {
			/* If we're not stopping, we were never set up */
			err = obd_cleanup(obd);
			if (err)
				CERROR("Cleanup %s returned %d\n",
				       obd->obd_name, err);
		}
		if (OBP(obd, detach)) {
			err = OBP(obd, detach)(obd);
			if (err)
				CERROR("Detach returned %d\n", err);
		}
		class_release_dev(obd);
	}
}
EXPORT_SYMBOL(class_decref);

/** Add a failover nid location.
 * Client obd types contact server obd types using this nid list.
 */
static int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	struct obd_import *imp;
	struct obd_uuid uuid;
	int rc;

	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
	    LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
		CERROR("invalid conn_uuid\n");
		return -EINVAL;
	}
	if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
	    strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
	    strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) &&
	    strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) &&
	    strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
		CERROR("can't add connection on non-client dev\n");
		return -EINVAL;
	}

	imp = obd->u.cli.cl_import;
	if (!imp) {
		CERROR("try to add conn on immature client dev\n");
		return -EINVAL;
	}

	obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
	rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);

	return rc;
}

/** Remove a failover nid location.
 */
static int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	struct obd_import *imp;
	struct obd_uuid uuid;
	int rc;

	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
	    LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
		CERROR("invalid conn_uuid\n");
		return -EINVAL;
	}
	if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
	    strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
		CERROR("can't del connection on non-client dev\n");
		return -EINVAL;
	}

	imp = obd->u.cli.cl_import;
	if (!imp) {
		CERROR("try to del conn on immature client dev\n");
		return -EINVAL;
	}

	obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
	rc = obd_del_conn(imp, &uuid);

	return rc;
}

static LIST_HEAD(lustre_profile_list);

struct lustre_profile *class_get_profile(const char *prof)
{
	struct lustre_profile *lprof;

	list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
		if (!strcmp(lprof->lp_profile, prof)) {
			return lprof;
		}
	}
	return NULL;
}
EXPORT_SYMBOL(class_get_profile);

/** Create a named "profile".
 * This defines the mdc and osc names to use for a client.
 * This also is used to define the lov to be used by a mdt.
 */
static int class_add_profile(int proflen, char *prof, int osclen, char *osc,
			     int mdclen, char *mdc)
{
	struct lustre_profile *lprof;
	int err = 0;

	CDEBUG(D_CONFIG, "Add profile %s\n", prof);

	lprof = kzalloc(sizeof(*lprof), GFP_NOFS);
	if (!lprof)
		return -ENOMEM;
	INIT_LIST_HEAD(&lprof->lp_list);

	LASSERT(proflen == (strlen(prof) + 1));
	lprof->lp_profile = kmemdup(prof, proflen, GFP_NOFS);
	if (!lprof->lp_profile) {
		err = -ENOMEM;
		goto free_lprof;
	}

	LASSERT(osclen == (strlen(osc) + 1));
	lprof->lp_dt = kmemdup(osc, osclen, GFP_NOFS);
	if (!lprof->lp_dt) {
		err = -ENOMEM;
		goto free_lp_profile;
	}

	if (mdclen > 0) {
		LASSERT(mdclen == (strlen(mdc) + 1));
		lprof->lp_md = kmemdup(mdc, mdclen, GFP_NOFS);
		if (!lprof->lp_md) {
			err = -ENOMEM;
			goto free_lp_dt;
		}
	}

	list_add(&lprof->lp_list, &lustre_profile_list);
	return err;

free_lp_dt:
	kfree(lprof->lp_dt);
free_lp_profile:
	kfree(lprof->lp_profile);
free_lprof:
	kfree(lprof);
	return err;
}

void class_del_profile(const char *prof)
{
	struct lustre_profile *lprof;

	CDEBUG(D_CONFIG, "Del profile %s\n", prof);

	lprof = class_get_profile(prof);
	if (lprof) {
		list_del(&lprof->lp_list);
		kfree(lprof->lp_profile);
		kfree(lprof->lp_dt);
		kfree(lprof->lp_md);
		kfree(lprof);
	}
}
EXPORT_SYMBOL(class_del_profile);

/* COMPAT_146 */
void class_del_profiles(void)
{
	struct lustre_profile *lprof, *n;

	list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
		list_del(&lprof->lp_list);
		kfree(lprof->lp_profile);
		kfree(lprof->lp_dt);
		kfree(lprof->lp_md);
		kfree(lprof);
	}
}
EXPORT_SYMBOL(class_del_profiles);

static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
{
	if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
		at_min = val;
	else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
		at_max = val;
	else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
		at_extra = val;
	else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
		at_early_margin = val;
	else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
		at_history = val;
	else if (class_match_param(ptr, PARAM_JOBID_VAR, NULL) == 0)
		strlcpy(obd_jobid_var, lustre_cfg_string(lcfg, 2),
			JOBSTATS_JOBID_VAR_MAX_LEN + 1);
	else
		return -EINVAL;

	CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
	return 0;
}

/* We can't call ll_process_config or lquota_process_config directly because
 * it lives in a module that must be loaded after this one.
 */
static int (*client_process_config)(struct lustre_cfg *lcfg);
static int (*quota_process_config)(struct lustre_cfg *lcfg);

void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
{
	client_process_config = cpc;
}
EXPORT_SYMBOL(lustre_register_client_process_config);

static int process_param2_config(struct lustre_cfg *lcfg)
{
	char *param = lustre_cfg_string(lcfg, 1);
	char *upcall = lustre_cfg_string(lcfg, 2);
	char *argv[] = {
		[0] = "/usr/sbin/lctl",
		[1] = "set_param",
		[2] = param,
		[3] = NULL
	};
	ktime_t	start;
	ktime_t	end;
	int		rc;

	/* Add upcall processing here. Now only lctl is supported */
	if (strcmp(upcall, LCTL_UPCALL) != 0) {
		CERROR("Unsupported upcall %s\n", upcall);
		return -EINVAL;
	}

	start = ktime_get();
	rc = call_usermodehelper(argv[0], argv, NULL, 1);
	end = ktime_get();

	if (rc < 0) {
		CERROR(
		       "lctl: error invoking upcall %s %s %s: rc = %d; time %ldus\n",
		       argv[0], argv[1], argv[2], rc,
		       (long)ktime_us_delta(end, start));
	} else {
		CDEBUG(D_HA, "lctl: invoked upcall %s %s %s, time %ldus\n",
		       argv[0], argv[1], argv[2],
		       (long)ktime_us_delta(end, start));
		       rc = 0;
	}

	return rc;
}

/** Process configuration commands given in lustre_cfg form.
 * These may come from direct calls (e.g. class_manual_cleanup)
 * or processing the config llog, or ioctl from lctl.
 */
int class_process_config(struct lustre_cfg *lcfg)
{
	struct obd_device *obd;
	int err;

	LASSERT(lcfg && !IS_ERR(lcfg));
	CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);

	/* Commands that don't need a device */
	switch (lcfg->lcfg_command) {
	case LCFG_ATTACH: {
		err = class_attach(lcfg);
		goto out;
	}
	case LCFG_ADD_UUID: {
		CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n",
		       lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
		       libcfs_nid2str(lcfg->lcfg_nid));

		err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
		goto out;
	}
	case LCFG_DEL_UUID: {
		CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
		       (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
		       ? "<all uuids>" : lustre_cfg_string(lcfg, 1));

		err = class_del_uuid(lustre_cfg_string(lcfg, 1));
		goto out;
	}
	case LCFG_MOUNTOPT: {
		CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
		       lustre_cfg_string(lcfg, 1),
		       lustre_cfg_string(lcfg, 2),
		       lustre_cfg_string(lcfg, 3));
		/* set these mount options somewhere, so ll_fill_super
		 * can find them.
		 */
		err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
					lustre_cfg_string(lcfg, 1),
					LUSTRE_CFG_BUFLEN(lcfg, 2),
					lustre_cfg_string(lcfg, 2),
					LUSTRE_CFG_BUFLEN(lcfg, 3),
					lustre_cfg_string(lcfg, 3));
		goto out;
	}
	case LCFG_DEL_MOUNTOPT: {
		CDEBUG(D_IOCTL, "mountopt: profile %s\n",
		       lustre_cfg_string(lcfg, 1));
		class_del_profile(lustre_cfg_string(lcfg, 1));
		err = 0;
		goto out;
	}
	case LCFG_SET_TIMEOUT: {
		CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
		       obd_timeout, lcfg->lcfg_num);
		obd_timeout = max(lcfg->lcfg_num, 1U);
		obd_timeout_set = 1;
		err = 0;
		goto out;
	}
	case LCFG_SET_LDLM_TIMEOUT: {
		/* ldlm_timeout is not used on the client */
		err = 0;
		goto out;
	}
	case LCFG_SET_UPCALL: {
		LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
		/* COMPAT_146 Don't fail on old configs */
		err = 0;
		goto out;
	}
	case LCFG_MARKER: {
		struct cfg_marker *marker;

		marker = lustre_cfg_buf(lcfg, 1);
		CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
		       marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
		err = 0;
		goto out;
	}
	case LCFG_PARAM: {
		char *tmp;
		/* llite has no obd */
		if ((class_match_param(lustre_cfg_string(lcfg, 1),
				       PARAM_LLITE, NULL) == 0) &&
		    client_process_config) {
			err = (*client_process_config)(lcfg);
			goto out;
		} else if ((class_match_param(lustre_cfg_string(lcfg, 1),
					      PARAM_SYS, &tmp) == 0)) {
			/* Global param settings */
			err = class_set_global(tmp, lcfg->lcfg_num, lcfg);
			/*
			 * Client or server should not fail to mount if
			 * it hits an unknown configuration parameter.
			 */
			if (err != 0)
				CWARN("Ignoring unknown param %s\n", tmp);

			err = 0;
			goto out;
		} else if ((class_match_param(lustre_cfg_string(lcfg, 1),
					      PARAM_QUOTA, &tmp) == 0) &&
			   quota_process_config) {
			err = (*quota_process_config)(lcfg);
			goto out;
		}

		break;
	}
	case LCFG_SET_PARAM: {
		err = process_param2_config(lcfg);
		goto out;
	}
	}
	/* Commands that require a device */
	obd = class_name2obd(lustre_cfg_string(lcfg, 0));
	if (!obd) {
		if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
			CERROR("this lcfg command requires a device name\n");
		else
			CERROR("no device for: %s\n",
			       lustre_cfg_string(lcfg, 0));

		err = -EINVAL;
		goto out;
	}

	switch (lcfg->lcfg_command) {
	case LCFG_SETUP: {
		err = class_setup(obd, lcfg);
		goto out;
	}
	case LCFG_DETACH: {
		err = class_detach(obd, lcfg);
		err = 0;
		goto out;
	}
	case LCFG_CLEANUP: {
		err = class_cleanup(obd, lcfg);
		err = 0;
		goto out;
	}
	case LCFG_ADD_CONN: {
		err = class_add_conn(obd, lcfg);
		err = 0;
		goto out;
	}
	case LCFG_DEL_CONN: {
		err = class_del_conn(obd, lcfg);
		err = 0;
		goto out;
	}
	case LCFG_POOL_NEW: {
		err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
		err = 0;
		goto out;
	}
	case LCFG_POOL_ADD: {
		err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
				   lustre_cfg_string(lcfg, 3));
		err = 0;
		goto out;
	}
	case LCFG_POOL_REM: {
		err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
				   lustre_cfg_string(lcfg, 3));
		err = 0;
		goto out;
	}
	case LCFG_POOL_DEL: {
		err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
		err = 0;
		goto out;
	}
	default: {
		err = obd_process_config(obd, sizeof(*lcfg), lcfg);
		goto out;
	}
	}
out:
	if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
		CWARN("Ignoring error %d on optional command %#x\n", err,
		      lcfg->lcfg_command);
		err = 0;
	}
	return err;
}
EXPORT_SYMBOL(class_process_config);

int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
			     struct lustre_cfg *lcfg, void *data)
{
	struct lprocfs_vars *var;
	struct file fakefile;
	struct seq_file fake_seqfile;
	char *key, *sval;
	int i, keylen, vallen;
	int matched = 0, j = 0;
	int rc = 0;
	int skip = 0;

	if (lcfg->lcfg_command != LCFG_PARAM) {
		CERROR("Unknown command: %d\n", lcfg->lcfg_command);
		return -EINVAL;
	}

	/* fake a seq file so that var->fops->write can work... */
	fakefile.private_data = &fake_seqfile;
	fake_seqfile.private = data;
	/* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
	 * or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
	 * or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36
	 */
	for (i = 1; i < lcfg->lcfg_bufcount; i++) {
		key = lustre_cfg_buf(lcfg, i);
		/* Strip off prefix */
		if (class_match_param(key, prefix, &key)) {
			/*
			 * If the prefix doesn't match, return error so we
			 * can pass it down the stack
			 */
			return -ENOSYS;
		}
		sval = strchr(key, '=');
		if (!sval || (*(sval + 1) == 0)) {
			CERROR("Can't parse param %s (missing '=')\n", key);
			/* rc = -EINVAL;	continue parsing other params */
			continue;
		}
		keylen = sval - key;
		sval++;
		vallen = strlen(sval);
		matched = 0;
		j = 0;
		/* Search proc entries */
		while (lvars[j].name) {
			var = &lvars[j];
			if (!class_match_param(key, var->name, NULL) &&
			    keylen == strlen(var->name)) {
				matched++;
				rc = -EROFS;
				if (var->fops && var->fops->write) {
					mm_segment_t oldfs;

					oldfs = get_fs();
					set_fs(KERNEL_DS);
					rc = (var->fops->write)(&fakefile, sval,
								vallen, NULL);
					set_fs(oldfs);
				}
				break;
			}
			j++;
		}
		if (!matched) {
			CERROR("%.*s: %s unknown param %s\n",
			       (int)strlen(prefix) - 1, prefix,
			       (char *)lustre_cfg_string(lcfg, 0), key);
			/* rc = -EINVAL;	continue parsing other params */
			skip++;
		} else if (rc < 0) {
			CERROR("%s: error writing proc entry '%s': rc = %d\n",
			       prefix, var->name, rc);
			rc = 0;
		} else {
			CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
			       lustre_cfg_string(lcfg, 0),
			       (int)strlen(prefix) - 1, prefix,
			       (int)(sval - key - 1), key, sval);
		}
	}

	if (rc > 0)
		rc = 0;
	if (!rc && skip)
		rc = skip;
	return rc;
}
EXPORT_SYMBOL(class_process_proc_param);

extern int lustre_check_exclusion(struct super_block *sb, char *svname);

/** Parse a configuration llog, doing various manipulations on them
 * for various reasons, (modifications for compatibility, skip obsolete
 * records, change uuids, etc), then class_process_config() resulting
 * net records.
 */
int class_config_llog_handler(const struct lu_env *env,
			      struct llog_handle *handle,
			      struct llog_rec_hdr *rec, void *data)
{
	struct config_llog_instance *clli = data;
	int cfg_len = rec->lrh_len;
	char *cfg_buf = (char *)(rec + 1);
	int rc = 0;

	switch (rec->lrh_type) {
	case OBD_CFG_REC: {
		struct lustre_cfg *lcfg, *lcfg_new;
		struct lustre_cfg_bufs bufs;
		char *inst_name = NULL;
		int inst_len = 0;
		int inst = 0, swab = 0;

		lcfg = (struct lustre_cfg *)cfg_buf;
		if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
			lustre_swab_lustre_cfg(lcfg);
			swab = 1;
		}

		rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
		if (rc)
			goto out;

		/* Figure out config state info */
		if (lcfg->lcfg_command == LCFG_MARKER) {
			struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);

			lustre_swab_cfg_marker(marker, swab,
					       LUSTRE_CFG_BUFLEN(lcfg, 1));
			CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
			       clli->cfg_flags, marker->cm_flags);
			if (marker->cm_flags & CM_START) {
				/* all previous flags off */
				clli->cfg_flags = CFG_F_MARKER;
				if (marker->cm_flags & CM_SKIP) {
					clli->cfg_flags |= CFG_F_SKIP;
					CDEBUG(D_CONFIG, "SKIP #%d\n",
					       marker->cm_step);
				} else if ((marker->cm_flags & CM_EXCLUDE) ||
					   (clli->cfg_sb &&
					    lustre_check_exclusion(clli->cfg_sb,
							 marker->cm_tgtname))) {
					clli->cfg_flags |= CFG_F_EXCLUDE;
					CDEBUG(D_CONFIG, "EXCLUDE %d\n",
					       marker->cm_step);
				}
			} else if (marker->cm_flags & CM_END) {
				clli->cfg_flags = 0;
			}
		}
		/* A config command without a start marker before it is
		 * illegal (post 146)
		 */
		if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
		    !(clli->cfg_flags & CFG_F_MARKER) &&
		    (lcfg->lcfg_command != LCFG_MARKER)) {
			CWARN("Config not inside markers, ignoring! (inst: %p, uuid: %s, flags: %#x)\n",
			      clli->cfg_instance,
			      clli->cfg_uuid.uuid, clli->cfg_flags);
			clli->cfg_flags |= CFG_F_SKIP;
		}
		if (clli->cfg_flags & CFG_F_SKIP) {
			CDEBUG(D_CONFIG, "skipping %#x\n",
			       clli->cfg_flags);
			rc = 0;
			/* No processing! */
			break;
		}

		/*
		 * For interoperability between 1.8 and 2.0,
		 * rename "mds" obd device type to "mdt".
		 */
		{
			char *typename = lustre_cfg_string(lcfg, 1);
			char *index = lustre_cfg_string(lcfg, 2);

			if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
			     strcmp(typename, "mds") == 0)) {
				CWARN("For 1.8 interoperability, rename obd type from mds to mdt\n");
				typename[2] = 't';
			}
			if ((lcfg->lcfg_command == LCFG_SETUP && index &&
			     strcmp(index, "type") == 0)) {
				CDEBUG(D_INFO, "For 1.8 interoperability, set this index to '0'\n");
				index[0] = '0';
				index[1] = 0;
			}
		}

		if (clli->cfg_flags & CFG_F_EXCLUDE) {
			CDEBUG(D_CONFIG, "cmd: %x marked EXCLUDED\n",
			       lcfg->lcfg_command);
			if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD)
				/* Add inactive instead */
				lcfg->lcfg_command = LCFG_LOV_ADD_INA;
		}

		lustre_cfg_bufs_init(&bufs, lcfg);

		if (clli && clli->cfg_instance &&
		    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
			inst = 1;
			inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
				   sizeof(clli->cfg_instance) * 2 + 4;
			inst_name = kasprintf(GFP_NOFS, "%s-%p",
					      lustre_cfg_string(lcfg, 0),
					      clli->cfg_instance);
			if (!inst_name) {
				rc = -ENOMEM;
				goto out;
			}
			lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
			CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
			       lcfg->lcfg_command, inst_name);
		}

		/* we override the llog's uuid for clients, to insure they
		 * are unique
		 */
		if (clli && clli->cfg_instance &&
		    lcfg->lcfg_command == LCFG_ATTACH) {
			lustre_cfg_bufs_set_string(&bufs, 2,
						   clli->cfg_uuid.uuid);
		}
		/*
		 * sptlrpc config record, we expect 2 data segments:
		 *  [0]: fs_name/target_name,
		 *  [1]: rule string
		 * moving them to index [1] and [2], and insert MGC's
		 * obdname at index [0].
		 */
		if (clli && !clli->cfg_instance &&
		    lcfg->lcfg_command == LCFG_SPTLRPC_CONF) {
			lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1],
					    bufs.lcfg_buflen[1]);
			lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0],
					    bufs.lcfg_buflen[0]);
			lustre_cfg_bufs_set_string(&bufs, 0,
						   clli->cfg_obdname);
		}

		lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);

		lcfg_new->lcfg_num   = lcfg->lcfg_num;
		lcfg_new->lcfg_flags = lcfg->lcfg_flags;

		/* XXX Hack to try to remain binary compatible with
		 * pre-newconfig logs
		 */
		if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
		    (lcfg->lcfg_nid >> 32) == 0) {
			__u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);

			lcfg_new->lcfg_nid =
				LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
			CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
			      lcfg->lcfg_nal, addr,
			      libcfs_nid2str(lcfg_new->lcfg_nid));
		} else {
			lcfg_new->lcfg_nid = lcfg->lcfg_nid;
		}

		lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */

		rc = class_process_config(lcfg_new);
		lustre_cfg_free(lcfg_new);

		if (inst)
			kfree(inst_name);
		break;
	}
	default:
		CERROR("Unknown llog record type %#x encountered\n",
		       rec->lrh_type);
		break;
	}
out:
	if (rc) {
		CERROR("%s: cfg command failed: rc = %d\n",
		       handle->lgh_ctxt->loc_obd->obd_name, rc);
		class_config_dump_handler(NULL, handle, rec, data);
	}
	return rc;
}
EXPORT_SYMBOL(class_config_llog_handler);

int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
			    char *name, struct config_llog_instance *cfg)
{
	struct llog_process_cat_data	 cd = {0, 0};
	struct llog_handle		*llh;
	llog_cb_t			 callback;
	int				 rc;

	CDEBUG(D_INFO, "looking up llog %s\n", name);
	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
	if (rc)
		return rc;

	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
	if (rc)
		goto parse_out;

	/* continue processing from where we last stopped to end-of-log */
	if (cfg) {
		cd.lpcd_first_idx = cfg->cfg_last_idx;
		callback = cfg->cfg_callback;
		LASSERT(callback);
	} else {
		callback = class_config_llog_handler;
	}

	cd.lpcd_last_idx = 0;

	rc = llog_process(env, llh, callback, cfg, &cd);

	CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
	       cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
	if (cfg)
		cfg->cfg_last_idx = cd.lpcd_last_idx;

parse_out:
	llog_close(env, llh);
	return rc;
}
EXPORT_SYMBOL(class_config_parse_llog);

/**
 * parse config record and output dump in supplied buffer.
 * This is separated from class_config_dump_handler() to use
 * for ioctl needs as well
 */
static int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf,
				  int size)
{
	struct lustre_cfg	*lcfg = (struct lustre_cfg *)(rec + 1);
	char			*ptr = buf;
	char			*end = buf + size;
	int			 rc = 0;

	LASSERT(rec->lrh_type == OBD_CFG_REC);
	rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
	if (rc < 0)
		return rc;

	ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
	if (lcfg->lcfg_flags)
		ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
				lcfg->lcfg_flags);

	if (lcfg->lcfg_num)
		ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);

	if (lcfg->lcfg_nid) {
		char nidstr[LNET_NIDSTR_SIZE];

		libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr));
		ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n     ",
				nidstr, lcfg->lcfg_nid);
	}

	if (lcfg->lcfg_command == LCFG_MARKER) {
		struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);

		ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
				marker->cm_step, marker->cm_flags,
				marker->cm_tgtname, marker->cm_comment);
	} else {
		int i;

		for (i = 0; i <  lcfg->lcfg_bufcount; i++) {
			ptr += snprintf(ptr, end-ptr, "%d:%s  ", i,
					lustre_cfg_string(lcfg, i));
		}
	}
	ptr += snprintf(ptr, end - ptr, "\n");
	/* return consumed bytes */
	rc = ptr - buf;
	return rc;
}

int class_config_dump_handler(const struct lu_env *env,
			      struct llog_handle *handle,
			      struct llog_rec_hdr *rec, void *data)
{
	char	*outstr;
	int	 rc = 0;

	outstr = kzalloc(256, GFP_NOFS);
	if (!outstr)
		return -ENOMEM;

	if (rec->lrh_type == OBD_CFG_REC) {
		class_config_parse_rec(rec, outstr, 256);
		LCONSOLE(D_WARNING, "   %s", outstr);
	} else {
		LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
		rc = -EINVAL;
	}

	kfree(outstr);
	return rc;
}

/** Call class_cleanup and class_detach.
 * "Manual" only in the sense that we're faking lcfg commands.
 */
int class_manual_cleanup(struct obd_device *obd)
{
	char		    flags[3] = "";
	struct lustre_cfg      *lcfg;
	struct lustre_cfg_bufs  bufs;
	int		     rc;

	if (!obd) {
		CERROR("empty cleanup\n");
		return -EALREADY;
	}

	if (obd->obd_force)
		strcat(flags, "F");
	if (obd->obd_fail)
		strcat(flags, "A");

	CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
	       obd->obd_name, flags);

	lustre_cfg_bufs_reset(&bufs, obd->obd_name);
	lustre_cfg_bufs_set_string(&bufs, 1, flags);
	lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
	if (!lcfg)
		return -ENOMEM;

	rc = class_process_config(lcfg);
	if (rc) {
		CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
		goto out;
	}

	/* the lcfg is almost the same for both ops */
	lcfg->lcfg_command = LCFG_DETACH;
	rc = class_process_config(lcfg);
	if (rc)
		CERROR("detach failed %d: %s\n", rc, obd->obd_name);
out:
	lustre_cfg_free(lcfg);
	return rc;
}
EXPORT_SYMBOL(class_manual_cleanup);

/*
 * uuid<->export lustre hash operations
 */

static unsigned
uuid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
{
	return cfs_hash_djb2_hash(((struct obd_uuid *)key)->uuid,
				  sizeof(((struct obd_uuid *)key)->uuid), mask);
}

static void *
uuid_key(struct hlist_node *hnode)
{
	struct obd_export *exp;

	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);

	return &exp->exp_client_uuid;
}

/*
 * NOTE: It is impossible to find an export that is in failed
 *       state with this function
 */
static int
uuid_keycmp(const void *key, struct hlist_node *hnode)
{
	struct obd_export *exp;

	LASSERT(key);
	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);

	return obd_uuid_equals(key, &exp->exp_client_uuid) &&
	       !exp->exp_failed;
}

static void *
uuid_export_object(struct hlist_node *hnode)
{
	return hlist_entry(hnode, struct obd_export, exp_uuid_hash);
}

static void
uuid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
{
	struct obd_export *exp;

	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
	class_export_get(exp);
}

static void
uuid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
{
	struct obd_export *exp;

	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
	class_export_put(exp);
}

static struct cfs_hash_ops uuid_hash_ops = {
	.hs_hash	= uuid_hash,
	.hs_key		= uuid_key,
	.hs_keycmp      = uuid_keycmp,
	.hs_object      = uuid_export_object,
	.hs_get		= uuid_export_get,
	.hs_put_locked  = uuid_export_put_locked,
};
