/*
 * 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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/obdclass/llog_osd.c - low level llog routines on top of OSD API
 *
 * Author: Alexey Zhuravlev <alexey.zhuravlev@intel.com>
 * Author: Mikhail Pershin <mike.pershin@intel.com>
 */

#define DEBUG_SUBSYSTEM S_LOG

#include <obd.h>
#include <obd_class.h>
#include <lustre_fid.h>
#include <dt_object.h>

#include "llog_internal.h"
#include "local_storage.h"

/*
 * - multi-chunks or big-declaration approach
 * - use unique sequence instead of llog sb tracking unique ids
 * - re-use existing environment
 * - named llog support (can be used for testing only at the present)
 * - llog_origin_connect() work with OSD API
 */

static int llog_osd_declare_new_object(const struct lu_env *env,
				       struct local_oid_storage *los,
				       struct dt_object *o,
				       struct thandle *th)
{
	struct llog_thread_info *lgi = llog_info(env);

	lgi->lgi_attr.la_valid = LA_MODE;
	lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
	lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);

	return local_object_declare_create(env, los, o, &lgi->lgi_attr,
					   &lgi->lgi_dof, th);
}

static int llog_osd_create_new_object(const struct lu_env *env,
				      struct local_oid_storage *los,
				      struct dt_object *o,
				      struct thandle *th)
{
	struct llog_thread_info *lgi = llog_info(env);

	lgi->lgi_attr.la_valid = LA_MODE;
	lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
	lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);

	return local_object_create(env, los, o, &lgi->lgi_attr,
				   &lgi->lgi_dof, th);
}

