/*
 * 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) 2002, 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.
 *
 * lustre/obdecho/echo.c
 *
 * Author: Peter Braam <braam@clusterfs.com>
 * Author: Andreas Dilger <adilger@clusterfs.com>
 */

#define DEBUG_SUBSYSTEM S_ECHO

#include <obd_support.h>
#include <obd_class.h>
#include <lustre_debug.h>
#include <lustre_dlm.h>
#include <lprocfs_status.h>

#include "echo_internal.h"

/* The echo objid needs to be below 2^32, because regular FID numbers are
 * limited to 2^32 objects in f_oid for the FID_SEQ_ECHO range. b=23335 */
#define ECHO_INIT_OID	0x10000000ULL
#define ECHO_HANDLE_MAGIC    0xabcd0123fedc9876ULL

#define ECHO_PERSISTENT_PAGES (ECHO_PERSISTENT_SIZE >> PAGE_CACHE_SHIFT)
static struct page *echo_persistent_pages[ECHO_PERSISTENT_PAGES];

enum {
	LPROC_ECHO_READ_BYTES = 1,
	LPROC_ECHO_WRITE_BYTES = 2,
	LPROC_ECHO_LAST = LPROC_ECHO_WRITE_BYTES +1
};

static int echo_connect(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 lustre_handle conn = { 0 };
	int rc;

	data->ocd_connect_flags &= ECHO_CONNECT_SUPPORTED;
	rc = class_connect(&conn, obd, cluuid);
	if (rc) {
		CERROR("can't connect %d\n", rc);
		return rc;
	}
	*exp = class_conn2export(&conn);

	return 0;
}

static int echo_disconnect(struct obd_export *exp)
{
	LASSERT (exp != NULL);

	return server_disconnect_export(exp);
}

static int echo_init_export(struct obd_export *exp)
{
	return ldlm_init_export(exp);
}

static int echo_destroy_export(struct obd_export *exp)
{
	target_destroy_export(exp);
	ldlm_destroy_export(exp);

	return 0;
}

 static __u64 echo_next_id(struct obd_device *obddev)
{
	obd_id id;

	spin_lock(&obddev->u.echo.eo_lock);
	id = ++obddev->u.echo.eo_lastino;
	spin_unlock(&obddev->u.echo.eo_lock);

	return id;
}

static int echo_create(const struct lu_env *env, struct obd_export *exp,
		       struct obdo *oa, struct lov_stripe_md **ea,
		       struct obd_trans_info *oti)
{
	struct obd_device *obd = class_exp2obd(exp);

	if (!obd) {
		CERROR("invalid client cookie "LPX64"\n",
		       exp->exp_handle.h_cookie);
		return -EINVAL;
	}

	if (!(oa->o_mode && S_IFMT)) {
		CERROR("echo obd: no type!\n");
		return -ENOENT;
	}

	if (!(oa->o_valid & OBD_MD_FLTYPE)) {
		CERROR("invalid o_valid "LPX64"\n", oa->o_valid);
		return -EINVAL;
	}

	ostid_set_seq_echo(&oa->o_oi);
	ostid_set_id(&oa->o_oi, echo_next_id(obd));
	oa->o_valid = OBD_MD_FLID;

	return 0;
}

static int echo_destroy(const struct lu_env *env, struct obd_export *exp,
			struct obdo *oa, struct lov_stripe_md *ea,
			struct obd_trans_info *oti, struct obd_export *md_exp,
			void *capa)
{
	struct obd_device *obd = class_exp2obd(exp);

	if (!obd) {
		CERROR("invalid client cookie "LPX64"\n",
		       exp->exp_handle.h_cookie);
		return -EINVAL;
	}

	if (!(oa->o_valid & OBD_MD_FLID)) {
		CERROR("obdo missing FLID valid flag: "LPX64"\n", oa->o_valid);
		return -EINVAL;
	}

	if (ostid_id(&oa->o_oi) > obd->u.echo.eo_lastino ||
	    ostid_id(&oa->o_oi) < ECHO_INIT_OID) {
		CERROR("bad destroy objid: "DOSTID"\n", POSTID(&oa->o_oi));
		return -EINVAL;
	}

	return 0;
}

