/*
 * 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 COPYING file that accompanied this code.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2012, Intel Corporation.
 */
/*
 * lustre/obdclass/local_storage.c
 *
 * Local storage for file/objects with fid generation. Works on top of OSD.
 *
 * Author: Mikhail Pershin <mike.pershin@intel.com>
 */

#define DEBUG_SUBSYSTEM S_CLASS

#include "local_storage.h"

/* all initialized local storages on this node are linked on this */
static LIST_HEAD(ls_list_head);
static DEFINE_MUTEX(ls_list_mutex);

static int ls_object_init(const struct lu_env *env, struct lu_object *o,
			  const struct lu_object_conf *unused)
{
	struct ls_device	*ls;
	struct lu_object	*below;
	struct lu_device	*under;

	ls = container_of0(o->lo_dev, struct ls_device, ls_top_dev.dd_lu_dev);
	under = &ls->ls_osd->dd_lu_dev;
	below = under->ld_ops->ldo_object_alloc(env, o->lo_header, under);
	if (below == NULL)
		return -ENOMEM;

	lu_object_add(o, below);

	return 0;
}

static void ls_object_free(const struct lu_env *env, struct lu_object *o)
{
	struct ls_object	*obj = lu2ls_obj(o);
	struct lu_object_header	*h = o->lo_header;

	dt_object_fini(&obj->ls_obj);
	lu_object_header_fini(h);
	OBD_FREE_PTR(obj);
}

struct lu_object_operations ls_lu_obj_ops = {
	.loo_object_init  = ls_object_init,
	.loo_object_free  = ls_object_free,
};

struct lu_object *ls_object_alloc(const struct lu_env *env,
				  const struct lu_object_header *_h,
				  struct lu_device *d)
{
	struct lu_object_header	*h;
	struct ls_object	*o;
	struct lu_object	*l;

	LASSERT(_h == NULL);

	OBD_ALLOC_PTR(o);
	if (o != NULL) {
		l = &o->ls_obj.do_lu;
		h = &o->ls_header;

		lu_object_header_init(h);
		dt_object_init(&o->ls_obj, h, d);
		lu_object_add_top(h, l);

		l->lo_ops = &ls_lu_obj_ops;

		return l;
	} else {
		return NULL;
	}
}

static struct lu_device_operations ls_lu_dev_ops = {
	.ldo_object_alloc =	ls_object_alloc
};

static struct ls_device *__ls_find_dev(struct dt_device *dev)
{
	struct ls_device *ls, *ret = NULL;

	list_for_each_entry(ls, &ls_list_head, ls_linkage) {
		if (ls->ls_osd == dev) {
			atomic_inc(&ls->ls_refcount);
			ret = ls;
			break;
		}
	}
	return ret;
}

struct ls_device *ls_find_dev(struct dt_device *dev)
{
	struct ls_device *ls;

	mutex_lock(&ls_list_mutex);
	ls = __ls_find_dev(dev);
	mutex_unlock(&ls_list_mutex);

	return ls;
}

static struct lu_device_type_operations ls_device_type_ops = {
	.ldto_start = NULL,
	.ldto_stop  = NULL,
};

static struct lu_device_type ls_lu_type = {
	.ldt_name = "local_storage",
	.ldt_ops  = &ls_device_type_ops,
};

struct ls_device *ls_device_get(struct dt_device *dev)
{
	struct ls_device *ls;

	mutex_lock(&ls_list_mutex);
	ls = __ls_find_dev(dev);
	if (ls)
		GOTO(out_ls, ls);

	/* not found, then create */
	OBD_ALLOC_PTR(ls);
	if (ls == NULL)
		GOTO(out_ls, ls = ERR_PTR(-ENOMEM));

	atomic_set(&ls->ls_refcount, 1);
	INIT_LIST_HEAD(&ls->ls_los_list);
	mutex_init(&ls->ls_los_mutex);

	ls->ls_osd = dev;

