/*
 * 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) 2010, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

/**
 * This file deals with various client/target related logic including recovery.
 *
 * TODO: This code more logically belongs in the ptlrpc module than in ldlm and
 * should be moved.
 */

#define DEBUG_SUBSYSTEM S_LDLM

#include "../../include/linux/libcfs/libcfs.h"
#include "../include/obd.h"
#include "../include/obd_class.h"
#include "../include/lustre_dlm.h"
#include "../include/lustre_net.h"
#include "../include/lustre_sec.h"
#include "ldlm_internal.h"

/* @priority: If non-zero, move the selected connection to the list head.
 * @create: If zero, only search in existing connections.
 */
static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
			   int priority, int create)
{
	struct ptlrpc_connection *ptlrpc_conn;
	struct obd_import_conn *imp_conn = NULL, *item;
	int rc = 0;

	if (!create && !priority) {
		CDEBUG(D_HA, "Nothing to do\n");
		return -EINVAL;
	}

	ptlrpc_conn = ptlrpc_uuid_to_connection(uuid);
	if (!ptlrpc_conn) {
		CDEBUG(D_HA, "can't find connection %s\n", uuid->uuid);
		return -ENOENT;
	}

	if (create) {
		OBD_ALLOC(imp_conn, sizeof(*imp_conn));
		if (!imp_conn) {
			rc = -ENOMEM;
			goto out_put;
		}
	}

	spin_lock(&imp->imp_lock);
	list_for_each_entry(item, &imp->imp_conn_list, oic_item) {
		if (obd_uuid_equals(uuid, &item->oic_uuid)) {
			if (priority) {
				list_del(&item->oic_item);
				list_add(&item->oic_item,
					     &imp->imp_conn_list);
				item->oic_last_attempt = 0;
			}
			CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",
			       imp, imp->imp_obd->obd_name, uuid->uuid,
			       (priority ? ", moved to head" : ""));
			spin_unlock(&imp->imp_lock);
			rc = 0;
			goto out_free;
		}
	}
	/* No existing import connection found for \a uuid. */
	if (create) {
		imp_conn->oic_conn = ptlrpc_conn;
		imp_conn->oic_uuid = *uuid;
		imp_conn->oic_last_attempt = 0;
		if (priority)
			list_add(&imp_conn->oic_item, &imp->imp_conn_list);
		else
			list_add_tail(&imp_conn->oic_item,
					  &imp->imp_conn_list);
		CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",
		       imp, imp->imp_obd->obd_name, uuid->uuid,
		       (priority ? "head" : "tail"));
	} else {
		spin_unlock(&imp->imp_lock);
		rc = -ENOENT;
		goto out_free;
	}

	spin_unlock(&imp->imp_lock);
	return 0;
out_free:
	if (imp_conn)
		OBD_FREE(imp_conn, sizeof(*imp_conn));
out_put:
	ptlrpc_connection_put(ptlrpc_conn);
	return rc;
}

int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid)
{
	return import_set_conn(imp, uuid, 1, 0);
}

int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
			   int priority)
{
	return import_set_conn(imp, uuid, priority, 1);
}
EXPORT_SYMBOL(client_import_add_conn);

int client_import_del_conn(struct obd_import *imp, struct obd_uuid *uuid)
{
	struct obd_import_conn *imp_conn;
	struct obd_export *dlmexp;
	int rc = -ENOENT;

	spin_lock(&imp->imp_lock);
	if (list_empty(&imp->imp_conn_list)) {
		LASSERT(!imp->imp_connection);
		goto out;
	}

	list_for_each_entry(imp_conn, &imp->imp_conn_list, oic_item) {
		if (!obd_uuid_equals(uuid, &imp_conn->oic_uuid))
			continue;
		LASSERT(imp_conn->oic_conn);

		if (imp_conn == imp->imp_conn_current) {
			LASSERT(imp_conn->oic_conn == imp->imp_connection);

			if (imp->imp_state != LUSTRE_IMP_CLOSED &&
			    imp->imp_state != LUSTRE_IMP_DISCON) {
				CERROR("can't remove current connection\n");
				rc = -EBUSY;
				goto out;
			}

			ptlrpc_connection_put(imp->imp_connection);
			imp->imp_connection = NULL;

			dlmexp = class_conn2export(&imp->imp_dlm_handle);
			if (dlmexp && dlmexp->exp_connection) {
				LASSERT(dlmexp->exp_connection ==
					imp_conn->oic_conn);
				ptlrpc_connection_put(dlmexp->exp_connection);
				dlmexp->exp_connection = NULL;
			}
		}

		list_del(&imp_conn->oic_item);
		ptlrpc_connection_put(imp_conn->oic_conn);
		OBD_FREE(imp_conn, sizeof(*imp_conn));
		CDEBUG(D_HA, "imp %p@%s: remove connection %s\n",
		       imp, imp->imp_obd->obd_name, uuid->uuid);
		rc = 0;
		break;
	}
out:
	spin_unlock(&imp->imp_lock);
	if (rc == -ENOENT)
		CERROR("connection %s not found\n", uuid->uuid);
	return rc;
}
EXPORT_SYMBOL(client_import_del_conn);