static int echo_getattr(const struct lu_env *env, struct obd_export *exp,
			struct obd_info *oinfo)
{
	struct obd_device *obd = class_exp2obd(exp);
	obd_id id = ostid_id(&oinfo->oi_oa->o_oi);

	if (!obd) {
		CERROR("invalid client cookie "LPX64"\n",
		       exp->exp_handle.h_cookie);
		return -EINVAL;
	}

	if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {
		CERROR("obdo missing FLID valid flag: "LPX64"\n",
		       oinfo->oi_oa->o_valid);
		return -EINVAL;
	}

	obdo_cpy_md(oinfo->oi_oa, &obd->u.echo.eo_oa, oinfo->oi_oa->o_valid);
	ostid_set_seq_echo(&oinfo->oi_oa->o_oi);
	ostid_set_id(&oinfo->oi_oa->o_oi, id);

	return 0;
}

static int echo_setattr(const struct lu_env *env, struct obd_export *exp,
			struct obd_info *oinfo, struct obd_trans_info *oti)
{
	struct obd_device *obd = class_exp2obd(exp);

	if (!obd) {
		CERROR("invalid client cookie "LPX64"\n",
		       exp->exp_handle.h_cookie);
		return -EINVAL;
	}

	if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {
		CERROR("obdo missing FLID valid flag: "LPX64"\n",
		       oinfo->oi_oa->o_valid);
		return -EINVAL;
	}

	memcpy(&obd->u.echo.eo_oa, oinfo->oi_oa, sizeof(*oinfo->oi_oa));

	if (ostid_id(&oinfo->oi_oa->o_oi) & 4) {
		/* Save lock to force ACKed reply */
		ldlm_lock_addref (&obd->u.echo.eo_nl_lock, LCK_NL);
		oti->oti_ack_locks[0].mode = LCK_NL;
		oti->oti_ack_locks[0].lock = obd->u.echo.eo_nl_lock;
	}

	return 0;
}

static void
echo_page_debug_setup(struct page *page, int rw, obd_id id,
		      __u64 offset, int len)
{
	int   page_offset = offset & ~CFS_PAGE_MASK;
	char *addr	= ((char *)kmap(page)) + page_offset;

	if (len % OBD_ECHO_BLOCK_SIZE != 0)
		CERROR("Unexpected block size %d\n", len);

	while (len > 0) {
		if (rw & OBD_BRW_READ)
			block_debug_setup(addr, OBD_ECHO_BLOCK_SIZE,
					  offset, id);
		else
			block_debug_setup(addr, OBD_ECHO_BLOCK_SIZE,
					  0xecc0ecc0ecc0ecc0ULL,
					  0xecc0ecc0ecc0ecc0ULL);

		addr   += OBD_ECHO_BLOCK_SIZE;
		offset += OBD_ECHO_BLOCK_SIZE;
		len    -= OBD_ECHO_BLOCK_SIZE;
	}

	kunmap(page);
}

static int
echo_page_debug_check(struct page *page, obd_id id,
		      __u64 offset, int len)
{
	int   page_offset = offset & ~CFS_PAGE_MASK;
	char *addr	= ((char *)kmap(page)) + page_offset;
	int   rc	  = 0;
	int   rc2;

	if (len % OBD_ECHO_BLOCK_SIZE != 0)
		CERROR("Unexpected block size %d\n", len);

	while (len > 0) {
		rc2 = block_debug_check("echo", addr, OBD_ECHO_BLOCK_SIZE,
					offset, id);

		if (rc2 != 0 && rc == 0)
			rc = rc2;

		addr   += OBD_ECHO_BLOCK_SIZE;
		offset += OBD_ECHO_BLOCK_SIZE;
		len    -= OBD_ECHO_BLOCK_SIZE;
	}

	kunmap(page);

	return (rc);
}

/* This allows us to verify that desc_private is passed unmolested */
#define DESC_PRIV 0x10293847