	LASSERT(dev->dd_lu_dev.ld_site);
	lu_device_init(&ls->ls_top_dev.dd_lu_dev, &ls_lu_type);
	ls->ls_top_dev.dd_lu_dev.ld_ops = &ls_lu_dev_ops;
	ls->ls_top_dev.dd_lu_dev.ld_site = dev->dd_lu_dev.ld_site;

	/* finally add ls to the list */
	list_add(&ls->ls_linkage, &ls_list_head);
out_ls:
	mutex_unlock(&ls_list_mutex);
	return ls;
}

void ls_device_put(const struct lu_env *env, struct ls_device *ls)
{
	LASSERT(env);
	if (!atomic_dec_and_test(&ls->ls_refcount))
		return;

	mutex_lock(&ls_list_mutex);
	if (atomic_read(&ls->ls_refcount) == 0) {
		LASSERT(list_empty(&ls->ls_los_list));
		list_del(&ls->ls_linkage);
		lu_site_purge(env, ls->ls_top_dev.dd_lu_dev.ld_site, ~0);
		lu_device_fini(&ls->ls_top_dev.dd_lu_dev);
		OBD_FREE_PTR(ls);
	}
	mutex_unlock(&ls_list_mutex);
}

/**
 * local file fid generation
 */
int local_object_fid_generate(const struct lu_env *env,
			      struct local_oid_storage *los,
			      struct lu_fid *fid)
{
	LASSERT(los->los_dev);
	LASSERT(los->los_obj);

	/* take next OID */

	/* to make it unique after reboot we store
	 * the latest generated fid atomically with
	 * object creation see local_object_create() */

	mutex_lock(&los->los_id_lock);
	fid->f_seq = los->los_seq;
	fid->f_oid = ++los->los_last_oid;
	fid->f_ver = 0;
	mutex_unlock(&los->los_id_lock);

	return 0;
}

int local_object_declare_create(const struct lu_env *env,
				struct local_oid_storage *los,
				struct dt_object *o, struct lu_attr *attr,
				struct dt_object_format *dof,
				struct thandle *th)
{
	struct dt_thread_info	*dti = dt_info(env);
	int			 rc;

	/* update fid generation file */
	if (los != NULL) {
		LASSERT(dt_object_exists(los->los_obj));
		rc = dt_declare_record_write(env, los->los_obj,
					     sizeof(struct los_ondisk), 0, th);
		if (rc)
			return rc;
	}

	rc = dt_declare_create(env, o, attr, NULL, dof, th);
	if (rc)
		return rc;

	dti->dti_lb.lb_buf = NULL;
	dti->dti_lb.lb_len = sizeof(dti->dti_lma);
	rc = dt_declare_xattr_set(env, o, &dti->dti_lb, XATTR_NAME_LMA, 0, th);

	return rc;
}

int local_object_create(const struct lu_env *env,
			struct local_oid_storage *los,
			struct dt_object *o, struct lu_attr *attr,
			struct dt_object_format *dof, struct thandle *th)
{
	struct dt_thread_info	*dti = dt_info(env);
	__le64			 lastid;
	int			 rc;

	rc = dt_create(env, o, attr, NULL, dof, th);
	if (rc)
		return rc;

	if (los == NULL)
		return rc;

	LASSERT(los->los_obj);
	LASSERT(dt_object_exists(los->los_obj));

	/* many threads can be updated this, serialize
	 * them here to avoid the race where one thread
	 * takes the value first, but writes it last */
	mutex_lock(&los->los_id_lock);

	/* update local oid number on disk so that
	 * we know the last one used after reboot */
	lastid = cpu_to_le64(los->los_last_oid);

	dti->dti_off = 0;
	dti->dti_lb.lb_buf = &lastid;
	dti->dti_lb.lb_len = sizeof(lastid);
	rc = dt_record_write(env, los->los_obj, &dti->dti_lb, &dti->dti_off,
			     th);
	mutex_unlock(&los->los_id_lock);

	return rc;
}

/*
 * Create local named object (file, directory or index) in parent directory.
 */