/**
 * Find conn UUID by peer NID. \a peer is a server NID. This function is used
 * to find a conn uuid of \a imp which can reach \a peer.
 */
int client_import_find_conn(struct obd_import *imp, lnet_nid_t peer,
			    struct obd_uuid *uuid)
{
	struct obd_import_conn *conn;
	int rc = -ENOENT;

	spin_lock(&imp->imp_lock);
	list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
		/* Check if conn UUID does have this peer NID. */
		if (class_check_uuid(&conn->oic_uuid, peer)) {
			*uuid = conn->oic_uuid;
			rc = 0;
			break;
		}
	}
	spin_unlock(&imp->imp_lock);
	return rc;
}
EXPORT_SYMBOL(client_import_find_conn);

void client_destroy_import(struct obd_import *imp)
{
	/* Drop security policy instance after all RPCs have finished/aborted
	 * to let all busy contexts be released. */
	class_import_get(imp);
	class_destroy_import(imp);
	sptlrpc_import_sec_put(imp);
	class_import_put(imp);
}
EXPORT_SYMBOL(client_destroy_import);

/**
 * Check whether or not the OSC is on MDT.
 * In the config log,
 * osc on MDT
 *	setup 0:{fsname}-OSTxxxx-osc[-MDTxxxx] 1:lustre-OST0000_UUID 2:NID
 * osc on client
 *	setup 0:{fsname}-OSTxxxx-osc 1:lustre-OST0000_UUID 2:NID
 *
 **/
static int osc_on_mdt(char *obdname)
{
	char *ptr;

	ptr = strrchr(obdname, '-');
	if (ptr == NULL)
		return 0;

	if (strncmp(ptr + 1, "MDT", 3) == 0)
		return 1;

	return 0;
}

/* Configure an RPC client OBD device.
 *
 * lcfg parameters:
 * 1 - client UUID
 * 2 - server UUID
 * 3 - inactive-on-startup
 */