static int llog_osd_pad(const struct lu_env *env, struct dt_object *o,
			loff_t *off, int len, int index, struct thandle *th)
{
	struct llog_thread_info	*lgi = llog_info(env);
	int			 rc;

	LASSERT(th);
	LASSERT(off);
	LASSERT(len >= LLOG_MIN_REC_SIZE && (len & 0x7) == 0);

	lgi->lgi_tail.lrt_len = lgi->lgi_lrh.lrh_len = len;
	lgi->lgi_tail.lrt_index = lgi->lgi_lrh.lrh_index = index;
	lgi->lgi_lrh.lrh_type = LLOG_PAD_MAGIC;

	lgi->lgi_buf.lb_buf = &lgi->lgi_lrh;
	lgi->lgi_buf.lb_len = sizeof(lgi->lgi_lrh);
	dt_write_lock(env, o, 0);
	rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
	if (rc) {
		CERROR("%s: error writing padding record: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, rc);
		GOTO(out, rc);
	}

	lgi->lgi_buf.lb_buf = &lgi->lgi_tail;
	lgi->lgi_buf.lb_len = sizeof(lgi->lgi_tail);
	*off += len - sizeof(lgi->lgi_lrh) - sizeof(lgi->lgi_tail);
	rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
	if (rc)
		CERROR("%s: error writing padding record: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, rc);
out:
	dt_write_unlock(env, o);
	return rc;
}

static int llog_osd_write_blob(const struct lu_env *env, struct dt_object *o,
			       struct llog_rec_hdr *rec, void *buf,
			       loff_t *off, struct thandle *th)
{
	struct llog_thread_info	*lgi = llog_info(env);
	int			 buflen = rec->lrh_len;
	int			 rc;

	LASSERT(env);
	LASSERT(o);

	if (buflen == 0)
		CWARN("0-length record\n");

	CDEBUG(D_OTHER, "write blob with type %x, buf %p/%u at off %llu\n",
	       rec->lrh_type, buf, buflen, *off);

	lgi->lgi_attr.la_valid = LA_SIZE;
	lgi->lgi_attr.la_size = *off;

	if (!buf) {
		lgi->lgi_buf.lb_len = buflen;
		lgi->lgi_buf.lb_buf = rec;
		rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
		if (rc)
			CERROR("%s: error writing log record: rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name, rc);
		GOTO(out, rc);
	}

	/* the buf case */
	/* protect the following 3 writes from concurrent read */
	dt_write_lock(env, o, 0);
	rec->lrh_len = sizeof(*rec) + buflen + sizeof(lgi->lgi_tail);
	lgi->lgi_buf.lb_len = sizeof(*rec);
	lgi->lgi_buf.lb_buf = rec;
	rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
	if (rc) {
		CERROR("%s: error writing log hdr: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, rc);
		GOTO(out_unlock, rc);
	}

	lgi->lgi_buf.lb_len = buflen;
	lgi->lgi_buf.lb_buf = buf;
	rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
	if (rc) {
		CERROR("%s: error writing log buffer: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,  rc);
		GOTO(out_unlock, rc);
	}

	lgi->lgi_tail.lrt_len = rec->lrh_len;
	lgi->lgi_tail.lrt_index = rec->lrh_index;
	lgi->lgi_buf.lb_len = sizeof(lgi->lgi_tail);
	lgi->lgi_buf.lb_buf = &lgi->lgi_tail;
	rc = dt_record_write(env, o, &lgi->lgi_buf, off, th);
	if (rc)
		CERROR("%s: error writing log tail: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, rc);

out_unlock:
	dt_write_unlock(env, o);

out:
	/* cleanup the content written above */
	if (rc) {
		dt_punch(env, o, lgi->lgi_attr.la_size, OBD_OBJECT_EOF, th,
			 BYPASS_CAPA);
		dt_attr_set(env, o, &lgi->lgi_attr, th, BYPASS_CAPA);
	}

	return rc;
}

static int llog_osd_read_header(const struct lu_env *env,
				struct llog_handle *handle)
{
	struct llog_rec_hdr	*llh_hdr;
	struct dt_object	*o;
	struct llog_thread_info	*lgi;
	int			 rc;

	LASSERT(sizeof(*handle->lgh_hdr) == LLOG_CHUNK_SIZE);

	o = handle->lgh_obj;
	LASSERT(o);

	lgi = llog_info(env);

	rc = dt_attr_get(env, o, &lgi->lgi_attr, NULL);
	if (rc)
		return rc;

	LASSERT(lgi->lgi_attr.la_valid & LA_SIZE);

	if (lgi->lgi_attr.la_size == 0) {
		CDEBUG(D_HA, "not reading header from 0-byte log\n");
		return LLOG_EEMPTY;
	}

	lgi->lgi_off = 0;
	lgi->lgi_buf.lb_buf = handle->lgh_hdr;
	lgi->lgi_buf.lb_len = LLOG_CHUNK_SIZE;

	rc = dt_record_read(env, o, &lgi->lgi_buf, &lgi->lgi_off);
	if (rc) {
		CERROR("%s: error reading log header from "DFID": rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,
		       PFID(lu_object_fid(&o->do_lu)), rc);
		return rc;
	}

	llh_hdr = &handle->lgh_hdr->llh_hdr;
	if (LLOG_REC_HDR_NEEDS_SWABBING(llh_hdr))
		lustre_swab_llog_hdr(handle->lgh_hdr);

	if (llh_hdr->lrh_type != LLOG_HDR_MAGIC) {
		CERROR("%s: bad log %s "DFID" header magic: %#x "
		       "(expected %#x)\n", o->do_lu.lo_dev->ld_obd->obd_name,
		       handle->lgh_name ? handle->lgh_name : "",
		       PFID(lu_object_fid(&o->do_lu)),
		       llh_hdr->lrh_type, LLOG_HDR_MAGIC);
		return -EIO;
	} else if (llh_hdr->lrh_len != LLOG_CHUNK_SIZE) {
		CERROR("%s: incorrectly sized log %s "DFID" header: "
		       "%#x (expected %#x)\n"
		       "you may need to re-run lconf --write_conf.\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,
		       handle->lgh_name ? handle->lgh_name : "",
		       PFID(lu_object_fid(&o->do_lu)),
		       llh_hdr->lrh_len, LLOG_CHUNK_SIZE);
		return -EIO;
	}

	handle->lgh_last_idx = handle->lgh_hdr->llh_tail.lrt_index;

	return 0;
}

static int llog_osd_declare_write_rec(const struct lu_env *env,
				      struct llog_handle *loghandle,
				      struct llog_rec_hdr *rec,
				      int idx, struct thandle *th)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct dt_object	*o;
	int			 rc;

	LASSERT(env);
	LASSERT(th);
	LASSERT(loghandle);

	o = loghandle->lgh_obj;
	LASSERT(o);

	/* each time we update header */
	rc = dt_declare_record_write(env, o, sizeof(struct llog_log_hdr), 0,
				     th);
	if (rc || idx == 0) /* if error or just header */
		return rc;

	if (dt_object_exists(o)) {
		rc = dt_attr_get(env, o, &lgi->lgi_attr, BYPASS_CAPA);
		lgi->lgi_off = lgi->lgi_attr.la_size;
		LASSERT(ergo(rc == 0, lgi->lgi_attr.la_valid & LA_SIZE));
		if (rc)
			return rc;

		rc = dt_declare_punch(env, o, lgi->lgi_off, OBD_OBJECT_EOF, th);
		if (rc)
			return rc;
	} else {
		lgi->lgi_off = 0;
	}

	/* XXX: implement declared window or multi-chunks approach */
	rc = dt_declare_record_write(env, o, 32 * 1024, lgi->lgi_off, th);

	return rc;
}

/* returns negative in on error; 0 if success && reccookie == 0; 1 otherwise */
/* appends if idx == -1, otherwise overwrites record idx. */
static int llog_osd_write_rec(const struct lu_env *env,
			      struct llog_handle *loghandle,
			      struct llog_rec_hdr *rec,
			      struct llog_cookie *reccookie, int cookiecount,
			      void *buf, int idx, struct thandle *th)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct llog_log_hdr	*llh;
	int			 reclen = rec->lrh_len;
	int			 index, rc, old_tail_idx;
	struct llog_rec_tail	*lrt;
	struct dt_object	*o;
	size_t			 left;

	LASSERT(env);
	llh = loghandle->lgh_hdr;
	LASSERT(llh);
	o = loghandle->lgh_obj;
	LASSERT(o);
	LASSERT(th);

	CDEBUG(D_OTHER, "new record %x to "DFID"\n",
	       rec->lrh_type, PFID(lu_object_fid(&o->do_lu)));

	/* record length should not bigger than LLOG_CHUNK_SIZE */
	if (buf)
		rc = (reclen > LLOG_CHUNK_SIZE - sizeof(struct llog_rec_hdr) -
		      sizeof(struct llog_rec_tail)) ? -E2BIG : 0;
	else
		rc = (reclen > LLOG_CHUNK_SIZE) ? -E2BIG : 0;
	if (rc)
		return rc;

	rc = dt_attr_get(env, o, &lgi->lgi_attr, NULL);
	if (rc)
		return rc;

	if (buf)
		/* write_blob adds header and tail to lrh_len. */
		reclen = sizeof(*rec) + rec->lrh_len +
			 sizeof(struct llog_rec_tail);

	if (idx != -1) {
		/* no header: only allowed to insert record 1 */
		if (idx != 1 && lgi->lgi_attr.la_size == 0)
			LBUG();

		if (idx && llh->llh_size && llh->llh_size != rec->lrh_len)
			return -EINVAL;

		if (!ext2_test_bit(idx, llh->llh_bitmap))
			CERROR("%s: modify unset record %u\n",
			       o->do_lu.lo_dev->ld_obd->obd_name, idx);
		if (idx != rec->lrh_index)
			CERROR("%s: index mismatch %d %u\n",
			       o->do_lu.lo_dev->ld_obd->obd_name, idx,
			       rec->lrh_index);

		lgi->lgi_off = 0;
		rc = llog_osd_write_blob(env, o, &llh->llh_hdr, NULL,
					 &lgi->lgi_off, th);
		/* we are done if we only write the header or on error */
		if (rc || idx == 0)
			return rc;

		if (buf) {
			/* We assume that caller has set lgh_cur_* */
			lgi->lgi_off = loghandle->lgh_cur_offset;
			CDEBUG(D_OTHER,
			       "modify record "DOSTID": idx:%d/%u/%d, len:%u "
			       "offset %llu\n",
			       POSTID(&loghandle->lgh_id.lgl_oi), idx,
			       rec->lrh_index,
			       loghandle->lgh_cur_idx, rec->lrh_len,
			       (long long)(lgi->lgi_off - sizeof(*llh)));
			if (rec->lrh_index != loghandle->lgh_cur_idx) {
				CERROR("%s: modify idx mismatch %u/%d\n",
				       o->do_lu.lo_dev->ld_obd->obd_name, idx,
				       loghandle->lgh_cur_idx);
				return -EFAULT;
			}
		} else {
			/* Assumes constant lrh_len */
			lgi->lgi_off = sizeof(*llh) + (idx - 1) * reclen;
		}

		rc = llog_osd_write_blob(env, o, rec, buf, &lgi->lgi_off, th);
		if (rc == 0 && reccookie) {
			reccookie->lgc_lgl = loghandle->lgh_id;
			reccookie->lgc_index = idx;
			rc = 1;
		}
		return rc;
	}

	/* Make sure that records don't cross a chunk boundary, so we can
	 * process them page-at-a-time if needed.  If it will cross a chunk
	 * boundary, write in a fake (but referenced) entry to pad the chunk.
	 *
	 * We know that llog_current_log() will return a loghandle that is
	 * big enough to hold reclen, so all we care about is padding here.
	 */
	LASSERT(lgi->lgi_attr.la_valid & LA_SIZE);
	lgi->lgi_off = lgi->lgi_attr.la_size;
	left = LLOG_CHUNK_SIZE - (lgi->lgi_off & (LLOG_CHUNK_SIZE - 1));
	/* NOTE: padding is a record, but no bit is set */
	if (left != 0 && left != reclen &&
	    left < (reclen + LLOG_MIN_REC_SIZE)) {
		index = loghandle->lgh_last_idx + 1;
		rc = llog_osd_pad(env, o, &lgi->lgi_off, left, index, th);
		if (rc)
			return rc;
		loghandle->lgh_last_idx++; /*for pad rec*/
	}
	/* if it's the last idx in log file, then return -ENOSPC */
	if (loghandle->lgh_last_idx >= LLOG_BITMAP_SIZE(llh) - 1)
		return -ENOSPC;

	loghandle->lgh_last_idx++;
	index = loghandle->lgh_last_idx;
	LASSERT(index < LLOG_BITMAP_SIZE(llh));
	rec->lrh_index = index;
	if (buf == NULL) {
		lrt = (struct llog_rec_tail *)((char *)rec + rec->lrh_len -
					       sizeof(*lrt));
		lrt->lrt_len = rec->lrh_len;
		lrt->lrt_index = rec->lrh_index;
	}
	/* The caller should make sure only 1 process access the lgh_last_idx,
	 * Otherwise it might hit the assert.*/
	LASSERT(index < LLOG_BITMAP_SIZE(llh));
	spin_lock(&loghandle->lgh_hdr_lock);
	if (ext2_set_bit(index, llh->llh_bitmap)) {
		CERROR("%s: index %u already set in log bitmap\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, index);
		spin_unlock(&loghandle->lgh_hdr_lock);
		LBUG(); /* should never happen */
	}
	llh->llh_count++;
	spin_unlock(&loghandle->lgh_hdr_lock);
	old_tail_idx = llh->llh_tail.lrt_index;
	llh->llh_tail.lrt_index = index;

	lgi->lgi_off = 0;
	rc = llog_osd_write_blob(env, o, &llh->llh_hdr, NULL, &lgi->lgi_off,
				 th);
	if (rc)
		GOTO(out, rc);

	rc = dt_attr_get(env, o, &lgi->lgi_attr, NULL);
	if (rc)
		GOTO(out, rc);

	LASSERT(lgi->lgi_attr.la_valid & LA_SIZE);
	lgi->lgi_off = lgi->lgi_attr.la_size;

	rc = llog_osd_write_blob(env, o, rec, buf, &lgi->lgi_off, th);

out:
	/* cleanup llog for error case */
	if (rc) {
		spin_lock(&loghandle->lgh_hdr_lock);
		ext2_clear_bit(index, llh->llh_bitmap);
		llh->llh_count--;
		spin_unlock(&loghandle->lgh_hdr_lock);

		/* restore the header */
		loghandle->lgh_last_idx--;
		llh->llh_tail.lrt_index = old_tail_idx;
		lgi->lgi_off = 0;
		llog_osd_write_blob(env, o, &llh->llh_hdr, NULL,
				    &lgi->lgi_off, th);
	}

	CDEBUG(D_RPCTRACE, "added record "DOSTID": idx: %u, %u\n",
	       POSTID(&loghandle->lgh_id.lgl_oi), index, rec->lrh_len);
	if (rc == 0 && reccookie) {
		reccookie->lgc_lgl = loghandle->lgh_id;
		reccookie->lgc_index = index;
		if ((rec->lrh_type == MDS_UNLINK_REC) ||
		    (rec->lrh_type == MDS_SETATTR64_REC))
			reccookie->lgc_subsys = LLOG_MDS_OST_ORIG_CTXT;
		else if (rec->lrh_type == OST_SZ_REC)
			reccookie->lgc_subsys = LLOG_SIZE_ORIG_CTXT;
		else
			reccookie->lgc_subsys = -1;
		rc = 1;
	}
	return rc;
}

/* We can skip reading at least as many log blocks as the number of
 * minimum sized log records we are skipping.  If it turns out
 * that we are not far enough along the log (because the
 * actual records are larger than minimum size) we just skip
 * some more records.
 */
static void llog_skip_over(__u64 *off, int curr, int goal)
{
	if (goal <= curr)
		return;
	*off = (*off + (goal - curr - 1) * LLOG_MIN_REC_SIZE) &
		~(LLOG_CHUNK_SIZE - 1);
}

/* sets:
 *  - cur_offset to the furthest point read in the log file
 *  - cur_idx to the log index preceeding cur_offset
 * returns -EIO/-EINVAL on error
 */
static int llog_osd_next_block(const struct lu_env *env,
			       struct llog_handle *loghandle, int *cur_idx,
			       int next_idx, __u64 *cur_offset, void *buf,
			       int len)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct dt_object	*o;
	struct dt_device	*dt;
	int			 rc;

	LASSERT(env);
	LASSERT(lgi);

	if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
		return -EINVAL;

	CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n",
	       next_idx, *cur_idx, *cur_offset);

	LASSERT(loghandle);
	LASSERT(loghandle->lgh_ctxt);

	o = loghandle->lgh_obj;
	LASSERT(o);
	LASSERT(dt_object_exists(o));
	dt = lu2dt_dev(o->do_lu.lo_dev);
	LASSERT(dt);

	rc = dt_attr_get(env, o, &lgi->lgi_attr, BYPASS_CAPA);
	if (rc)
		GOTO(out, rc);

	while (*cur_offset < lgi->lgi_attr.la_size) {
		struct llog_rec_hdr	*rec, *last_rec;
		struct llog_rec_tail	*tail;

		llog_skip_over(cur_offset, *cur_idx, next_idx);

		/* read up to next LLOG_CHUNK_SIZE block */
		lgi->lgi_buf.lb_len = LLOG_CHUNK_SIZE -
				      (*cur_offset & (LLOG_CHUNK_SIZE - 1));
		lgi->lgi_buf.lb_buf = buf;

		/* Note: read lock is not needed around la_size get above at
		 * the time of dt_attr_get(). There are only two cases that
		 * matter. Either la_size == cur_offset, in which case the
		 * entire read is skipped, or la_size > cur_offset and the loop
		 * is entered and this thread is blocked at dt_read_lock()
		 * until the write is completed. When the write completes, then
		 * the dt_read() will be done with the full length, and will
		 * get the full data.
		 */
		dt_read_lock(env, o, 0);
		rc = dt_read(env, o, &lgi->lgi_buf, cur_offset);
		dt_read_unlock(env, o);
		if (rc < 0) {
			CERROR("%s: can't read llog block from log "DFID
			       " offset "LPU64": rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       PFID(lu_object_fid(&o->do_lu)), *cur_offset,
			       rc);
			GOTO(out, rc);
		}

		if (rc < len) {
			/* signal the end of the valid buffer to
			 * llog_process */
			memset(buf + rc, 0, len - rc);
		}

		if (rc == 0) /* end of file, nothing to do */
			GOTO(out, rc);

		if (rc < sizeof(*tail)) {
			CERROR("%s: invalid llog block at log id "DOSTID"/%u "
			       "offset "LPU64"\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       POSTID(&loghandle->lgh_id.lgl_oi),
			       loghandle->lgh_id.lgl_ogen, *cur_offset);
			GOTO(out, rc = -EINVAL);
		}

		rec = buf;
		if (LLOG_REC_HDR_NEEDS_SWABBING(rec))
			lustre_swab_llog_rec(rec);

		tail = (struct llog_rec_tail *)((char *)buf + rc -
						sizeof(struct llog_rec_tail));
		/* get the last record in block */
		last_rec = (struct llog_rec_hdr *)((char *)buf + rc -
						   le32_to_cpu(tail->lrt_len));

		if (LLOG_REC_HDR_NEEDS_SWABBING(last_rec))
			lustre_swab_llog_rec(last_rec);
		LASSERT(last_rec->lrh_index == tail->lrt_index);

		*cur_idx = tail->lrt_index;

		/* this shouldn't happen */
		if (tail->lrt_index == 0) {
			CERROR("%s: invalid llog tail at log id "DOSTID"/%u "
			       "offset "LPU64"\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       POSTID(&loghandle->lgh_id.lgl_oi),
			       loghandle->lgh_id.lgl_ogen, *cur_offset);
			GOTO(out, rc = -EINVAL);
		}
		if (tail->lrt_index < next_idx)
			continue;

		/* sanity check that the start of the new buffer is no farther
		 * than the record that we wanted.  This shouldn't happen. */
		if (rec->lrh_index > next_idx) {
			CERROR("%s: missed desired record? %u > %u\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       rec->lrh_index, next_idx);
			GOTO(out, rc = -ENOENT);
		}
		GOTO(out, rc = 0);
	}
	GOTO(out, rc = -EIO);
out:
	return rc;
}

static int llog_osd_prev_block(const struct lu_env *env,
			       struct llog_handle *loghandle,
			       int prev_idx, void *buf, int len)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct dt_object	*o;
	struct dt_device	*dt;
	loff_t			 cur_offset;
	int			 rc;

	if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
		return -EINVAL;

	CDEBUG(D_OTHER, "looking for log index %u\n", prev_idx);

	LASSERT(loghandle);
	LASSERT(loghandle->lgh_ctxt);

	o = loghandle->lgh_obj;
	LASSERT(o);
	LASSERT(dt_object_exists(o));
	dt = lu2dt_dev(o->do_lu.lo_dev);
	LASSERT(dt);

	cur_offset = LLOG_CHUNK_SIZE;
	llog_skip_over(&cur_offset, 0, prev_idx);

	rc = dt_attr_get(env, o, &lgi->lgi_attr, BYPASS_CAPA);
	if (rc)
		GOTO(out, rc);

	while (cur_offset < lgi->lgi_attr.la_size) {
		struct llog_rec_hdr	*rec, *last_rec;
		struct llog_rec_tail	*tail;

		lgi->lgi_buf.lb_len = len;
		lgi->lgi_buf.lb_buf = buf;
		/* It is OK to have locking around dt_read() only, see
		 * comment in llog_osd_next_block for details
		 */
		dt_read_lock(env, o, 0);
		rc = dt_read(env, o, &lgi->lgi_buf, &cur_offset);
		dt_read_unlock(env, o);
		if (rc < 0) {
			CERROR("%s: can't read llog block from log "DFID
			       " offset "LPU64": rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       PFID(lu_object_fid(&o->do_lu)), cur_offset, rc);
			GOTO(out, rc);
		}

		if (rc == 0) /* end of file, nothing to do */
			GOTO(out, rc);

		if (rc < sizeof(*tail)) {
			CERROR("%s: invalid llog block at log id "DOSTID"/%u "
			       "offset "LPU64"\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       POSTID(&loghandle->lgh_id.lgl_oi),
			       loghandle->lgh_id.lgl_ogen, cur_offset);
			GOTO(out, rc = -EINVAL);
		}

		rec = buf;
		if (LLOG_REC_HDR_NEEDS_SWABBING(rec))
			lustre_swab_llog_rec(rec);

		tail = (struct llog_rec_tail *)((char *)buf + rc -
						sizeof(struct llog_rec_tail));
		/* get the last record in block */
		last_rec = (struct llog_rec_hdr *)((char *)buf + rc -
						   le32_to_cpu(tail->lrt_len));

		if (LLOG_REC_HDR_NEEDS_SWABBING(last_rec))
			lustre_swab_llog_rec(last_rec);
		LASSERT(last_rec->lrh_index == tail->lrt_index);

		/* this shouldn't happen */
		if (tail->lrt_index == 0) {
			CERROR("%s: invalid llog tail at log id "DOSTID"/%u "
			       "offset "LPU64"\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       POSTID(&loghandle->lgh_id.lgl_oi),
			       loghandle->lgh_id.lgl_ogen, cur_offset);
			GOTO(out, rc = -EINVAL);
		}
		if (tail->lrt_index < prev_idx)
			continue;

		/* sanity check that the start of the new buffer is no farther
		 * than the record that we wanted.  This shouldn't happen. */
		if (rec->lrh_index > prev_idx) {
			CERROR("%s: missed desired record? %u > %u\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       rec->lrh_index, prev_idx);
			GOTO(out, rc = -ENOENT);
		}
		GOTO(out, rc = 0);
	}
	GOTO(out, rc = -EIO);
out:
	return rc;
}

struct dt_object *llog_osd_dir_get(const struct lu_env *env,
				   struct llog_ctxt *ctxt)
{
	struct dt_device	*dt;
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dir;
	int			 rc;

	dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt;
	if (ctxt->loc_dir == NULL) {
		rc = dt_root_get(env, dt, &dti->dti_fid);
		if (rc)
			return ERR_PTR(rc);
		dir = dt_locate(env, dt, &dti->dti_fid);
	} else {
		lu_object_get(&ctxt->loc_dir->do_lu);
		dir = ctxt->loc_dir;
	}

	return dir;
}

static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle,
			 struct llog_logid *logid, char *name,
			 enum llog_open_param open_param)
{
	struct llog_thread_info		*lgi = llog_info(env);
	struct llog_ctxt		*ctxt = handle->lgh_ctxt;
	struct dt_object		*o;
	struct dt_device		*dt;
	struct ls_device		*ls;
	struct local_oid_storage	*los;
	int				 rc = 0;

	LASSERT(env);
	LASSERT(ctxt);
	LASSERT(ctxt->loc_exp);
	LASSERT(ctxt->loc_exp->exp_obd);
	dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt;
	LASSERT(dt);

	ls = ls_device_get(dt);
	if (IS_ERR(ls))
		return PTR_ERR(ls);

	mutex_lock(&ls->ls_los_mutex);
	los = dt_los_find(ls, name != NULL ? FID_SEQ_LLOG_NAME : FID_SEQ_LLOG);
	mutex_unlock(&ls->ls_los_mutex);
	LASSERT(los);
	ls_device_put(env, ls);

	LASSERT(handle);

	if (logid != NULL) {
		logid_to_fid(logid, &lgi->lgi_fid);
	} else if (name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, ctxt);
		if (IS_ERR(llog_dir))
			GOTO(out, rc = PTR_ERR(llog_dir));
		dt_read_lock(env, llog_dir, 0);
		rc = dt_lookup_dir(env, llog_dir, name, &lgi->lgi_fid);
		dt_read_unlock(env, llog_dir);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc == -ENOENT && open_param == LLOG_OPEN_NEW) {
			/* generate fid for new llog */
			rc = local_object_fid_generate(env, los,
						       &lgi->lgi_fid);
		}
		if (rc < 0)
			GOTO(out, rc);
		OBD_ALLOC(handle->lgh_name, strlen(name) + 1);
		if (handle->lgh_name)
			strcpy(handle->lgh_name, name);
		else
			GOTO(out, rc = -ENOMEM);
	} else {
		LASSERTF(open_param & LLOG_OPEN_NEW, "%#x\n", open_param);
		/* generate fid for new llog */
		rc = local_object_fid_generate(env, los, &lgi->lgi_fid);
		if (rc < 0)
			GOTO(out, rc);
	}

	o = ls_locate(env, ls, &lgi->lgi_fid);
	if (IS_ERR(o))
		GOTO(out_name, rc = PTR_ERR(o));

	/* No new llog is expected but doesn't exist */
	if (open_param != LLOG_OPEN_NEW && !dt_object_exists(o))
		GOTO(out_put, rc = -ENOENT);

	fid_to_logid(&lgi->lgi_fid, &handle->lgh_id);
	handle->lgh_obj = o;
	handle->private_data = los;
	LASSERT(handle->lgh_ctxt);

	return rc;

out_put:
	lu_object_put(env, &o->do_lu);
out_name:
	if (handle->lgh_name != NULL)
		OBD_FREE(handle->lgh_name, strlen(name) + 1);
out:
	dt_los_put(los);
	return rc;
}

static int llog_osd_exist(struct llog_handle *handle)
{
	LASSERT(handle->lgh_obj);
	return (dt_object_exists(handle->lgh_obj) &&
		!lu_object_is_dying(handle->lgh_obj->do_lu.lo_header));
}

static int llog_osd_declare_create(const struct lu_env *env,
				   struct llog_handle *res, struct thandle *th)
{
	struct llog_thread_info		*lgi = llog_info(env);
	struct local_oid_storage	*los;
	struct dt_object		*o;
	int				 rc;

	LASSERT(res->lgh_obj);
	LASSERT(th);

	/* object can be created by another thread */
	o = res->lgh_obj;
	if (dt_object_exists(o))
		return 0;

	los = res->private_data;
	LASSERT(los);

	rc = llog_osd_declare_new_object(env, los, o, th);
	if (rc)
		return rc;

	rc = dt_declare_record_write(env, o, LLOG_CHUNK_SIZE, 0, th);
	if (rc)
		return rc;

	if (res->lgh_name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, res->lgh_ctxt);
		if (IS_ERR(llog_dir))
			return PTR_ERR(llog_dir);
		logid_to_fid(&res->lgh_id, &lgi->lgi_fid);
		rc = dt_declare_insert(env, llog_dir,
				       (struct dt_rec *)&lgi->lgi_fid,
				       (struct dt_key *)res->lgh_name, th);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc)
			CERROR("%s: can't declare named llog %s: rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       res->lgh_name, rc);
	}
	return rc;
}

/* This is a callback from the llog_* functions.
 * Assumes caller has already pushed us into the kernel context. */
static int llog_osd_create(const struct lu_env *env, struct llog_handle *res,
			   struct thandle *th)
{
	struct llog_thread_info *lgi = llog_info(env);
	struct local_oid_storage *los;
	struct dt_object	*o;
	int		      rc = 0;

	LASSERT(env);
	o = res->lgh_obj;
	LASSERT(o);

	/* llog can be already created */
	if (dt_object_exists(o))
		return -EEXIST;

	los = res->private_data;
	LASSERT(los);

	dt_write_lock(env, o, 0);
	if (!dt_object_exists(o))
		rc = llog_osd_create_new_object(env, los, o, th);
	else
		rc = -EEXIST;

	dt_write_unlock(env, o);
	if (rc)
		return rc;

	if (res->lgh_name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, res->lgh_ctxt);
		if (IS_ERR(llog_dir))
			return PTR_ERR(llog_dir);

		logid_to_fid(&res->lgh_id, &lgi->lgi_fid);
		dt_read_lock(env, llog_dir, 0);
		rc = dt_insert(env, llog_dir,
			       (struct dt_rec *)&lgi->lgi_fid,
			       (struct dt_key *)res->lgh_name,
			       th, BYPASS_CAPA, 1);
		dt_read_unlock(env, llog_dir);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc)
			CERROR("%s: can't create named llog %s: rc = %d\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       res->lgh_name, rc);
	}
	return rc;
}