struct dt_object *__local_file_create(const struct lu_env *env,
				      const struct lu_fid *fid,
				      struct local_oid_storage *los,
				      struct ls_device *ls,
				      struct dt_object *parent,
				      const char *name, struct lu_attr *attr,
				      struct dt_object_format *dof)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	struct thandle		*th;
	int			 rc;

	dto = ls_locate(env, ls, fid);
	if (unlikely(IS_ERR(dto)))
		return dto;

	LASSERT(dto != NULL);
	if (dt_object_exists(dto))
		GOTO(out, rc = -EEXIST);

	th = dt_trans_create(env, ls->ls_osd);
	if (IS_ERR(th))
		GOTO(out, rc = PTR_ERR(th));

	rc = local_object_declare_create(env, los, dto, attr, dof, th);
	if (rc)
		GOTO(trans_stop, rc);

	if (dti->dti_dof.dof_type == DFT_DIR) {
		dt_declare_ref_add(env, dto, th);
		dt_declare_ref_add(env, parent, th);
	}

	rc = dt_declare_insert(env, parent, (void *)fid, (void *)name, th);
	if (rc)
		GOTO(trans_stop, rc);

	rc = dt_trans_start_local(env, ls->ls_osd, th);
	if (rc)
		GOTO(trans_stop, rc);

	dt_write_lock(env, dto, 0);
	if (dt_object_exists(dto))
		GOTO(unlock, rc = 0);

	CDEBUG(D_OTHER, "create new object "DFID"\n",
	       PFID(lu_object_fid(&dto->do_lu)));
	rc = local_object_create(env, los, dto, attr, dof, th);
	if (rc)
		GOTO(unlock, rc);
	LASSERT(dt_object_exists(dto));

	if (dti->dti_dof.dof_type == DFT_DIR) {
		if (!dt_try_as_dir(env, dto))
			GOTO(destroy, rc = -ENOTDIR);
		/* Add "." and ".." for newly created dir */
		rc = dt_insert(env, dto, (void *)fid, (void *)".", th,
			       BYPASS_CAPA, 1);
		if (rc)
			GOTO(destroy, rc);
		dt_ref_add(env, dto, th);
		rc = dt_insert(env, dto, (void *)lu_object_fid(&parent->do_lu),
			       (void *)"..", th, BYPASS_CAPA, 1);
		if (rc)
			GOTO(destroy, rc);
	}

	dt_write_lock(env, parent, 0);
	rc = dt_insert(env, parent, (const struct dt_rec *)fid,
		       (const struct dt_key *)name, th, BYPASS_CAPA, 1);
	if (dti->dti_dof.dof_type == DFT_DIR)
		dt_ref_add(env, parent, th);
	dt_write_unlock(env, parent);
	if (rc)
		GOTO(destroy, rc);
destroy:
	if (rc)
		dt_destroy(env, dto, th);
unlock:
	dt_write_unlock(env, dto);
trans_stop:
	dt_trans_stop(env, ls->ls_osd, th);
out:
	if (rc) {
		lu_object_put_nocache(env, &dto->do_lu);
		dto = ERR_PTR(rc);
	}
	return dto;
}

/*
 * Look up and create (if it does not exist) a local named file or directory in
 * parent directory.
 */
struct dt_object *local_file_find_or_create(const struct lu_env *env,
					    struct local_oid_storage *los,
					    struct dt_object *parent,
					    const char *name, __u32 mode)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	int			 rc;

	LASSERT(parent);

	rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
	if (rc == 0)
		/* name is found, get the object */
		dto = ls_locate(env, dt2ls_dev(los->los_dev), &dti->dti_fid);
	else if (rc != -ENOENT)
		dto = ERR_PTR(rc);
	else {
		rc = local_object_fid_generate(env, los, &dti->dti_fid);
		if (rc < 0) {
			dto = ERR_PTR(rc);
		} else {
			/* create the object */
			dti->dti_attr.la_valid	= LA_MODE;
			dti->dti_attr.la_mode	= mode;
			dti->dti_dof.dof_type	= dt_mode_to_dft(mode & S_IFMT);
			dto = __local_file_create(env, &dti->dti_fid, los,
						  dt2ls_dev(los->los_dev),
						  parent, name, &dti->dti_attr,
						  &dti->dti_dof);
		}
	}
	return dto;
}
EXPORT_SYMBOL(local_file_find_or_create);