int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
{
	struct client_obd *cli = &obddev->u.cli;
	struct obd_import *imp;
	struct obd_uuid server_uuid;
	int rq_portal, rp_portal, connect_op;
	char *name = obddev->obd_type->typ_name;
	ldlm_ns_type_t ns_type = LDLM_NS_TYPE_UNKNOWN;
	int rc;

	/* In a more perfect world, we would hang a ptlrpc_client off of
	 * obd_type and just use the values from there. */
	if (!strcmp(name, LUSTRE_OSC_NAME)) {
		rq_portal = OST_REQUEST_PORTAL;
		rp_portal = OSC_REPLY_PORTAL;
		connect_op = OST_CONNECT;
		cli->cl_sp_me = LUSTRE_SP_CLI;
		cli->cl_sp_to = LUSTRE_SP_OST;
		ns_type = LDLM_NS_TYPE_OSC;
	} else if (!strcmp(name, LUSTRE_MDC_NAME) ||
		   !strcmp(name, LUSTRE_LWP_NAME)) {
		rq_portal = MDS_REQUEST_PORTAL;
		rp_portal = MDC_REPLY_PORTAL;
		connect_op = MDS_CONNECT;
		cli->cl_sp_me = LUSTRE_SP_CLI;
		cli->cl_sp_to = LUSTRE_SP_MDT;
		ns_type = LDLM_NS_TYPE_MDC;
	} else if (!strcmp(name, LUSTRE_OSP_NAME)) {
		if (strstr(lustre_cfg_buf(lcfg, 1), "OST") == NULL) {
			/* OSP_on_MDT for other MDTs */
			connect_op = MDS_CONNECT;
			cli->cl_sp_to = LUSTRE_SP_MDT;
			ns_type = LDLM_NS_TYPE_MDC;
			rq_portal = OUT_PORTAL;
		} else {
			/* OSP on MDT for OST */
			connect_op = OST_CONNECT;
			cli->cl_sp_to = LUSTRE_SP_OST;
			ns_type = LDLM_NS_TYPE_OSC;
			rq_portal = OST_REQUEST_PORTAL;
		}
		rp_portal = OSC_REPLY_PORTAL;
		cli->cl_sp_me = LUSTRE_SP_CLI;
	} else if (!strcmp(name, LUSTRE_MGC_NAME)) {
		rq_portal = MGS_REQUEST_PORTAL;
		rp_portal = MGC_REPLY_PORTAL;
		connect_op = MGS_CONNECT;
		cli->cl_sp_me = LUSTRE_SP_MGC;
		cli->cl_sp_to = LUSTRE_SP_MGS;
		cli->cl_flvr_mgc.sf_rpc = SPTLRPC_FLVR_INVALID;
		ns_type = LDLM_NS_TYPE_MGC;
	} else {
		CERROR("unknown client OBD type \"%s\", can't setup\n",
		       name);
		return -EINVAL;
	}

	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
		CERROR("requires a TARGET UUID\n");
		return -EINVAL;
	}

	if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {
		CERROR("client UUID must be less than 38 characters\n");
		return -EINVAL;
	}

	if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
		CERROR("setup requires a SERVER UUID\n");
		return -EINVAL;
	}

	if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {
		CERROR("target UUID must be less than 38 characters\n");
		return -EINVAL;
	}

	init_rwsem(&cli->cl_sem);
	mutex_init(&cli->cl_mgc_mutex);
	cli->cl_conn_count = 0;
	memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
	       min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
		     sizeof(server_uuid)));

	cli->cl_dirty = 0;
	cli->cl_avail_grant = 0;
	/* FIXME: Should limit this for the sum of all cl_dirty_max. */
	cli->cl_dirty_max = OSC_MAX_DIRTY_DEFAULT * 1024 * 1024;
	if (cli->cl_dirty_max >> PAGE_CACHE_SHIFT > totalram_pages / 8)
		cli->cl_dirty_max = totalram_pages << (PAGE_CACHE_SHIFT - 3);
	INIT_LIST_HEAD(&cli->cl_cache_waiters);
	INIT_LIST_HEAD(&cli->cl_loi_ready_list);
	INIT_LIST_HEAD(&cli->cl_loi_hp_ready_list);
	INIT_LIST_HEAD(&cli->cl_loi_write_list);
	INIT_LIST_HEAD(&cli->cl_loi_read_list);
	client_obd_list_lock_init(&cli->cl_loi_list_lock);
	atomic_set(&cli->cl_pending_w_pages, 0);
	atomic_set(&cli->cl_pending_r_pages, 0);
	cli->cl_r_in_flight = 0;
	cli->cl_w_in_flight = 0;

	spin_lock_init(&cli->cl_read_rpc_hist.oh_lock);
	spin_lock_init(&cli->cl_write_rpc_hist.oh_lock);
	spin_lock_init(&cli->cl_read_page_hist.oh_lock);
	spin_lock_init(&cli->cl_write_page_hist.oh_lock);
	spin_lock_init(&cli->cl_read_offset_hist.oh_lock);
	spin_lock_init(&cli->cl_write_offset_hist.oh_lock);

	/* lru for osc. */
	INIT_LIST_HEAD(&cli->cl_lru_osc);
	atomic_set(&cli->cl_lru_shrinkers, 0);
	atomic_set(&cli->cl_lru_busy, 0);
	atomic_set(&cli->cl_lru_in_list, 0);
	INIT_LIST_HEAD(&cli->cl_lru_list);
	client_obd_list_lock_init(&cli->cl_lru_list_lock);

	init_waitqueue_head(&cli->cl_destroy_waitq);
	atomic_set(&cli->cl_destroy_in_flight, 0);
	/* Turn on checksumming by default. */
	cli->cl_checksum = 1;
	/*
	 * The supported checksum types will be worked out at connect time
	 * Set cl_chksum* to CRC32 for now to avoid returning screwed info
	 * through procfs.
	 */
	cli->cl_cksum_type = cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;
	atomic_set(&cli->cl_resends, OSC_DEFAULT_RESENDS);

	/* This value may be reduced at connect time in
	 * ptlrpc_connect_interpret() . We initialize it to only
	 * 1MB until we know what the performance looks like.
	 * In the future this should likely be increased. LU-1431 */
	cli->cl_max_pages_per_rpc = min_t(int, PTLRPC_MAX_BRW_PAGES,
					  LNET_MTU >> PAGE_CACHE_SHIFT);

	if (!strcmp(name, LUSTRE_MDC_NAME)) {
		cli->cl_max_rpcs_in_flight = MDC_MAX_RIF_DEFAULT;
	} else if (totalram_pages >> (20 - PAGE_CACHE_SHIFT) <= 128 /* MB */) {
		cli->cl_max_rpcs_in_flight = 2;
	} else if (totalram_pages >> (20 - PAGE_CACHE_SHIFT) <= 256 /* MB */) {
		cli->cl_max_rpcs_in_flight = 3;
	} else if (totalram_pages >> (20 - PAGE_CACHE_SHIFT) <= 512 /* MB */) {
		cli->cl_max_rpcs_in_flight = 4;
	} else {
		if (osc_on_mdt(obddev->obd_name))
			cli->cl_max_rpcs_in_flight = MDS_OSC_MAX_RIF_DEFAULT;
		else
			cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT;
	}
	rc = ldlm_get_ref();
	if (rc) {
		CERROR("ldlm_get_ref failed: %d\n", rc);
		goto err;
	}

	ptlrpc_init_client(rq_portal, rp_portal, name,
			   &obddev->obd_ldlm_client);

	imp = class_new_import(obddev);
	if (imp == NULL) {
		rc = -ENOENT;
		goto err_ldlm;
	}
	imp->imp_client = &obddev->obd_ldlm_client;
	imp->imp_connect_op = connect_op;
	memcpy(cli->cl_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),
	       LUSTRE_CFG_BUFLEN(lcfg, 1));
	class_import_put(imp);

	rc = client_import_add_conn(imp, &server_uuid, 1);
	if (rc) {
		CERROR("can't add initial connection\n");
		goto err_import;
	}

	cli->cl_import = imp;
	/* cli->cl_max_mds_{easize,cookiesize} updated by mdc_init_ea_size() */
	cli->cl_max_mds_easize = sizeof(struct lov_mds_md_v3);
	cli->cl_max_mds_cookiesize = sizeof(struct llog_cookie);

	if (LUSTRE_CFG_BUFLEN(lcfg, 3) > 0) {
		if (!strcmp(lustre_cfg_string(lcfg, 3), "inactive")) {
			CDEBUG(D_HA, "marking %s %s->%s as inactive\n",
			       name, obddev->obd_name,
			       cli->cl_target_uuid.uuid);
			spin_lock(&imp->imp_lock);
			imp->imp_deactive = 1;
			spin_unlock(&imp->imp_lock);
		}
	}

	obddev->obd_namespace = ldlm_namespace_new(obddev, obddev->obd_name,
						   LDLM_NAMESPACE_CLIENT,
						   LDLM_NAMESPACE_GREEDY,
						   ns_type);
	if (obddev->obd_namespace == NULL) {
		CERROR("Unable to create client namespace - %s\n",
		       obddev->obd_name);
		rc = -ENOMEM;
		goto err_import;
	}

	cli->cl_qchk_stat = CL_NOT_QUOTACHECKED;

	return rc;