static int llog_osd_close(const struct lu_env *env, struct llog_handle *handle)
{
	struct local_oid_storage	*los;
	int				 rc = 0;

	LASSERT(handle->lgh_obj);

	lu_object_put(env, &handle->lgh_obj->do_lu);

	los = handle->private_data;
	LASSERT(los);
	dt_los_put(los);

	if (handle->lgh_name)
		OBD_FREE(handle->lgh_name, strlen(handle->lgh_name) + 1);

	return rc;
}

static int llog_osd_destroy(const struct lu_env *env,
			    struct llog_handle *loghandle)
{
	struct llog_ctxt	*ctxt;
	struct dt_object	*o, *llog_dir = NULL;
	struct dt_device	*d;
	struct thandle		*th;
	char			*name = NULL;
	int			 rc;

	ctxt = loghandle->lgh_ctxt;
	LASSERT(ctxt);

	o = loghandle->lgh_obj;
	LASSERT(o);

	d = lu2dt_dev(o->do_lu.lo_dev);
	LASSERT(d);
	LASSERT(d == ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt);

	th = dt_trans_create(env, d);
	if (IS_ERR(th))
		return PTR_ERR(th);

	if (loghandle->lgh_name) {
		llog_dir = llog_osd_dir_get(env, ctxt);
		if (IS_ERR(llog_dir))
			GOTO(out_trans, rc = PTR_ERR(llog_dir));

		name = loghandle->lgh_name;
		rc = dt_declare_delete(env, llog_dir,
				       (struct dt_key *)name, th);
		if (rc)
			GOTO(out_trans, rc);
	}