struct dt_object *local_file_find_or_create_with_fid(const struct lu_env *env,
						     struct dt_device *dt,
						     const struct lu_fid *fid,
						     struct dt_object *parent,
						     const char *name,
						     __u32 mode)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	int			 rc;

	LASSERT(parent);

	rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
	if (rc == 0) {
		dto = dt_locate(env, dt, &dti->dti_fid);
	} else if (rc != -ENOENT) {
		dto = ERR_PTR(rc);
	} else {
		struct ls_device *ls;

		ls = ls_device_get(dt);
		if (IS_ERR(ls)) {
			dto = ERR_CAST(ls);
		} else {
			/* create the object */
			dti->dti_attr.la_valid	= LA_MODE;
			dti->dti_attr.la_mode	= mode;
			dti->dti_dof.dof_type	= dt_mode_to_dft(mode & S_IFMT);
			dto = __local_file_create(env, fid, NULL, ls, parent,
						  name, &dti->dti_attr,
						  &dti->dti_dof);
			/* ls_device_put() will finalize the ls device, we
			 * have to open the object in other device stack */
			if (!IS_ERR(dto)) {
				dti->dti_fid = dto->do_lu.lo_header->loh_fid;
				lu_object_put_nocache(env, &dto->do_lu);
				dto = dt_locate(env, dt, &dti->dti_fid);
			}
			ls_device_put(env, ls);
		}
	}
	return dto;
}
EXPORT_SYMBOL(local_file_find_or_create_with_fid);

/*
 * Look up and create (if it does not exist) a local named index file in parent
 * directory.
 */
struct dt_object *local_index_find_or_create(const struct lu_env *env,
					     struct local_oid_storage *los,
					     struct dt_object *parent,
					     const char *name, __u32 mode,
					     const struct dt_index_features *ft)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	int			 rc;

	LASSERT(parent);

	rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
	if (rc == 0) {
		/* name is found, get the object */
		dto = ls_locate(env, dt2ls_dev(los->los_dev), &dti->dti_fid);
	} else if (rc != -ENOENT) {
		dto = ERR_PTR(rc);
	} else {
		rc = local_object_fid_generate(env, los, &dti->dti_fid);
		if (rc < 0) {
			dto = ERR_PTR(rc);
		} else {
			/* create the object */
			dti->dti_attr.la_valid		= LA_MODE;
			dti->dti_attr.la_mode		= mode;
			dti->dti_dof.dof_type		= DFT_INDEX;
			dti->dti_dof.u.dof_idx.di_feat	= ft;
			dto = __local_file_create(env, &dti->dti_fid, los,
						  dt2ls_dev(los->los_dev),
						  parent, name, &dti->dti_attr,
						  &dti->dti_dof);
		}
	}
	return dto;

}
EXPORT_SYMBOL(local_index_find_or_create);

struct dt_object *
local_index_find_or_create_with_fid(const struct lu_env *env,
				    struct dt_device *dt,
				    const struct lu_fid *fid,
				    struct dt_object *parent,
				    const char *name, __u32 mode,
				    const struct dt_index_features *ft)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	int			 rc;

	LASSERT(parent);

	rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
	if (rc == 0) {
		/* name is found, get the object */
		if (!lu_fid_eq(fid, &dti->dti_fid))
			dto = ERR_PTR(-EINVAL);
		else
			dto = dt_locate(env, dt, fid);
	} else if (rc != -ENOENT) {
		dto = ERR_PTR(rc);
	} else {
		struct ls_device *ls;

		ls = ls_device_get(dt);
		if (IS_ERR(ls)) {
			dto = ERR_CAST(ls);
		} else {
			/* create the object */
			dti->dti_attr.la_valid		= LA_MODE;
			dti->dti_attr.la_mode		= mode;
			dti->dti_dof.dof_type		= DFT_INDEX;
			dti->dti_dof.u.dof_idx.di_feat  = ft;
			dto = __local_file_create(env, fid, NULL, ls, parent,
						  name, &dti->dti_attr,
						  &dti->dti_dof);
			/* ls_device_put() will finalize the ls device, we
			 * have to open the object in other device stack */
			if (!IS_ERR(dto)) {
				dti->dti_fid = dto->do_lu.lo_header->loh_fid;
				lu_object_put_nocache(env, &dto->do_lu);
				dto = dt_locate(env, dt, &dti->dti_fid);
			}
			ls_device_put(env, ls);
		}
	}
	return dto;
}
EXPORT_SYMBOL(local_index_find_or_create_with_fid);