err_import:
	class_destroy_import(imp);
err_ldlm:
	ldlm_put_ref();
err:
	return rc;

}
EXPORT_SYMBOL(client_obd_setup);

int client_obd_cleanup(struct obd_device *obddev)
{
	ldlm_namespace_free_post(obddev->obd_namespace);
	obddev->obd_namespace = NULL;

	LASSERT(obddev->u.cli.cl_import == NULL);

	ldlm_put_ref();
	return 0;
}
EXPORT_SYMBOL(client_obd_cleanup);

/* ->o_connect() method for client side (OSC and MDC and MGC) */
int client_connect_import(const struct lu_env *env,
			  struct obd_export **exp,
			  struct obd_device *obd, struct obd_uuid *cluuid,
			  struct obd_connect_data *data, void *localdata)
{
	struct client_obd       *cli    = &obd->u.cli;
	struct obd_import       *imp    = cli->cl_import;
	struct obd_connect_data *ocd;
	struct lustre_handle    conn    = { 0 };
	int		     rc;

	*exp = NULL;
	down_write(&cli->cl_sem);
	if (cli->cl_conn_count > 0) {
		rc = -EALREADY;
		goto out_sem;
	}

	rc = class_connect(&conn, obd, cluuid);
	if (rc)
		goto out_sem;