	dt_declare_ref_del(env, o, th);

	rc = dt_declare_destroy(env, o, th);
	if (rc)
		GOTO(out_trans, rc);

	rc = dt_trans_start_local(env, d, th);
	if (rc)
		GOTO(out_trans, rc);

	dt_write_lock(env, o, 0);
	if (dt_object_exists(o)) {
		if (name) {
			dt_read_lock(env, llog_dir, 0);
			rc = dt_delete(env, llog_dir,
				       (struct dt_key *) name,
				       th, BYPASS_CAPA);
			dt_read_unlock(env, llog_dir);
			if (rc) {
				CERROR("%s: can't remove llog %s: rc = %d\n",
				       o->do_lu.lo_dev->ld_obd->obd_name,
				       name, rc);
				GOTO(out_unlock, rc);
			}
		}
		dt_ref_del(env, o, th);
		rc = dt_destroy(env, o, th);
		if (rc)
			GOTO(out_unlock, rc);
	}
out_unlock:
	dt_write_unlock(env, o);
out_trans:
	dt_trans_stop(env, d, th);
	if (llog_dir != NULL)
		lu_object_put(env, &llog_dir->do_lu);
	return rc;
}

static int llog_osd_setup(const struct lu_env *env, struct obd_device *obd,
			  struct obd_llog_group *olg, int ctxt_idx,
			  struct obd_device *disk_obd)
{
	struct local_oid_storage	*los;
	struct llog_thread_info		*lgi = llog_info(env);
	struct llog_ctxt		*ctxt;
	int				 rc = 0;