static int local_object_declare_unlink(const struct lu_env *env,
				       struct dt_device *dt,
				       struct dt_object *p,
				       struct dt_object *c, const char *name,
				       struct thandle *th)
{
	int rc;

	rc = dt_declare_delete(env, p, (const struct dt_key *)name, th);
	if (rc < 0)
		return rc;

	rc = dt_declare_ref_del(env, c, th);
	if (rc < 0)
		return rc;

	return dt_declare_destroy(env, c, th);
}

int local_object_unlink(const struct lu_env *env, struct dt_device *dt,
			struct dt_object *parent, const char *name)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*dto;
	struct thandle		*th;
	int			 rc;

	rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
	if (rc == -ENOENT)
		return 0;
	else if (rc < 0)
		return rc;

	dto = dt_locate(env, dt, &dti->dti_fid);
	if (unlikely(IS_ERR(dto)))
		return PTR_ERR(dto);

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

	rc = local_object_declare_unlink(env, dt, parent, dto, name, th);
	if (rc < 0)
		GOTO(stop, rc);

	rc = dt_trans_start_local(env, dt, th);
	if (rc < 0)
		GOTO(stop, rc);

	dt_write_lock(env, dto, 0);
	rc = dt_delete(env, parent, (struct dt_key *)name, th, BYPASS_CAPA);
	if (rc < 0)
		GOTO(unlock, rc);

	rc = dt_ref_del(env, dto, th);
	if (rc < 0) {
		rc = dt_insert(env, parent,
			       (const struct dt_rec *)&dti->dti_fid,
			       (const struct dt_key *)name, th, BYPASS_CAPA, 1);
		GOTO(unlock, rc);
	}

	rc = dt_destroy(env, dto, th);
unlock:
	dt_write_unlock(env, dto);
stop:
	dt_trans_stop(env, dt, th);
out:
	lu_object_put_nocache(env, &dto->do_lu);
	return rc;
}
EXPORT_SYMBOL(local_object_unlink);

struct local_oid_storage *dt_los_find(struct ls_device *ls, __u64 seq)
{
	struct local_oid_storage *los, *ret = NULL;

	list_for_each_entry(los, &ls->ls_los_list, los_list) {
		if (los->los_seq == seq) {
			atomic_inc(&los->los_refcount);
			ret = los;
			break;
		}
	}
	return ret;
}

void dt_los_put(struct local_oid_storage *los)
{
	if (atomic_dec_and_test(&los->los_refcount))
		/* should never happen, only local_oid_storage_fini should
		 * drop refcount to zero */
		LBUG();
	return;
}

/* after Lustre 2.3 release there may be old file to store last generated FID
 * If such file exists then we have to read its content
 */