	cli->cl_conn_count++;
	*exp = class_conn2export(&conn);

	LASSERT(obd->obd_namespace);

	imp->imp_dlm_handle = conn;
	rc = ptlrpc_init_import(imp);
	if (rc != 0)
		goto out_ldlm;

	ocd = &imp->imp_connect_data;
	if (data) {
		*ocd = *data;
		imp->imp_connect_flags_orig = data->ocd_connect_flags;
	}

	rc = ptlrpc_connect_import(imp);
	if (rc != 0) {
		LASSERT(imp->imp_state == LUSTRE_IMP_DISCON);
		goto out_ldlm;
	}
	LASSERT(*exp != NULL && (*exp)->exp_connection);

	if (data) {
		LASSERTF((ocd->ocd_connect_flags & data->ocd_connect_flags) ==
			 ocd->ocd_connect_flags, "old %#llx, new %#llx\n",
			 data->ocd_connect_flags, ocd->ocd_connect_flags);
		data->ocd_connect_flags = ocd->ocd_connect_flags;
	}

	ptlrpc_pinger_add_import(imp);

	if (rc) {
out_ldlm:
		cli->cl_conn_count--;
		class_disconnect(*exp);
		*exp = NULL;
	}
out_sem:
	up_write(&cli->cl_sem);

	return rc;
}
EXPORT_SYMBOL(client_connect_import);

int client_disconnect_export(struct obd_export *exp)
{
	struct obd_device *obd = class_exp2obd(exp);
	struct client_obd *cli;
	struct obd_import *imp;
	int rc = 0, err;

	if (!obd) {
		CERROR("invalid export for disconnect: exp %p cookie %#llx\n",
		       exp, exp ? exp->exp_handle.h_cookie : -1);
		return -EINVAL;
	}

	cli = &obd->u.cli;
	imp = cli->cl_import;

	down_write(&cli->cl_sem);
	CDEBUG(D_INFO, "disconnect %s - %d\n", obd->obd_name,
	       cli->cl_conn_count);

	if (!cli->cl_conn_count) {
		CERROR("disconnecting disconnected device (%s)\n",
		       obd->obd_name);
		rc = -EINVAL;
		goto out_disconnect;
	}

	cli->cl_conn_count--;
	if (cli->cl_conn_count) {
		rc = 0;
		goto out_disconnect;
	}

	/* Mark import deactivated now, so we don't try to reconnect if any
	 * of the cleanup RPCs fails (e.g. LDLM cancel, etc).  We don't
	 * fully deactivate the import, or that would drop all requests. */
	spin_lock(&imp->imp_lock);
	imp->imp_deactive = 1;
	spin_unlock(&imp->imp_lock);

	/* Some non-replayable imports (MDS's OSCs) are pinged, so just
	 * delete it regardless.  (It's safe to delete an import that was
	 * never added.) */
	(void)ptlrpc_pinger_del_import(imp);

	if (obd->obd_namespace != NULL) {
		/* obd_force == local only */
		ldlm_cli_cancel_unused(obd->obd_namespace, NULL,
				       obd->obd_force ? LCF_LOCAL : 0, NULL);
		ldlm_namespace_free_prior(obd->obd_namespace, imp,
					  obd->obd_force);
	}

	/* There's no need to hold sem while disconnecting an import,
	 * and it may actually cause deadlock in GSS. */
	up_write(&cli->cl_sem);
	rc = ptlrpc_disconnect_import(imp, 0);
	down_write(&cli->cl_sem);

	ptlrpc_invalidate_import(imp);

out_disconnect:
	/* Use server style - class_disconnect should be always called for
	 * o_disconnect. */
	err = class_disconnect(exp);
	if (!rc && err)
		rc = err;

	up_write(&cli->cl_sem);

	return rc;
}
EXPORT_SYMBOL(client_disconnect_export);