	LASSERT(obd);
	LASSERT(olg->olg_ctxts[ctxt_idx]);

	ctxt = llog_ctxt_get(olg->olg_ctxts[ctxt_idx]);
	LASSERT(ctxt);

	/* initialize data allowing to generate new fids,
	 * literally we need a sequece */
	lgi->lgi_fid.f_seq = FID_SEQ_LLOG;
	lgi->lgi_fid.f_oid = 1;
	lgi->lgi_fid.f_ver = 0;
	rc = local_oid_storage_init(env, disk_obd->obd_lvfs_ctxt.dt,
				    &lgi->lgi_fid, &los);
	if (rc < 0)
		return rc;

	lgi->lgi_fid.f_seq = FID_SEQ_LLOG_NAME;
	lgi->lgi_fid.f_oid = 1;
	lgi->lgi_fid.f_ver = 0;
	rc = local_oid_storage_init(env, disk_obd->obd_lvfs_ctxt.dt,
				    &lgi->lgi_fid, &los);
	llog_ctxt_put(ctxt);
	return rc;
}

static int llog_osd_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
{
	struct dt_device		*dt;
	struct ls_device		*ls;
	struct local_oid_storage	*los, *nlos;

	LASSERT(ctxt->loc_exp->exp_obd);
	dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt;
	ls = ls_device_get(dt);
	if (IS_ERR(ls))
		return PTR_ERR(ls);

	mutex_lock(&ls->ls_los_mutex);
	los = dt_los_find(ls, FID_SEQ_LLOG);
	nlos = dt_los_find(ls, FID_SEQ_LLOG_NAME);
	mutex_unlock(&ls->ls_los_mutex);
	if (los != NULL) {
		dt_los_put(los);
		local_oid_storage_fini(env, los);
	}
	if (nlos != NULL) {
		dt_los_put(nlos);
		local_oid_storage_fini(env, nlos);
	}
	ls_device_put(env, ls);
	return 0;
}