int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
			__u64 lastid_seq, __u32 *first_oid, struct ls_device *ls)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct dt_object	*root = NULL;
	struct los_ondisk	 losd;
	struct dt_object	*o = NULL;
	int			 rc = 0;

	rc = dt_root_get(env, dev, &dti->dti_fid);
	if (rc)
		return rc;

	root = ls_locate(env, ls, &dti->dti_fid);
	if (IS_ERR(root))
		return PTR_ERR(root);

	/* find old last_id file */
	snprintf(dti->dti_buf, sizeof(dti->dti_buf), "seq-"LPX64"-lastid",
		 lastid_seq);
	rc = dt_lookup_dir(env, root, dti->dti_buf, &dti->dti_fid);
	lu_object_put_nocache(env, &root->do_lu);
	if (rc == -ENOENT) {
		/* old llog lastid accessed by FID only */
		if (lastid_seq != FID_SEQ_LLOG)
			return 0;
		dti->dti_fid.f_seq = FID_SEQ_LLOG;
		dti->dti_fid.f_oid = 1;
		dti->dti_fid.f_ver = 0;
		o = ls_locate(env, ls, &dti->dti_fid);
		if (IS_ERR(o))
			return PTR_ERR(o);

		if (!dt_object_exists(o)) {
			lu_object_put_nocache(env, &o->do_lu);
			return 0;
		}
		CDEBUG(D_INFO, "Found old llog lastid file\n");
	} else if (rc < 0) {
		return rc;
	} else {
		CDEBUG(D_INFO, "Found old lastid file for sequence "LPX64"\n",
		       lastid_seq);
		o = ls_locate(env, ls, &dti->dti_fid);
		if (IS_ERR(o))
			return PTR_ERR(o);
	}
	/* let's read seq-NNNNNN-lastid file value */
	LASSERT(dt_object_exists(o));
	dti->dti_off = 0;
	dti->dti_lb.lb_buf = &losd;
	dti->dti_lb.lb_len = sizeof(losd);
	dt_read_lock(env, o, 0);
	rc = dt_record_read(env, o, &dti->dti_lb, &dti->dti_off);
	dt_read_unlock(env, o);
	lu_object_put_nocache(env, &o->do_lu);
	if (rc == 0 && le32_to_cpu(losd.lso_magic) != LOS_MAGIC) {
		CERROR("%s: wrong content of seq-"LPX64"-lastid file, magic %x\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq,
		       le32_to_cpu(losd.lso_magic));
		return -EINVAL;
	} else if (rc < 0) {
		CERROR("%s: failed to read seq-"LPX64"-lastid: rc = %d\n",
		       o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq, rc);
		return rc;
	}
	*first_oid = le32_to_cpu(losd.lso_next_oid);
	return rc;
}

/**
 * Initialize local OID storage for required sequence.
 * That may be needed for services that uses local files and requires
 * dynamic OID allocation for them.
 *
 * Per each sequence we have an object with 'first_fid' identificator
 * containing the counter for OIDs of locally created files with that
 * sequence.
 *
 * It is used now by llog subsystem and MGS for NID tables
 *
 * Function gets first_fid to create counter object.
 * All dynamic fids will be generated with the same sequence and incremented
 * OIDs
 *
 * Returned local_oid_storage is in-memory representaion of OID storage
 */
int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
			   const struct lu_fid *first_fid,
			   struct local_oid_storage **los)
{
	struct dt_thread_info	*dti = dt_info(env);
	struct ls_device	*ls;
	obd_id			 lastid;
	struct dt_object	*o = NULL;
	struct thandle		*th;
	__u32			 first_oid = fid_oid(first_fid);
	int			 rc = 0;

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

	mutex_lock(&ls->ls_los_mutex);
	*los = dt_los_find(ls, fid_seq(first_fid));
	if (*los != NULL)
		GOTO(out, rc = 0);

	/* not found, then create */
	OBD_ALLOC_PTR(*los);
	if (*los == NULL)
		GOTO(out, rc = -ENOMEM);

	atomic_set(&(*los)->los_refcount, 1);
	mutex_init(&(*los)->los_id_lock);
	(*los)->los_dev = &ls->ls_top_dev;
	atomic_inc(&ls->ls_refcount);
	list_add(&(*los)->los_list, &ls->ls_los_list);

	/* Use {seq, 0, 0} to create the LAST_ID file for every
	 * sequence.  OIDs start at LUSTRE_FID_INIT_OID.
	 */
	dti->dti_fid.f_seq = fid_seq(first_fid);
	dti->dti_fid.f_oid = LUSTRE_FID_LASTID_OID;
	dti->dti_fid.f_ver = 0;
	o = ls_locate(env, ls, &dti->dti_fid);
	if (IS_ERR(o))
		GOTO(out_los, rc = PTR_ERR(o));