static int echo_map_nb_to_lb(struct obdo *oa, struct obd_ioobj *obj,
			     struct niobuf_remote *nb, int *pages,
			     struct niobuf_local *lb, int cmd, int *left)
{
	int gfp_mask = (ostid_id(&obj->ioo_oid) & 1) ?
			GFP_HIGHUSER : GFP_IOFS;
	int ispersistent = ostid_id(&obj->ioo_oid) == ECHO_PERSISTENT_OBJID;
	int debug_setup = (!ispersistent &&
			   (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
			   (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0);
	struct niobuf_local *res = lb;
	obd_off offset = nb->offset;
	int len = nb->len;

	while (len > 0) {
		int plen = PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1));
		if (len < plen)
			plen = len;

		/* check for local buf overflow */
		if (*left == 0)
			return -EINVAL;

		res->lnb_file_offset = offset;
		res->len = plen;
		LASSERT((res->lnb_file_offset & ~CFS_PAGE_MASK) + res->len <=
			PAGE_CACHE_SIZE);

		if (ispersistent &&
		    ((res->lnb_file_offset >> PAGE_CACHE_SHIFT) <
		      ECHO_PERSISTENT_PAGES)) {
			res->page =
				echo_persistent_pages[res->lnb_file_offset >>
						      PAGE_CACHE_SHIFT];
			/* Take extra ref so __free_pages() can be called OK */
			get_page (res->page);
		} else {
			OBD_PAGE_ALLOC(res->page, gfp_mask);
			if (res->page == NULL) {
				CERROR("can't get page for id " DOSTID"\n",
				       POSTID(&obj->ioo_oid));
				return -ENOMEM;
			}
		}

		CDEBUG(D_PAGE, "$$$$ get page %p @ "LPU64" for %d\n",
		       res->page, res->lnb_file_offset, res->len);

		if (cmd & OBD_BRW_READ)
			res->rc = res->len;

		if (debug_setup)
			echo_page_debug_setup(res->page, cmd,
					      ostid_id(&obj->ioo_oid),
					      res->lnb_file_offset, res->len);

		offset += plen;
		len -= plen;
		res++;

		(*left)--;
		(*pages)++;
	}

	return 0;
}

static int echo_finalize_lb(struct obdo *oa, struct obd_ioobj *obj,
			    struct niobuf_remote *rb, int *pgs,
			    struct niobuf_local *lb, int verify)
{
	struct niobuf_local *res = lb;
	obd_off start  = rb->offset >> PAGE_CACHE_SHIFT;
	obd_off end    = (rb->offset + rb->len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	int     count  = (int)(end - start);
	int     rc     = 0;
	int     i;

	for (i = 0; i < count; i++, (*pgs) ++, res++) {
		struct page *page = res->page;
		void       *addr;

		if (page == NULL) {
			CERROR("null page objid "LPU64":%p, buf %d/%d\n",
			       ostid_id(&obj->ioo_oid), page, i,
			       obj->ioo_bufcnt);
			return -EFAULT;
		}

		addr = kmap(page);

		CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@"LPU64"\n",
		       res->page, addr, res->lnb_file_offset);

		if (verify) {
			int vrc = echo_page_debug_check(page,
							ostid_id(&obj->ioo_oid),
							res->lnb_file_offset,
							res->len);
			/* check all the pages always */
			if (vrc != 0 && rc == 0)
				rc = vrc;
		}

		kunmap(page);
		/* NB see comment above regarding persistent pages */
		OBD_PAGE_FREE(page);
	}

	return rc;
}

static int echo_preprw(const struct lu_env *env, int cmd,
		       struct obd_export *export, struct obdo *oa,
		       int objcount, struct obd_ioobj *obj,
		       struct niobuf_remote *nb, int *pages,
		       struct niobuf_local *res, struct obd_trans_info *oti,
		       struct lustre_capa *unused)
{
	struct obd_device *obd;
	int tot_bytes = 0;
	int rc = 0;
	int i, left;

	obd = export->exp_obd;
	if (obd == NULL)
		return -EINVAL;

	/* Temp fix to stop falling foul of osc_announce_cached() */
	oa->o_valid &= ~(OBD_MD_FLBLOCKS | OBD_MD_FLGRANT);

	memset(res, 0, sizeof(*res) * *pages);

	CDEBUG(D_PAGE, "%s %d obdos with %d IOs\n",
	       cmd == OBD_BRW_READ ? "reading" : "writing", objcount, *pages);