struct llog_operations llog_osd_ops = {
	.lop_next_block		= llog_osd_next_block,
	.lop_prev_block		= llog_osd_prev_block,
	.lop_read_header	= llog_osd_read_header,
	.lop_destroy		= llog_osd_destroy,
	.lop_setup		= llog_osd_setup,
	.lop_cleanup		= llog_osd_cleanup,
	.lop_open		= llog_osd_open,
	.lop_exist		= llog_osd_exist,
	.lop_declare_create	= llog_osd_declare_create,
	.lop_create		= llog_osd_create,
	.lop_declare_write_rec	= llog_osd_declare_write_rec,
	.lop_write_rec		= llog_osd_write_rec,
	.lop_close		= llog_osd_close,
};
EXPORT_SYMBOL(llog_osd_ops);

/* reads the catalog list */
int llog_osd_get_cat_list(const struct lu_env *env, struct dt_device *d,
			  int idx, int count, struct llog_catid *idarray)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct dt_object	*o = NULL;
	struct thandle		*th;
	int			 rc, size;

	LASSERT(d);

	size = sizeof(*idarray) * count;
	lgi->lgi_off = idx *  sizeof(*idarray);

	lu_local_obj_fid(&lgi->lgi_fid, LLOG_CATALOGS_OID);

	o = dt_locate(env, d, &lgi->lgi_fid);
	if (IS_ERR(o))
		return PTR_ERR(o);

	if (!dt_object_exists(o)) {
		th = dt_trans_create(env, d);
		if (IS_ERR(th))
			GOTO(out, rc = PTR_ERR(th));

		lgi->lgi_attr.la_valid = LA_MODE;
		lgi->lgi_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
		lgi->lgi_dof.dof_type = dt_mode_to_dft(S_IFREG);

		rc = dt_declare_create(env, o, &lgi->lgi_attr, NULL,
				       &lgi->lgi_dof, th);
		if (rc)
			GOTO(out_trans, rc);

		rc = dt_trans_start_local(env, d, th);
		if (rc)
			GOTO(out_trans, rc);

		dt_write_lock(env, o, 0);
		if (!dt_object_exists(o))
			rc = dt_create(env, o, &lgi->lgi_attr, NULL,
				       &lgi->lgi_dof, th);
		dt_write_unlock(env, o);
out_trans:
		dt_trans_stop(env, d, th);
		if (rc)
			GOTO(out, rc);
	}

	rc = dt_attr_get(env, o, &lgi->lgi_attr, BYPASS_CAPA);
	if (rc)
		GOTO(out, rc);

	if (!S_ISREG(lgi->lgi_attr.la_mode)) {
		CERROR("%s: CATALOGS is not a regular file!: mode = %o\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,
		       lgi->lgi_attr.la_mode);
		GOTO(out, rc = -ENOENT);
	}

	CDEBUG(D_CONFIG, "cat list: disk size=%d, read=%d\n",
	       (int)lgi->lgi_attr.la_size, size);

	/* return just number of llogs */
	if (idarray == NULL) {
		rc = lgi->lgi_attr.la_size / sizeof(*idarray);
		GOTO(out, rc);
	}

	/* read for new ost index or for empty file */
	memset(idarray, 0, size);
	if (lgi->lgi_attr.la_size < lgi->lgi_off + size)
		GOTO(out, rc = 0);
	if (lgi->lgi_attr.la_size < lgi->lgi_off + size)
		size = lgi->lgi_attr.la_size - lgi->lgi_off;

	lgi->lgi_buf.lb_buf = idarray;
	lgi->lgi_buf.lb_len = size;
	rc = dt_record_read(env, o, &lgi->lgi_buf, &lgi->lgi_off);
	if (rc) {
		CERROR("%s: error reading CATALOGS: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,  rc);
		GOTO(out, rc);
	}

out:
	lu_object_put(env, &o->do_lu);
	return rc;
}
EXPORT_SYMBOL(llog_osd_get_cat_list);