	if (!dt_object_exists(o)) {
		rc = lastid_compat_check(env, dev, fid_seq(first_fid),
					 &first_oid, ls);
		if (rc < 0)
			GOTO(out_los, rc);

		th = dt_trans_create(env, dev);
		if (IS_ERR(th))
			GOTO(out_los, rc = PTR_ERR(th));

		dti->dti_attr.la_valid = LA_MODE | LA_TYPE;
		dti->dti_attr.la_mode = S_IFREG | S_IRUGO | S_IWUSR;
		dti->dti_dof.dof_type = dt_mode_to_dft(S_IFREG);

		rc = dt_declare_create(env, o, &dti->dti_attr, NULL,
				       &dti->dti_dof, th);
		if (rc)
			GOTO(out_trans, rc);

		rc = dt_declare_record_write(env, o, sizeof(lastid), 0, th);
		if (rc)
			GOTO(out_trans, rc);

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

		dt_write_lock(env, o, 0);
		if (dt_object_exists(o))
			GOTO(out_lock, rc = 0);

		rc = dt_create(env, o, &dti->dti_attr, NULL, &dti->dti_dof,
			       th);
		if (rc)
			GOTO(out_lock, rc);

		lastid = cpu_to_le64(first_oid);

		dti->dti_off = 0;
		dti->dti_lb.lb_buf = &lastid;
		dti->dti_lb.lb_len = sizeof(lastid);
		rc = dt_record_write(env, o, &dti->dti_lb, &dti->dti_off, th);
		if (rc)
			GOTO(out_lock, rc);
out_lock:
		dt_write_unlock(env, o);
out_trans:
		dt_trans_stop(env, dev, th);
	} else {
		dti->dti_off = 0;
		dti->dti_lb.lb_buf = &lastid;
		dti->dti_lb.lb_len = sizeof(lastid);
		dt_read_lock(env, o, 0);
		rc = dt_record_read(env, o, &dti->dti_lb, &dti->dti_off);
		dt_read_unlock(env, o);
		if (rc == 0 && le64_to_cpu(lastid) > OBIF_MAX_OID) {
			CERROR("%s: bad oid "LPU64" is read from LAST_ID\n",
			       o->do_lu.lo_dev->ld_obd->obd_name,
			       le64_to_cpu(lastid));
			rc = -EINVAL;
		}
	}
out_los:
	if (rc != 0) {
		list_del(&(*los)->los_list);
		atomic_dec(&ls->ls_refcount);
		OBD_FREE_PTR(*los);
		*los = NULL;
		if (o != NULL && !IS_ERR(o))
			lu_object_put_nocache(env, &o->do_lu);
	} else {
		(*los)->los_seq = fid_seq(first_fid);
		(*los)->los_last_oid = le64_to_cpu(lastid);
		(*los)->los_obj = o;
		/* Read value should not be less than initial one
		 * but possible after upgrade from older fs.
		 * In this case just switch to the first_oid in memory and
		 * it will be updated on disk with first object generated */
		if ((*los)->los_last_oid < first_oid)
			(*los)->los_last_oid = first_oid;
	}
out:
	mutex_unlock(&ls->ls_los_mutex);
	ls_device_put(env, ls);
	return rc;
}
EXPORT_SYMBOL(local_oid_storage_init);

void local_oid_storage_fini(const struct lu_env *env,
			    struct local_oid_storage *los)
{
	struct ls_device *ls;

	if (!atomic_dec_and_test(&los->los_refcount))
		return;

	LASSERT(env);
	LASSERT(los->los_dev);
	ls = dt2ls_dev(los->los_dev);

	mutex_lock(&ls->ls_los_mutex);
	if (atomic_read(&los->los_refcount) == 0) {
		if (los->los_obj)
			lu_object_put_nocache(env, &los->los_obj->do_lu);
		list_del(&los->los_list);
		OBD_FREE_PTR(los);
	}
	mutex_unlock(&ls->ls_los_mutex);
	ls_device_put(env, ls);
}
EXPORT_SYMBOL(local_oid_storage_fini);