/**
 * Packs current SLV and Limit into \a req.
 */
int target_pack_pool_reply(struct ptlrpc_request *req)
{
	struct obd_device *obd;

	/* Check that we still have all structures alive as this may
	 * be some late RPC at shutdown time. */
	if (unlikely(!req->rq_export || !req->rq_export->exp_obd ||
		     !exp_connect_lru_resize(req->rq_export))) {
		lustre_msg_set_slv(req->rq_repmsg, 0);
		lustre_msg_set_limit(req->rq_repmsg, 0);
		return 0;
	}

	/* OBD is alive here as export is alive, which we checked above. */
	obd = req->rq_export->exp_obd;

	read_lock(&obd->obd_pool_lock);
	lustre_msg_set_slv(req->rq_repmsg, obd->obd_pool_slv);
	lustre_msg_set_limit(req->rq_repmsg, obd->obd_pool_limit);
	read_unlock(&obd->obd_pool_lock);

	return 0;
}
EXPORT_SYMBOL(target_pack_pool_reply);

int target_send_reply_msg(struct ptlrpc_request *req, int rc, int fail_id)
{
	if (OBD_FAIL_CHECK_ORSET(fail_id & ~OBD_FAIL_ONCE, OBD_FAIL_ONCE)) {
		DEBUG_REQ(D_ERROR, req, "dropping reply");
		return -ECOMM;
	}

	if (unlikely(rc)) {
		DEBUG_REQ(D_NET, req, "processing error (%d)", rc);
		req->rq_status = rc;
		return ptlrpc_send_error(req, 1);
	} else {
		DEBUG_REQ(D_NET, req, "sending reply");
	}

	return ptlrpc_send_reply(req, PTLRPC_REPLY_MAYBE_DIFFICULT);
}

void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
{
	struct ptlrpc_service_part *svcpt;
	int			netrc;
	struct ptlrpc_reply_state *rs;
	struct obd_export	 *exp;

	if (req->rq_no_reply)
		return;

	svcpt = req->rq_rqbd->rqbd_svcpt;
	rs = req->rq_reply_state;
	if (rs == NULL || !rs->rs_difficult) {
		/* no notifiers */
		target_send_reply_msg(req, rc, fail_id);
		return;
	}

	/* must be an export if locks saved */
	LASSERT(req->rq_export != NULL);
	/* req/reply consistent */
	LASSERT(rs->rs_svcpt == svcpt);

	/* "fresh" reply */
	LASSERT(!rs->rs_scheduled);
	LASSERT(!rs->rs_scheduled_ever);
	LASSERT(!rs->rs_handled);
	LASSERT(!rs->rs_on_net);
	LASSERT(rs->rs_export == NULL);
	LASSERT(list_empty(&rs->rs_obd_list));
	LASSERT(list_empty(&rs->rs_exp_list));

	exp = class_export_get(req->rq_export);

	/* disable reply scheduling while I'm setting up */
	rs->rs_scheduled = 1;
	rs->rs_on_net    = 1;
	rs->rs_xid       = req->rq_xid;
	rs->rs_transno   = req->rq_transno;
	rs->rs_export    = exp;
	rs->rs_opc       = lustre_msg_get_opc(req->rq_reqmsg);

	spin_lock(&exp->exp_uncommitted_replies_lock);
	CDEBUG(D_NET, "rs transno = %llu, last committed = %llu\n",
	       rs->rs_transno, exp->exp_last_committed);
	if (rs->rs_transno > exp->exp_last_committed) {
		/* not committed already */
		list_add_tail(&rs->rs_obd_list,
				  &exp->exp_uncommitted_replies);
	}
	spin_unlock(&exp->exp_uncommitted_replies_lock);

	spin_lock(&exp->exp_lock);
	list_add_tail(&rs->rs_exp_list, &exp->exp_outstanding_replies);
	spin_unlock(&exp->exp_lock);

	netrc = target_send_reply_msg(req, rc, fail_id);

	spin_lock(&svcpt->scp_rep_lock);

	atomic_inc(&svcpt->scp_nreps_difficult);

	if (netrc != 0) {
		/* error sending: reply is off the net.  Also we need +1
		 * reply ref until ptlrpc_handle_rs() is done
		 * with the reply state (if the send was successful, there
		 * would have been +1 ref for the net, which
		 * reply_out_callback leaves alone) */
		rs->rs_on_net = 0;
		ptlrpc_rs_addref(rs);
	}

	spin_lock(&rs->rs_lock);
	if (rs->rs_transno <= exp->exp_last_committed ||
	    (!rs->rs_on_net && !rs->rs_no_ack) ||
	    list_empty(&rs->rs_exp_list) ||     /* completed already */
	    list_empty(&rs->rs_obd_list)) {
		CDEBUG(D_HA, "Schedule reply immediately\n");
		ptlrpc_dispatch_difficult_reply(rs);
	} else {
		list_add(&rs->rs_list, &svcpt->scp_rep_active);
		rs->rs_scheduled = 0;	/* allow notifier to schedule */
	}
	spin_unlock(&rs->rs_lock);
	spin_unlock(&svcpt->scp_rep_lock);
}
EXPORT_SYMBOL(target_send_reply);