/* writes the cat list */
int llog_osd_put_cat_list(const struct lu_env *env, struct dt_device *d,
			  int idx, int count, struct llog_catid *idarray)
{
	struct llog_thread_info	*lgi = llog_info(env);
	struct dt_object	*o = NULL;
	struct thandle		*th;
	int			 rc, size;

	if (!count)
		return 0;

	LASSERT(d);

	size = sizeof(*idarray) * count;
	lgi->lgi_off = idx * sizeof(*idarray);

	lu_local_obj_fid(&lgi->lgi_fid, LLOG_CATALOGS_OID);

	o = dt_locate(env, d, &lgi->lgi_fid);
	if (IS_ERR(o))
		return PTR_ERR(o);

	if (!dt_object_exists(o))
		GOTO(out, rc = -ENOENT);

	rc = dt_attr_get(env, o, &lgi->lgi_attr, BYPASS_CAPA);
	if (rc)
		GOTO(out, rc);

	if (!S_ISREG(lgi->lgi_attr.la_mode)) {
		CERROR("%s: CATALOGS is not a regular file!: mode = %o\n",
		       o->do_lu.lo_dev->ld_obd->obd_name,
		       lgi->lgi_attr.la_mode);
		GOTO(out, rc = -ENOENT);
	}

	th = dt_trans_create(env, d);
	if (IS_ERR(th))
		GOTO(out, rc = PTR_ERR(th));

	rc = dt_declare_record_write(env, o, size, lgi->lgi_off, th);
	if (rc)
		GOTO(out, rc);

	rc = dt_trans_start_local(env, d, th);
	if (rc)
		GOTO(out_trans, rc);

	lgi->lgi_buf.lb_buf = idarray;
	lgi->lgi_buf.lb_len = size;
	rc = dt_record_write(env, o, &lgi->lgi_buf, &lgi->lgi_off, th);
	if (rc)
		CDEBUG(D_INODE, "error writeing CATALOGS: rc = %d\n", rc);
out_trans:
	dt_trans_stop(env, d, th);
out:
	lu_object_put(env, &o->do_lu);
	return rc;
}
EXPORT_SYMBOL(llog_osd_put_cat_list);