	if (oti)
		oti->oti_handle = (void *)DESC_PRIV;

	left = *pages;
	*pages = 0;

	for (i = 0; i < objcount; i++, obj++) {
		int j;

		for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++) {

			rc = echo_map_nb_to_lb(oa, obj, nb, pages,
					       res + *pages, cmd, &left);
			if (rc)
				GOTO(preprw_cleanup, rc);

			tot_bytes += nb->len;
		}
	}

	atomic_add(*pages, &obd->u.echo.eo_prep);

	if (cmd & OBD_BRW_READ)
		lprocfs_counter_add(obd->obd_stats, LPROC_ECHO_READ_BYTES,
				    tot_bytes);
	else
		lprocfs_counter_add(obd->obd_stats, LPROC_ECHO_WRITE_BYTES,
				    tot_bytes);

	CDEBUG(D_PAGE, "%d pages allocated after prep\n",
	       atomic_read(&obd->u.echo.eo_prep));

	return 0;

preprw_cleanup:
	/* It is possible that we would rather handle errors by  allow
	 * any already-set-up pages to complete, rather than tearing them
	 * all down again.  I believe that this is what the in-kernel
	 * prep/commit operations do.
	 */
	CERROR("cleaning up %u pages (%d obdos)\n", *pages, objcount);
	for (i = 0; i < *pages; i++) {
		kunmap(res[i].page);
		/* NB if this is a persistent page, __free_pages will just
		 * lose the extra ref gained above */
		OBD_PAGE_FREE(res[i].page);
		res[i].page = NULL;
		atomic_dec(&obd->u.echo.eo_prep);
	}

	return rc;
}

static int echo_commitrw(const struct lu_env *env, int cmd,
			 struct obd_export *export, struct obdo *oa,
			 int objcount, struct obd_ioobj *obj,
			 struct niobuf_remote *rb, int niocount,
			 struct niobuf_local *res, struct obd_trans_info *oti,
			 int rc)
{
	struct obd_device *obd;
	int pgs = 0;
	int i;

	obd = export->exp_obd;
	if (obd == NULL)
		return -EINVAL;

	if (rc)
		GOTO(commitrw_cleanup, rc);

	if ((cmd & OBD_BRW_RWMASK) == OBD_BRW_READ) {
		CDEBUG(D_PAGE, "reading %d obdos with %d IOs\n",
		       objcount, niocount);
	} else {
		CDEBUG(D_PAGE, "writing %d obdos with %d IOs\n",
		       objcount, niocount);
	}

	if (niocount && res == NULL) {
		CERROR("NULL res niobuf with niocount %d\n", niocount);
		return -EINVAL;
	}

	LASSERT(oti == NULL || oti->oti_handle == (void *)DESC_PRIV);

	for (i = 0; i < objcount; i++, obj++) {
		int verify = (rc == 0 &&
			     ostid_id(&obj->ioo_oid) != ECHO_PERSISTENT_OBJID &&
			      (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
			      (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0);
		int j;

		for (j = 0 ; j < obj->ioo_bufcnt ; j++, rb++) {
			int vrc = echo_finalize_lb(oa, obj, rb, &pgs, &res[pgs],
						   verify);
			if (vrc == 0)
				continue;

			if (vrc == -EFAULT)
				GOTO(commitrw_cleanup, rc = vrc);

			if (rc == 0)
				rc = vrc;
		}

	}

	atomic_sub(pgs, &obd->u.echo.eo_prep);

	CDEBUG(D_PAGE, "%d pages remain after commit\n",
	       atomic_read(&obd->u.echo.eo_prep));
	return rc;

commitrw_cleanup:
	atomic_sub(pgs, &obd->u.echo.eo_prep);

	CERROR("cleaning up %d pages (%d obdos)\n",
	       niocount - pgs - 1, objcount);

	while (pgs < niocount) {
		struct page *page = res[pgs++].page;

		if (page == NULL)
			continue;

		/* NB see comment above regarding persistent pages */
		OBD_PAGE_FREE(page);
		atomic_dec(&obd->u.echo.eo_prep);
	}
	return rc;
}

static int echo_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
{
	struct lprocfs_static_vars lvars;
	int			rc;
	__u64		      lock_flags = 0;
	struct ldlm_res_id	 res_id = {.name = {1}};
	char		       ns_name[48];

	obd->u.echo.eo_obt.obt_magic = OBT_MAGIC;
	spin_lock_init(&obd->u.echo.eo_lock);
	obd->u.echo.eo_lastino = ECHO_INIT_OID;

	sprintf(ns_name, "echotgt-%s", obd->obd_uuid.uuid);
	obd->obd_namespace = ldlm_namespace_new(obd, ns_name,
						LDLM_NAMESPACE_SERVER,
						LDLM_NAMESPACE_MODEST,
						LDLM_NS_TYPE_OST);
	if (obd->obd_namespace == NULL) {
		LBUG();
		return -ENOMEM;
	}

	rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id, LDLM_PLAIN,
				    NULL, LCK_NL, &lock_flags, NULL,
				    ldlm_completion_ast, NULL, NULL, 0,
				    LVB_T_NONE, NULL, &obd->u.echo.eo_nl_lock);
	LASSERT (rc == ELDLM_OK);

	lprocfs_echo_init_vars(&lvars);
	if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0 &&
	    lprocfs_alloc_obd_stats(obd, LPROC_ECHO_LAST) == 0) {
		lprocfs_counter_init(obd->obd_stats, LPROC_ECHO_READ_BYTES,
				     LPROCFS_CNTR_AVGMINMAX,
				     "read_bytes", "bytes");
		lprocfs_counter_init(obd->obd_stats, LPROC_ECHO_WRITE_BYTES,
				     LPROCFS_CNTR_AVGMINMAX,
				     "write_bytes", "bytes");
	}

	ptlrpc_init_client (LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
			    "echo_ldlm_cb_client", &obd->obd_ldlm_client);
	return 0;
}