ldlm_mode_t lck_compat_array[] = {
	[LCK_EX]	= LCK_COMPAT_EX,
	[LCK_PW]	= LCK_COMPAT_PW,
	[LCK_PR]	= LCK_COMPAT_PR,
	[LCK_CW]	= LCK_COMPAT_CW,
	[LCK_CR]	= LCK_COMPAT_CR,
	[LCK_NL]	= LCK_COMPAT_NL,
	[LCK_GROUP]	= LCK_COMPAT_GROUP,
	[LCK_COS]	= LCK_COMPAT_COS,
};

/**
 * Rather arbitrary mapping from LDLM error codes to errno values. This should
 * not escape to the user level.
 */
int ldlm_error2errno(ldlm_error_t error)
{
	int result;

	switch (error) {
	case ELDLM_OK:
		result = 0;
		break;
	case ELDLM_LOCK_CHANGED:
		result = -ESTALE;
		break;
	case ELDLM_LOCK_ABORTED:
		result = -ENAVAIL;
		break;
	case ELDLM_LOCK_REPLACED:
		result = -ESRCH;
		break;
	case ELDLM_NO_LOCK_DATA:
		result = -ENOENT;
		break;
	case ELDLM_NAMESPACE_EXISTS:
		result = -EEXIST;
		break;
	case ELDLM_BAD_NAMESPACE:
		result = -EBADF;
		break;
	default:
		if (((int)error) < 0)  /* cast to signed type */
			result = error; /* as ldlm_error_t can be unsigned */
		else {
			CERROR("Invalid DLM result code: %d\n", error);
			result = -EPROTO;
		}
	}
	return result;
}
EXPORT_SYMBOL(ldlm_error2errno);

/**
 * Dual to ldlm_error2errno(): maps errno values back to ldlm_error_t.
 */
ldlm_error_t ldlm_errno2error(int err_no)
{
	int error;

	switch (err_no) {
	case 0:
		error = ELDLM_OK;
		break;
	case -ESTALE:
		error = ELDLM_LOCK_CHANGED;
		break;
	case -ENAVAIL:
		error = ELDLM_LOCK_ABORTED;
		break;
	case -ESRCH:
		error = ELDLM_LOCK_REPLACED;
		break;
	case -ENOENT:
		error = ELDLM_NO_LOCK_DATA;
		break;
	case -EEXIST:
		error = ELDLM_NAMESPACE_EXISTS;
		break;
	case -EBADF:
		error = ELDLM_BAD_NAMESPACE;
		break;
	default:
		error = err_no;
	}
	return error;
}
EXPORT_SYMBOL(ldlm_errno2error);

#if LUSTRE_TRACKS_LOCK_EXP_REFS
void ldlm_dump_export_locks(struct obd_export *exp)
{
	spin_lock(&exp->exp_locks_list_guard);
	if (!list_empty(&exp->exp_locks_list)) {
		struct ldlm_lock *lock;

		CERROR("dumping locks for export %p,ignore if the unmount doesn't hang\n",
		       exp);
		list_for_each_entry(lock, &exp->exp_locks_list,
					l_exp_refs_link)
			LDLM_ERROR(lock, "lock:");
	}
	spin_unlock(&exp->exp_locks_list_guard);
}
#endif