static int echo_cleanup(struct obd_device *obd)
{
	int leaked;

	lprocfs_obd_cleanup(obd);
	lprocfs_free_obd_stats(obd);

	ldlm_lock_decref(&obd->u.echo.eo_nl_lock, LCK_NL);

	/* XXX Bug 3413; wait for a bit to ensure the BL callback has
	 * happened before calling ldlm_namespace_free() */
	schedule_timeout_and_set_state(TASK_UNINTERRUPTIBLE, cfs_time_seconds(1));

	ldlm_namespace_free(obd->obd_namespace, NULL, obd->obd_force);
	obd->obd_namespace = NULL;

	leaked = atomic_read(&obd->u.echo.eo_prep);
	if (leaked != 0)
		CERROR("%d prep/commitrw pages leaked\n", leaked);

	return 0;
}

struct obd_ops echo_obd_ops = {
	.o_owner	   = THIS_MODULE,
	.o_connect	 = echo_connect,
	.o_disconnect      = echo_disconnect,
	.o_init_export     = echo_init_export,
	.o_destroy_export  = echo_destroy_export,
	.o_create	  = echo_create,
	.o_destroy	 = echo_destroy,
	.o_getattr	 = echo_getattr,
	.o_setattr	 = echo_setattr,
	.o_preprw	  = echo_preprw,
	.o_commitrw	= echo_commitrw,
	.o_setup	   = echo_setup,
	.o_cleanup	 = echo_cleanup
};

void echo_persistent_pages_fini(void)
{
	int     i;

	for (i = 0; i < ECHO_PERSISTENT_PAGES; i++)
		if (echo_persistent_pages[i] != NULL) {
			OBD_PAGE_FREE(echo_persistent_pages[i]);
			echo_persistent_pages[i] = NULL;
		}
}

int echo_persistent_pages_init(void)
{
	struct page *pg;
	int	  i;

	for (i = 0; i < ECHO_PERSISTENT_PAGES; i++) {
		int gfp_mask = (i < ECHO_PERSISTENT_PAGES/2) ?
			GFP_IOFS : GFP_HIGHUSER;

		OBD_PAGE_ALLOC(pg, gfp_mask);
		if (pg == NULL) {
			echo_persistent_pages_fini ();
			return (-ENOMEM);
		}

		memset (kmap (pg), 0, PAGE_CACHE_SIZE);
		kunmap (pg);

		echo_persistent_pages[i] = pg;
	}

	return (0);
}
