Viewing: lu_object.c

// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2017, Intel Corporation.
 */

/*
 * This file is part of Lustre, http://www.lustre.org/
 *
 * Lustre Object.
 * These are the only exported functions, they provide some generic
 * infrastructure for managing object devices
 *
 * Author: Nikita Danilov <nikita.danilov@sun.com>
 */

#define DEBUG_SUBSYSTEM S_CLASS

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/processor.h>
#include <linux/random.h>
#include <lustre_compat/linux/shrinker.h>
#include <linux/rhashtable.h>

#include <obd_class.h>
#include <obd_support.h>
#include <lustre_disk.h>
#include <lustre_fid.h>
#include <lu_object.h>

#include <lustre_compat.h>

struct lu_site_bkt_data {
	/**
	 * LRU list, updated on each access to object. Protected by
	 * lsb_waitq.lock.
	 *
	 * "Cold" end of LRU is lu_site::ls_lru.next. Accessed object are
	 * moved to the lu_site::ls_lru.prev
	 */
	struct list_head		lsb_lru;

	/** object list for delayed freeding */
	struct list_head		lsb_free;

	/**
	 * Wait-queue signaled when an object in this site is ultimately
	 * destroyed (lu_object_free()) or initialized (lu_object_start()).
	 * It is used by lu_object_find() to wait before re-trying when
	 * object in the process of destruction is found in the hash table;
	 * or wait object to be initialized by the allocator.
	 *
	 * \see htable_lookup().
	 */
	wait_queue_head_t		lsb_waitq;
};

enum {
	LU_CACHE_PERCENT_MAX     = 50,
	LU_CACHE_PERCENT_DEFAULT = 20
};

#define	LU_CACHE_NR_MAX_ADJUST		1024
#define	LU_CACHE_NR_UNLIMITED		-1
#define	LU_CACHE_NR_DEFAULT		LU_CACHE_NR_UNLIMITED

#define	LU_CACHE_NR_MIN			4096
#define	LU_CACHE_NR_MAX			0x80000000UL

/*
 * Max 256 buckets, we don't want too many buckets because:
 * - consume too much memory (currently max 16K)
 * - avoid unbalanced LRU list
 * With few cpus there is little gain from extra buckets, so
 * we treat this as a maximum in lu_site_init().
 */
#define LU_SITE_BKT_BITS    8

static unsigned int lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
module_param(lu_cache_percent, int, 0644);
MODULE_PARM_DESC(lu_cache_percent, "Percentage of memory to be used as lu_object cache");

static long lu_cache_nr = LU_CACHE_NR_DEFAULT;
module_param(lu_cache_nr, long, 0644);
MODULE_PARM_DESC(lu_cache_nr, "Maximum number of objects in lu_object cache");

static void lu_object_free(const struct lu_env *env, struct lu_object *o);
static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx);

static struct delayed_work lu_site_flush;


u32 lu_fid_hash(const void *data, u32 len, u32 seed)
{
	const struct lu_fid *fid = data;

	seed = hash_32(seed ^ fid->f_oid, 32);
	seed ^= hash_64(fid->f_seq, 32);
	return seed;
}
EXPORT_SYMBOL(lu_fid_hash);

static const struct rhashtable_params obj_hash_params = {
	.key_len	= sizeof(struct lu_fid),
	.key_offset	= offsetof(struct lu_object_header, loh_fid),
	.head_offset	= offsetof(struct lu_object_header, loh_hash),
	.hashfn		= lu_fid_hash,
	.automatic_shrinking = true,
};

static inline int lu_bkt_hash(struct lu_site *s, const struct lu_fid *fid)
{
	return lu_fid_hash(fid, sizeof(*fid), s->ls_bkt_seed) &
	       (s->ls_bkt_cnt - 1);
}

wait_queue_head_t *
lu_site_wq_from_fid(struct lu_site *site, struct lu_fid *fid)
{
	struct lu_site_bkt_data *bkt;

	bkt = &site->ls_bkts[lu_bkt_hash(site, fid)];
	return &bkt->lsb_waitq;
}
EXPORT_SYMBOL(lu_site_wq_from_fid);

/**
 * lu_object_put() - Decrease reference counter on object
 * @env: current lustre environment
 * @o: lu object to decrease reference from
 *
 * Decrease reference counter on object. If last reference is freed, return
 * object to the cache, unless lu_object_is_dying(o) holds. In the latter
 * case, free object immediately.
 */
void lu_object_put(const struct lu_env *env, struct lu_object *o)
{
	struct lu_site_bkt_data *bkt;
	struct lu_object_header *top = o->lo_header;
	struct lu_site *site = o->lo_dev->ld_site;
	struct lu_object *orig = o;
	const struct lu_fid *fid = lu_object_fid(o);
	bool free;

	LASSERTF(atomic_read(&top->loh_ref) > 0, "o %p\n", o);
	/*
	 * till we have full fids-on-OST implemented anonymous objects
	 * are possible in OSP. such an object isn't listed in the site
	 * so we should not remove it from the site.
	 */
	if (fid_is_zero(fid)) {
		LASSERT(list_empty(&top->loh_lru));
		if (!atomic_dec_and_test(&top->loh_ref))
			return;
		list_for_each_entry_reverse(o, &top->loh_layers, lo_linkage) {
			if (o->lo_ops->loo_object_release != NULL)
				o->lo_ops->loo_object_release(env, o);
		}
		lu_object_free(env, orig);
		return;
	}

	bkt = &site->ls_bkts[lu_bkt_hash(site, &top->loh_fid)];
	if (atomic_add_unless(&top->loh_ref, -1, 1)) {
still_active:
		/*
		 * At this point the object reference is dropped and lock is
		 * not taken, so lu_object should not be touched because it
		 * can be freed by concurrent thread.
		 *
		 * Somebody may be waiting for this, currently only used for
		 * cl_object, see cl_object_put_last().
		 */
		wake_up(&bkt->lsb_waitq);

		return;
	}

	spin_lock(&bkt->lsb_waitq.lock);
	if (!atomic_dec_and_test(&top->loh_ref)) {
		spin_unlock(&bkt->lsb_waitq.lock);
		goto still_active;
	}

	/*
	 * Refcount is zero, and cannot be incremented without taking the bkt
	 * lock, so object is stable.
	 */

	/*
	 * When last reference is released, iterate over object layers, and
	 * notify them that object is no longer busy.
	 */
	list_for_each_entry_reverse(o, &top->loh_layers, lo_linkage) {
		if (o->lo_ops->loo_object_release != NULL)
			o->lo_ops->loo_object_release(env, o);
	}

	/*
	 * Don't use local 'is_dying' here because if was taken without lock but
	 * here we need the latest actual value of it so check lu_object
	 * directly here.
	 */
	LASSERT(list_empty(&top->loh_lru));
	if (!lu_object_is_dying(top) &&
	    (lu_object_exists(orig) || lu_object_is_cl(orig))) {
		list_add_tail(&top->loh_lru, &bkt->lsb_lru);
		spin_unlock(&bkt->lsb_waitq.lock);
		percpu_counter_inc(&site->ls_lru_len_counter);
		CDEBUG(D_INODE, "Add %p/%p to site lru. bkt: %p\n",
		       orig, top, bkt);
		return;
	}

	/*
	 * If object is dying (will not be cached) then remove it from hash
	 * table (it is already not on the LRU).
	 *
	 * This is done with bucket lock held.  As the only way to acquire first
	 * reference to previously unreferenced object is through hash-table
	 * lookup (lu_object_find()) which takes the lock for first reference,
	 * no race with concurrent object lookup is possible and we can safely
	 * destroy object below.
	 */
	if (!test_and_set_bit(LU_OBJECT_UNHASHED, &top->loh_flags))
		rhashtable_remove_fast(&site->ls_obj_hash, &top->loh_hash,
				       obj_hash_params);

	free = lu_object_is_dfree(top) || !fid_is_norm(fid);
	/* delayed free */
	if (!free)
		list_add_tail(&top->loh_lru, &bkt->lsb_free);

	spin_unlock(&bkt->lsb_waitq.lock);
	/* Object was already removed from hash above, can kill it. */
	if (free)
		lu_object_free(env, orig);
}
EXPORT_SYMBOL(lu_object_put);

/**
 * lu_object_put_nocache() - Put object and don't keep in cache.
 * @env: current lustre environment
 * @o: lu object to decrease reference from
 *
 * Put object and don't keep in cache. This is temporary solution for
 * multi-site objects when its layering is not constant.
 */
void lu_object_put_nocache(const struct lu_env *env, struct lu_object *o)
{
	set_bit(LU_OBJECT_HEARD_BANSHEE, &o->lo_header->loh_flags);
	return lu_object_put(env, o);
}
EXPORT_SYMBOL(lu_object_put_nocache);

/**
 * lu_object_unhash() - Kill the object and take it out of LRU cache.
 * @env: current lustre environment
 * @o: lu object to be killed
 *
 * Currently used by client code for layout change.
 */
void lu_object_unhash(const struct lu_env *env, struct lu_object *o)
{
	struct lu_object_header *top;

	top = o->lo_header;
	set_bit(LU_OBJECT_HEARD_BANSHEE, &top->loh_flags);
	if (!test_and_set_bit(LU_OBJECT_UNHASHED, &top->loh_flags)) {
		struct lu_site *site = o->lo_dev->ld_site;
		struct rhashtable *obj_hash = &site->ls_obj_hash;
		struct lu_site_bkt_data *bkt;

		bkt = &site->ls_bkts[lu_bkt_hash(site, &top->loh_fid)];
		spin_lock(&bkt->lsb_waitq.lock);
		if (!list_empty(&top->loh_lru)) {
			list_del_init(&top->loh_lru);
			percpu_counter_dec(&site->ls_lru_len_counter);
		}
		spin_unlock(&bkt->lsb_waitq.lock);

		rhashtable_remove_fast(obj_hash, &top->loh_hash,
				       obj_hash_params);
	}
}
EXPORT_SYMBOL(lu_object_unhash);

/*
 * Allocate new object.
 *
 * This follows object creation protocol, described in the comment within
 * struct lu_device_operations definition.
 */
static struct lu_object *lu_object_alloc(const struct lu_env *env,
					 struct lu_device *dev,
					 const struct lu_fid *f)
{
	struct lu_object *top;

	/*
	 * Create top-level object slice. This will also create
	 * lu_object_header.
	 */
	top = dev->ld_ops->ldo_object_alloc(env, NULL, dev);
	if (top == NULL)
		return ERR_PTR(-ENOMEM);
	if (IS_ERR(top))
		return top;
	/* The only place where obj fid is assigned. It's constant after this */
	top->lo_header->loh_fid = *f;
	return top;
}

/*
 * Initialize object.
 *
 * This is called after object hash insertion to avoid returning an object with
 * stale attributes.
 */
static int lu_object_start(const struct lu_env *env, struct lu_device *dev,
			   struct lu_object *top,
			   const struct lu_object_conf *conf)
{
	struct lu_object *scan;
	struct list_head *layers;
	unsigned int init_mask = 0;
	unsigned int init_flag;
	int clean;
	int result;

	layers = &top->lo_header->loh_layers;

	do {
		/*
		 * Call ->loo_object_init() repeatedly, until no more new
		 * object slices are created.
		 */
		clean = 1;
		init_flag = 1;
		list_for_each_entry(scan, layers, lo_linkage) {
			if (init_mask & init_flag)
				goto next;
			clean = 0;
			scan->lo_header = top->lo_header;
			result = scan->lo_ops->loo_object_init(env, scan, conf);
			if (result)
				return result;

			init_mask |= init_flag;
next:
			init_flag <<= 1;
		}
	} while (!clean);

	list_for_each_entry_reverse(scan, layers, lo_linkage) {
		if (scan->lo_ops->loo_object_start != NULL) {
			result = scan->lo_ops->loo_object_start(env, scan);
			if (result)
				return result;
		}
	}

	lprocfs_counter_incr(dev->ld_site->ls_stats, LU_SS_CREATED);

	set_bit(LU_OBJECT_INITED, &top->lo_header->loh_flags);

	return 0;
}

/* Free an object. */
static void lu_object_free(const struct lu_env *env, struct lu_object *o)
{
	wait_queue_head_t *wq;
	struct lu_site *site;
	struct lu_object *scan;
	struct list_head *layers;
	LIST_HEAD(splice);

	site = o->lo_dev->ld_site;
	layers = &o->lo_header->loh_layers;
	wq = lu_site_wq_from_fid(site, &o->lo_header->loh_fid);
	/* First call ->loo_object_delete() method to release all resources. */
	list_for_each_entry_reverse(scan, layers, lo_linkage) {
		if (scan->lo_ops->loo_object_delete != NULL)
			scan->lo_ops->loo_object_delete(env, scan);
	}

	/*
	 * Then, splice object layers into stand-alone list, and call
	 * ->loo_object_free() on all layers to free memory. Splice is
	 * necessary, because lu_object_header is freed together with the
	 * top-level slice.
	 */
	list_splice_init(layers, &splice);
	while (!list_empty(&splice)) {
		/*
		 * Free layers in bottom-to-top order, so that object header
		 * lives as long as possible and ->loo_object_free() methods
		 * can look at its contents.
		 */
		o = container_of(splice.prev, struct lu_object, lo_linkage);
		list_del_init(&o->lo_linkage);
		LASSERT(o->lo_ops->loo_object_free != NULL);
		o->lo_ops->loo_object_free(env, o);
	}

	if (waitqueue_active(wq))
		wake_up(wq);
}

/**
 * lu_site_purge_objects() - Free @nr objects from cold end of the site LRU list
 * @env: current lustre environment
 * @s: pointer to lu_site struct (lustre mount)
 * @nr: number of objects to purge (-1 to purge all objects)
 * @canblock: if canblock is 0, then don't block awaiting for another instance
 * of lu_site_purge() to complete
 *
 * Return number of objects purged
 */
int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s,
			  int nr, int canblock)
{
	struct lu_object_header *h;
	struct lu_object_header *temp;
	struct lu_site_bkt_data *bkt;
	LIST_HEAD(dispose);
	int                      did_sth;
	unsigned int		 start = 0;
	int                      count;
	int                      bnr;
	unsigned int             i;

	if (CFS_FAIL_CHECK(OBD_FAIL_OBD_NO_LRU))
		RETURN(0);

	/*
	 * Under LRU list lock, scan LRU list and move unreferenced objects to
	 * the dispose list, removing them from LRU and hash table.
	 */
	if (nr != ~0)
		start = s->ls_purge_start;
	bnr = (nr == ~0) ? -1 : nr / s->ls_bkt_cnt + 1;
again:
	/*
	 * It doesn't make any sense to make purge threads parallel, that can
	 * only bring troubles to us.  See LU-5331.
	 */
	if (canblock != 0)
		mutex_lock(&s->ls_purge_mutex);
	else if (mutex_trylock(&s->ls_purge_mutex) == 0)
		goto out;

	did_sth = 0;
	for (i = start; i < s->ls_bkt_cnt ; i++) {
		count = bnr;
		bkt = &s->ls_bkts[i];
		spin_lock(&bkt->lsb_waitq.lock);

		/* we can sleep with objects free */
		if (canblock)
			list_splice_init(&bkt->lsb_free, &dispose);

		list_for_each_entry_safe(h, temp, &bkt->lsb_lru, loh_lru) {
			struct lu_object *top = lu_object_top(h);
			bool free;

			LASSERT(atomic_read(&h->loh_ref) == 0);

			LINVRNT(lu_bkt_hash(s, &h->loh_fid) == i);

			set_bit(LU_OBJECT_UNHASHED, &h->loh_flags);
			rhashtable_remove_fast(&s->ls_obj_hash, &h->loh_hash,
					       obj_hash_params);

			free = lu_object_is_dfree(top->lo_header) ||
				!fid_is_norm(lu_object_fid(top));
			if (free || canblock)
				list_move(&h->loh_lru, &dispose);
			else
				list_move(&h->loh_lru, &bkt->lsb_free);

			percpu_counter_dec(&s->ls_lru_len_counter);
			if (did_sth == 0)
				did_sth = 1;

			if (nr != ~0 && --nr == 0)
				break;

			if (count > 0 && --count == 0)
				break;

		}
		spin_unlock(&bkt->lsb_waitq.lock);
		cond_resched();
		/*
		 * Free everything on the dispose list. This is safe against
		 * races due to the reasons described in lu_object_put().
		 */
		while ((h = list_first_entry_or_null(&dispose,
						     struct lu_object_header,
						     loh_lru)) != NULL) {
			struct lu_object *top = lu_object_top(h);

			list_del_init(&h->loh_lru);
			lu_object_free(env, top);
			lprocfs_counter_incr(s->ls_stats, LU_SS_LRU_PURGED);
		}

		if (nr == 0)
			break;
	}
	mutex_unlock(&s->ls_purge_mutex);

	/* Final shutdown */
	if (canblock && nr == ~0) {
		wait_event_idle(s->ls_freeq,
			atomic_read(&s->ls_free_done) == 1);
	}

	if (nr != 0 && did_sth && start != 0) {
		start = 0; /* restart from the first bucket */
		goto again;
	}
	/* race on s->ls_purge_start, but nobody cares */
	s->ls_purge_start = i & (s->ls_bkt_cnt - 1);
out:
	return nr;
}
EXPORT_SYMBOL(lu_site_purge_objects);

/*
 * Object printing.
 *
 * Code below has to jump through certain loops to output object description
 * into libcfs_debug_msg-based log. The problem is that lu_object_print()
 * composes object description from strings that are parts of _lines_ of
 * output (i.e., strings that are not terminated by newline). This doesn't fit
 * very well into libcfs_debug_msg() interface that assumes that each message
 * supplied to it is a self-contained output line.
 *
 * To work around this, strings are collected in a temporary buffer
 * (implemented as a value of lu_cdebug_key key), until terminating newline
 * character is detected.
 *
 */

enum {
	/**
	 * Maximal line size.
	 *
	 * XXX overflow is not handled correctly.
	 */
	LU_CDEBUG_LINE = 512
};

struct lu_cdebug_data {
	/* Temporary buffer */
	char lck_area[LU_CDEBUG_LINE];
};

/* context key constructor/destructor: lu_global_key_init, lu_global_key_fini */
LU_KEY_INIT_FINI(lu_global, struct lu_cdebug_data);

/*
 * Key, holding temporary buffer. This key is registered very early by
 * lu_global_init().
 */
static struct lu_context_key lu_global_key = {
	.lct_tags = LCT_MD_THREAD | LCT_DT_THREAD |
		    LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL,
	.lct_init = lu_global_key_init,
	.lct_fini = lu_global_key_fini
};

/* Printer function emitting messages through libcfs_debug_msg(). */
int lu_cdebug_printer(const struct lu_env *env,
		      void *cookie, const char *format, ...)
{
	struct libcfs_debug_msg_data *msgdata = cookie;
	struct lu_cdebug_data        *key;
	int used;
	int complete;
	va_list args;

	va_start(args, format);

	key = lu_context_key_get(&env->le_ctx, &lu_global_key);
	LASSERT(key != NULL);

	used = strlen(key->lck_area);
	complete = format[strlen(format) - 1] == '\n';
	/* Append new chunk to the buffer. */
	vsnprintf(key->lck_area + used,
		  ARRAY_SIZE(key->lck_area) - used, format, args);
	if (complete) {
		if (cfs_cdebug_show(msgdata->msg_mask, msgdata->msg_subsys))
			libcfs_debug_msg(msgdata, "%s", key->lck_area);
		key->lck_area[0] = 0;
	}
	va_end(args);
	return 0;
}
EXPORT_SYMBOL(lu_cdebug_printer);

/* Print object header. */
void lu_object_header_print(const struct lu_env *env, void *cookie,
			    lu_printer_t printer,
			    const struct lu_object_header *hdr)
{
	(*printer)(env, cookie, "header@%p[%#lx, %d, "DFID"%s%s%s]",
		   hdr, hdr->loh_flags, atomic_read(&hdr->loh_ref),
		   PFID(&hdr->loh_fid),
		   test_bit(LU_OBJECT_UNHASHED,
			    &hdr->loh_flags) ? "" : " hash",
		   list_empty(&hdr->loh_lru) ? "" : " lru",
		   hdr->loh_attr & LOHA_EXISTS ? " exist" : "");
}
EXPORT_SYMBOL(lu_object_header_print);

/* Print human readable representation of the \a o to the \a printer. */
void lu_object_print(const struct lu_env *env, void *cookie,
		     lu_printer_t printer, const struct lu_object *o)
{
	static const char ruler[] = "........................................";
	struct lu_object_header *top;
	int depth = 4;

	top = o->lo_header;
	lu_object_header_print(env, cookie, printer, top);
	(*printer)(env, cookie, "{\n");

	list_for_each_entry(o, &top->loh_layers, lo_linkage) {
		/* print '.' \a depth times followed by type name and address */
		(*printer)(env, cookie, "%*.*s%s@%p", depth, depth, ruler,
			   o->lo_dev->ld_type->ldt_name, o);

		if (o->lo_ops->loo_object_print != NULL)
			(*o->lo_ops->loo_object_print)(env, cookie, printer, o);

		(*printer)(env, cookie, "\n");
	}

	(*printer)(env, cookie, "} header@%p\n", top);
}
EXPORT_SYMBOL(lu_object_print);

/* Check object consistency. */
int lu_object_invariant(const struct lu_object *o)
{
	struct lu_object_header *top;

	top = o->lo_header;
	list_for_each_entry(o, &top->loh_layers, lo_linkage) {
		if (o->lo_ops->loo_object_invariant != NULL &&
		    !o->lo_ops->loo_object_invariant(o))
			return 0;
	}
	return 1;
}

/*
 * Limit the lu_object cache to a maximum of lu_cache_nr objects.  Because the
 * calculation for the number of objects to reclaim is not covered by a lock the
 * maximum number of objects is capped by LU_CACHE_MAX_ADJUST.  This ensures
 * that many concurrent threads will not accidentally purge the entire cache.
 */
void lu_site_limit(const struct lu_env *env, struct lu_site *s,
		   u64 nr)
{
	u64 size;

	if (nr == LU_CACHE_NR_UNLIMITED)
		return;

	size = atomic_read(&s->ls_obj_hash.nelems);
	if (size <= nr)
		return;

	lu_site_purge_objects(env, s,
			      min_t(u64, size - nr, LU_CACHE_NR_MAX_ADJUST),
			      0);
}
EXPORT_SYMBOL(lu_site_limit);

static void lu_object_limit(const struct lu_env *env,
			    struct lu_device *dev)
{
	lu_site_limit(env, dev->ld_site, (u64)lu_cache_nr);
}


static struct lu_object *htable_lookup(const struct lu_env *env,
				       struct lu_device *dev,
				       struct lu_site_bkt_data *bkt,
				       const struct lu_fid *f,
				       struct lu_object_header *new)
{
	struct lu_site *s = dev->ld_site;
	struct lu_object_header	*h;

try_again:
	rcu_read_lock();
	if (new)
		h = rhashtable_lookup_get_insert_fast(&s->ls_obj_hash,
						      &new->loh_hash,
						      obj_hash_params);
	else
		h = rhashtable_lookup(&s->ls_obj_hash, f, obj_hash_params);

	if (IS_ERR_OR_NULL(h)) {
		/* Not found */
		if (!new)
			lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_MISS);
		rcu_read_unlock();
		if (PTR_ERR(h) == -ENOMEM) {
			msleep(20);
			goto try_again;
		}
		lu_object_limit(env, dev);
		if (PTR_ERR(h) == -E2BIG)
			goto try_again;

		return ERR_PTR(-ENOENT);
	}

	if (atomic_inc_not_zero(&h->loh_ref)) {
		rcu_read_unlock();
		return lu_object_top(h);
	}

	spin_lock(&bkt->lsb_waitq.lock);
	if (lu_object_is_dying(h) ||
	    test_bit(LU_OBJECT_UNHASHED, &h->loh_flags)) {
		spin_unlock(&bkt->lsb_waitq.lock);
		rcu_read_unlock();
		if (new) {
			/*
			 * Old object might have already been removed, or will
			 * be soon.  We need to insert our new object, so
			 * remove the old one just in case it is still there.
			 */
			rhashtable_remove_fast(&s->ls_obj_hash, &h->loh_hash,
					       obj_hash_params);
			goto try_again;
		}
		lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_MISS);
		return ERR_PTR(-ENOENT);
	}
	/* Now protected by spinlock */
	rcu_read_unlock();

	if (!list_empty(&h->loh_lru)) {
		list_del_init(&h->loh_lru);
		percpu_counter_dec(&s->ls_lru_len_counter);
	}
	atomic_inc(&h->loh_ref);
	spin_unlock(&bkt->lsb_waitq.lock);
	lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_HIT);
	return lu_object_top(h);
}

/**
 * lu_object_find() - Search cache for an object with the fid @f
 * @env: current lustre environment
 * @dev: d
 * @f: globally unique identifier to search object with
 * @conf: Determin if it is a new object create (LOC_F_NEW) or just lookup
 *
 * Additional reference is acquired on the returned object.
 *
 * Return object if found. Otherwise, create new object and insert it into cache
 * and return it. Else ERR_PTR on error
 */
struct lu_object *lu_object_find(const struct lu_env *env,
				 struct lu_device *dev, const struct lu_fid *f,
				 const struct lu_object_conf *conf)
{
	return lu_object_find_at(env, dev->ld_site->ls_top_dev, f, conf);
}
EXPORT_SYMBOL(lu_object_find);

/* Get a 'first' ref to an obj that was found looking through the hash table */
struct lu_object *lu_object_get_first(struct lu_object_header *h,
				      struct lu_device *dev)
{
	struct lu_site *s = dev->ld_site;
	struct lu_object *ret;

	if (IS_ERR_OR_NULL(h) || lu_object_is_dying(h))
		return NULL;

	ret = lu_object_locate(h, dev->ld_type);
	if (!ret)
		return ret;

	if (!atomic_inc_not_zero(&h->loh_ref)) {
		struct lu_site_bkt_data *bkt;

		bkt = &s->ls_bkts[lu_bkt_hash(s, &h->loh_fid)];
		spin_lock(&bkt->lsb_waitq.lock);
		if (!lu_object_is_dying(h) &&
		    !test_bit(LU_OBJECT_UNHASHED, &h->loh_flags))
			atomic_inc(&h->loh_ref);
		else
			ret = NULL;
		spin_unlock(&bkt->lsb_waitq.lock);
	}
	return ret;
}
EXPORT_SYMBOL(lu_object_get_first);

/**
 * lu_object_find_at() - Core logic of lu_object_find*() functions.
 * @env: current lustre environment
 * @dev:  Top-level device for this stack.
 * @f: globally unique identifier to search object with
 * @conf: Determin if it is a new object create (LOC_F_NEW) or just lookup
 *
 * Much like lu_object_find(), but top level device of object is specifically
 * @dev rather than top level device of the site. This interface allows
 * objects of different "stacking" to be created within the same site.
 *
 * Return object if found. Otherwise, create new object and insert it into cache
 * and return it. Else ERR_PTR on error
 */
struct lu_object *lu_object_find_at(const struct lu_env *env,
				    struct lu_device *dev,
				    const struct lu_fid *f,
				    const struct lu_object_conf *conf)
{
	struct lu_object *o;
	struct lu_object *shadow;
	struct lu_site *s;
	struct lu_site_bkt_data *bkt;
	struct rhashtable *hs;
	int rc;

	ENTRY;

	/* FID is from disk or network, zero FID is meaningless, return error
	 * early to avoid assertion in lu_object_put. If a zero FID is wanted,
	 * it should be allocated via lu_object_anon().
	 */
	if (fid_is_zero(f))
		RETURN(ERR_PTR(-EINVAL));

	/*
	 * This uses standard index maintenance protocol:
	 *
	 *     - search index under lock, and return object if found;
	 *     - otherwise, unlock index, allocate new object;
	 *     - lock index and search again;
	 *     - if nothing is found (usual case), insert newly created
	 *       object into index;
	 *     - otherwise (race: other thread inserted object), free
	 *       object just allocated.
	 *     - unlock index;
	 *     - return object.
	 *
	 * For "LOC_F_NEW" case, we are sure the object is new established.
	 * It is unnecessary to perform lookup-alloc-lookup-insert, instead,
	 * just alloc and insert directly.
	 *
	 */
	s  = dev->ld_site;
	hs = &s->ls_obj_hash;

	if (unlikely(CFS_FAIL_PRECHECK(OBD_FAIL_OBD_ZERO_NLINK_RACE)))
		lu_site_purge(env, s, -1);

	bkt = &s->ls_bkts[lu_bkt_hash(s, f)];
	if (!(conf && conf->loc_flags & LOC_F_NEW)) {
		o = htable_lookup(env, dev, bkt, f, NULL);

		if (!IS_ERR(o)) {
			if (likely(lu_object_is_inited(o->lo_header)))
				RETURN(o);

			wait_event_idle(bkt->lsb_waitq,
					lu_object_is_inited(o->lo_header) ||
					lu_object_is_dying(o->lo_header));

			if (lu_object_is_dying(o->lo_header)) {
				lu_object_put(env, o);

				RETURN(ERR_PTR(-ENOENT));
			}

			RETURN(o);
		}

		if (PTR_ERR(o) != -ENOENT)
			RETURN(o);
	}

	/*
	 * Allocate new object, NB, object is unitialized in case object
	 * is changed between allocation and hash insertion, thus the object
	 * with stale attributes is returned.
	 */
	o = lu_object_alloc(env, dev, f);
	if (IS_ERR(o))
		RETURN(o);

	LASSERT(lu_fid_eq(lu_object_fid(o), f));

	CFS_RACE_WAIT(OBD_FAIL_OBD_ZERO_NLINK_RACE);

	if (conf && conf->loc_flags & LOC_F_NEW) {
		int status = rhashtable_insert_fast(hs, &o->lo_header->loh_hash,
						    obj_hash_params);
		if (status)
			/* Strange error - go the slow way */
			shadow = htable_lookup(env, dev, bkt, f, o->lo_header);
		else
			shadow = ERR_PTR(-ENOENT);
	} else {
		shadow = htable_lookup(env, dev, bkt, f, o->lo_header);
	}
	if (likely(PTR_ERR(shadow) == -ENOENT)) {
		/*
		 * The new object has been successfully inserted.
		 *
		 * This may result in rather complicated operations, including
		 * fld queries, inode loading, etc.
		 */
		rc = lu_object_start(env, dev, o, conf);
		if (rc) {
			lu_object_put_nocache(env, o);
			RETURN(ERR_PTR(rc));
		}

		wake_up(&bkt->lsb_waitq);

		lu_object_limit(env, dev);

		RETURN(o);
	}

	lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_RACE);
	lu_object_free(env, o);

	if (!(conf && conf->loc_flags & LOC_F_NEW) &&
	    !IS_ERR(shadow) &&
	    !lu_object_is_inited(shadow->lo_header)) {
		wait_event_idle(bkt->lsb_waitq,
				lu_object_is_inited(shadow->lo_header) ||
				lu_object_is_dying(shadow->lo_header));

		if (lu_object_is_dying(shadow->lo_header)) {
			lu_object_put(env, shadow);

			RETURN(ERR_PTR(-ENOENT));
		}
	}

	RETURN(shadow);
}
EXPORT_SYMBOL(lu_object_find_at);

/**
 * lu_object_find_slice() - Find object with given fid
 * @env: current lustre environment
 * @dev:  Top-level device for this stack.
 * @f: globally unique identifier to search object with
 * @conf: Determin if it is a new object create (LOC_F_NEW) or just lookup
 *
 * Return slice belonging to given device on success
 */
struct lu_object *lu_object_find_slice(const struct lu_env *env,
				       struct lu_device *dev,
				       const struct lu_fid *f,
				       const struct lu_object_conf *conf)
{
	struct lu_object *top;
	struct lu_object *obj;

	top = lu_object_find(env, dev, f, conf);
	if (IS_ERR(top))
		return top;

	obj = lu_object_locate(top->lo_header, dev->ld_type);
	if (unlikely(obj == NULL)) {
		lu_object_put(env, top);
		obj = ERR_PTR(-ENOENT);
	}

	return obj;
}
EXPORT_SYMBOL(lu_object_find_slice);

int lu_device_type_init(struct lu_device_type *ldt)
{
	int result = 0;

	atomic_set(&ldt->ldt_device_nr, 0);
	if (ldt->ldt_ops->ldto_init)
		result = ldt->ldt_ops->ldto_init(ldt);

	return result;
}
EXPORT_SYMBOL(lu_device_type_init);

void lu_device_type_fini(struct lu_device_type *ldt)
{
	if (ldt->ldt_ops->ldto_fini)
		ldt->ldt_ops->ldto_fini(ldt);
}
EXPORT_SYMBOL(lu_device_type_fini);

/* Global list of all sites on this node */
static LIST_HEAD(lu_sites);
static DECLARE_RWSEM(lu_sites_guard);

/* Global environment used by site shrinker. */
static struct lu_env lu_shrink_env;

static struct lu_env lu_free_env;


struct lu_site_print_arg {
	struct lu_env   *lsp_env;
	void            *lsp_cookie;
	lu_printer_t     lsp_printer;
};

static void
lu_site_obj_print(struct lu_object_header *h, struct lu_site_print_arg *arg)
{
	if (!list_empty(&h->loh_layers)) {
		const struct lu_object *o;

		o = lu_object_top(h);
		lu_object_print(arg->lsp_env, arg->lsp_cookie,
				arg->lsp_printer, o);
	} else {
		lu_object_header_print(arg->lsp_env, arg->lsp_cookie,
				       arg->lsp_printer, h);
	}
}

/* Print all objects in \a s. */
void lu_site_print(const struct lu_env *env, struct lu_site *s, atomic_t *ref,
		   int msg_flag, lu_printer_t printer)
{
	struct lu_site_print_arg arg = {
		.lsp_env     = (struct lu_env *)env,
		.lsp_printer = printer,
	};
	struct rhashtable_iter iter;
	struct lu_object_header *h;

	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, msg_flag, NULL);

	if (!s || !atomic_read(ref))
		return;

	arg.lsp_cookie = (void *)&msgdata;

	rhashtable_walk_enter(&s->ls_obj_hash, &iter);
	rhashtable_walk_start(&iter);
	while ((h = rhashtable_walk_next(&iter)) != NULL) {
		if (IS_ERR(h))
			continue;
		lu_site_obj_print(h, &arg);
	}
	rhashtable_walk_stop(&iter);
	rhashtable_walk_exit(&iter);
}
EXPORT_SYMBOL(lu_site_print);

/* Return desired hash table order. */
static void lu_htable_limits(struct lu_device *top)
{
	unsigned long cache_size;

	/*
	 * Calculate hash table size, assuming that we want reasonable
	 * performance when 20% of total memory is occupied by cache of
	 * lu_objects.
	 *
	 * Size of lu_object is (arbitrary) taken as 1K (together with inode).
	 */
	cache_size = compat_totalram_pages();

#if BITS_PER_LONG == 32
	/* limit hashtable size for lowmem systems to low RAM */
	if (cache_size > 1 << (30 - PAGE_SHIFT))
		cache_size = 1 << (30 - PAGE_SHIFT) * 3 / 4;
#endif

	/* clear off unreasonable cache setting. */
	if (lu_cache_percent == 0 || lu_cache_percent > LU_CACHE_PERCENT_MAX) {
		CWARN("obdclass: invalid lu_cache_percent: %u, it must be in the range of (0, %u]. Will use default value: %u.\n",
		      lu_cache_percent, LU_CACHE_PERCENT_MAX,
		      LU_CACHE_PERCENT_DEFAULT);

		lu_cache_percent = LU_CACHE_PERCENT_DEFAULT;
	}
	cache_size = cache_size / 100 * lu_cache_percent *
		(PAGE_SIZE / 1024);

	lu_cache_nr = clamp_t(typeof(cache_size), cache_size,
			      LU_CACHE_NR_MIN, LU_CACHE_NR_MAX);
}

void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d)
{
	spin_lock(&s->ls_ld_lock);
	if (list_empty(&d->ld_linkage))
		list_add(&d->ld_linkage, &s->ls_ld_linkage);
	spin_unlock(&s->ls_ld_lock);
}
EXPORT_SYMBOL(lu_dev_add_linkage);

void lu_dev_del_linkage(struct lu_site *s, struct lu_device *d)
{
	spin_lock(&s->ls_ld_lock);
	list_del_init(&d->ld_linkage);
	spin_unlock(&s->ls_ld_lock);
}
EXPORT_SYMBOL(lu_dev_del_linkage);

/* Initialize site \a s, with \a d as the top level device.  */
int lu_site_init(struct lu_site *s, struct lu_device *top)
{
	struct lu_site_bkt_data *bkt;
	unsigned int i;
	int rc;

	ENTRY;

	memset(s, 0, sizeof(*s));
	mutex_init(&s->ls_purge_mutex);
	lu_htable_limits(top);

	rc = percpu_counter_init(&s->ls_lru_len_counter, 0, GFP_NOFS);
	if (rc)
		return -ENOMEM;

	if (rhashtable_init(&s->ls_obj_hash, &obj_hash_params) != 0) {
		CERROR("failed to create lu_site hash\n");
		return -ENOMEM;
	}

	s->ls_bkt_seed = get_random_u32();
	s->ls_bkt_cnt = max_t(long, 1 << LU_SITE_BKT_BITS,
			      2 * num_possible_cpus());
	s->ls_bkt_cnt = roundup_pow_of_two(s->ls_bkt_cnt);
	OBD_ALLOC_PTR_ARRAY_LARGE(s->ls_bkts, s->ls_bkt_cnt);
	if (!s->ls_bkts) {
		rhashtable_destroy(&s->ls_obj_hash);
		s->ls_bkts = NULL;
		return -ENOMEM;
	}

	for (i = 0; i < s->ls_bkt_cnt; i++) {
		bkt = &s->ls_bkts[i];
		INIT_LIST_HEAD(&bkt->lsb_lru);
		INIT_LIST_HEAD(&bkt->lsb_free);
		init_waitqueue_head(&bkt->lsb_waitq);
	}

	s->ls_stats = lprocfs_stats_alloc(LU_SS_LAST_STAT, 0);
	if (s->ls_stats == NULL) {
		OBD_FREE_PTR_ARRAY_LARGE(s->ls_bkts, s->ls_bkt_cnt);
		s->ls_bkts = NULL;
		rhashtable_destroy(&s->ls_obj_hash);
		return -ENOMEM;
	}

	lprocfs_counter_init(s->ls_stats, LU_SS_CREATED, 0, "created");
	lprocfs_counter_init(s->ls_stats, LU_SS_CACHE_HIT, 0, "cache_hit");
	lprocfs_counter_init(s->ls_stats, LU_SS_CACHE_MISS, 0, "cache_miss");
	lprocfs_counter_init(s->ls_stats, LU_SS_CACHE_RACE, 0, "cache_race");
	lprocfs_counter_init(s->ls_stats, LU_SS_CACHE_DEATH_RACE,
			     0, "cache_death_race");
	lprocfs_counter_init(s->ls_stats, LU_SS_LRU_PURGED, 0, "lru_purged");

	INIT_LIST_HEAD(&s->ls_linkage);
	s->ls_top_dev = top;
	top->ld_site = s;
	lu_device_get(top);

	INIT_LIST_HEAD(&s->ls_ld_linkage);
	spin_lock_init(&s->ls_ld_lock);

	atomic_set(&s->ls_free_done, 1);
	init_waitqueue_head(&s->ls_freeq);

	lu_dev_add_linkage(s, top);

	RETURN(0);
}
EXPORT_SYMBOL(lu_site_init);

/* Finalize \a s and release its resources. */
void lu_site_fini(struct lu_site *s)
{
	down_write(&lu_sites_guard);
	list_del_init(&s->ls_linkage);
	up_write(&lu_sites_guard);

	percpu_counter_destroy(&s->ls_lru_len_counter);

	if (s->ls_bkts) {
		rhashtable_destroy(&s->ls_obj_hash);
		OBD_FREE_PTR_ARRAY_LARGE(s->ls_bkts, s->ls_bkt_cnt);
		s->ls_bkts = NULL;
	}

	if (s->ls_top_dev != NULL) {
		s->ls_top_dev->ld_site = NULL;
		lu_device_put(s->ls_top_dev);
		s->ls_top_dev = NULL;
	}

	if (s->ls_stats != NULL)
		lprocfs_stats_free(&s->ls_stats);
}
EXPORT_SYMBOL(lu_site_fini);

/* Called when initialization of stack for this site is completed. */
int lu_site_init_finish(struct lu_site *s)
{
	int result;

	down_write(&lu_sites_guard);
	result = lu_context_refill(&lu_shrink_env.le_ctx);
	if (result == 0)
		result = lu_context_refill(&lu_free_env.le_ctx);
	if (result == 0)
		list_add(&s->ls_linkage, &lu_sites);
	up_write(&lu_sites_guard);

	return result;
}
EXPORT_SYMBOL(lu_site_init_finish);

/* Acquire additional reference on device \a d */
void lu_device_get(struct lu_device *d)
{
	atomic_inc(&d->ld_ref);
}
EXPORT_SYMBOL(lu_device_get);

/* Release reference on device \a d. */
void lu_device_put(struct lu_device *d)
{
	LASSERT(atomic_read(&d->ld_ref) > 0);
	atomic_dec(&d->ld_ref);
}
EXPORT_SYMBOL(lu_device_put);

enum { /* Maximal number of tld slots. */
	LU_CONTEXT_KEY_NR = 40
};
static struct lu_context_key *lu_keys[LU_CONTEXT_KEY_NR] = { NULL, };
static DECLARE_RWSEM(lu_key_initing);

/* Initialize device \a d of type \a t. */
int lu_device_init(struct lu_device *d, struct lu_device_type *t)
{
	if (atomic_add_unless(&t->ldt_device_nr, 1, 0) == 0) {
		down_write(&lu_key_initing);
		if (t->ldt_ops->ldto_start &&
		    atomic_read(&t->ldt_device_nr) == 0)
			t->ldt_ops->ldto_start(t);
		atomic_inc(&t->ldt_device_nr);
		up_write(&lu_key_initing);
	}

	memset(d, 0, sizeof(*d));
	d->ld_type = t;
	INIT_LIST_HEAD(&d->ld_linkage);

	return 0;
}
EXPORT_SYMBOL(lu_device_init);

/* Finalize device \a d. */
void lu_device_fini(struct lu_device *d)
{
	struct lu_device_type *t = d->ld_type;

	if (d->ld_obd != NULL) {
		d->ld_obd->obd_lu_dev = NULL;
		d->ld_obd = NULL;
	}

	LASSERTF(atomic_read(&d->ld_ref) == 0,
		 "Refcount is %u\n", atomic_read(&d->ld_ref));
	LASSERT(atomic_read(&t->ldt_device_nr) > 0);

	if (atomic_dec_and_test(&t->ldt_device_nr) &&
	    t->ldt_ops->ldto_stop != NULL)
		t->ldt_ops->ldto_stop(t);
}
EXPORT_SYMBOL(lu_device_fini);

/* Initialize obj o that is part of compound obj h and was created by dev d */
int lu_object_init(struct lu_object *o, struct lu_object_header *h,
		   struct lu_device *d)
{
	memset(o, 0, sizeof(*o));
	o->lo_header = h;
	o->lo_dev = d;
	lu_device_get(d);
	INIT_LIST_HEAD(&o->lo_linkage);

	return 0;
}
EXPORT_SYMBOL(lu_object_init);

/* Finalize object and release its resources. */
void lu_object_fini(struct lu_object *o)
{
	struct lu_device *dev = o->lo_dev;

	LASSERT(list_empty(&o->lo_linkage));

	if (dev != NULL) {
		lu_device_put(dev);
		o->lo_dev = NULL;
	}
}
EXPORT_SYMBOL(lu_object_fini);

/**
 * lu_object_add_top() - Add object @o as first layer of compound object @h
 * @h: compound object where object @o will be added
 * @o: object to be added
 *
 * This is typically called by the ->ldo_object_alloc() method of top-level
 * device.
 */
void lu_object_add_top(struct lu_object_header *h, struct lu_object *o)
{
	list_move(&o->lo_linkage, &h->loh_layers);
}
EXPORT_SYMBOL(lu_object_add_top);

/**
 * lu_object_add() - Add obj @o as a layer of compound obj, going after @before.
 * @before: layer to add object @o
 * @o: object to add
 *
 * This is typically called by the ->ldo_object_alloc() method of @before.lo_dev
 */
void lu_object_add(struct lu_object *before, struct lu_object *o)
{
	list_move(&o->lo_linkage, &before->lo_linkage);
}
EXPORT_SYMBOL(lu_object_add);

/* Initialize compound object. */
int lu_object_header_init(struct lu_object_header *h)
{
	memset(h, 0, sizeof(*h));
	atomic_set(&h->loh_ref, 1);
	INIT_LIST_HEAD(&h->loh_lru);
	INIT_LIST_HEAD(&h->loh_layers);
	return 0;
}
EXPORT_SYMBOL(lu_object_header_init);

/* Finalize compound object. */
void lu_object_header_fini(struct lu_object_header *h)
{
	LASSERT(list_empty(&h->loh_layers));
	LASSERT(list_empty(&h->loh_lru));
}
EXPORT_SYMBOL(lu_object_header_fini);

/* Free lu_object_header with proper RCU handling */
void lu_object_header_free(struct lu_object_header *h)
{
	lu_object_header_fini(h);
	OBD_FREE_RCU(h, sizeof(*h), loh_rcu);
}
EXPORT_SYMBOL(lu_object_header_free);

/**
 * lu_object_locate() - For compound obj, find its slice, corresponding to the
 * device type dtype
 * @h: compound object to be search
 * @dtype: type of object/layer we want to find
 *
 * Return pointer to lu_object on success or NULL
 */
struct lu_object *lu_object_locate(struct lu_object_header *h,
				   const struct lu_device_type *dtype)
{
	struct lu_object *o;

	list_for_each_entry(o, &h->loh_layers, lo_linkage) {
		if (o->lo_dev->ld_type == dtype)
			return o;
	}
	return NULL;
}
EXPORT_SYMBOL(lu_object_locate);

/**
 * lu_stack_fini() - Finalize and free devices in the device stack.
 * @env: current lustre environment
 * @top:  Top-level device for this stack.
 *
 * Finalize device stack by purging object cache, and calling
 * lu_device_type_operations::ldto_device_fini() and
 * lu_device_type_operations::ldto_device_free() on all devices in the stack.
 */
void lu_stack_fini(const struct lu_env *env, struct lu_device *top)
{
	struct lu_site   *site = top->ld_site;
	struct lu_device *scan;
	struct lu_device *next;

	lu_site_purge(env, site, ~0);
	for (scan = top; scan != NULL; scan = next) {
		if (strcmp(scan->ld_type->ldt_name, LUSTRE_MDC_NAME) == 0)
			next = NULL;
		else if (strcmp(scan->ld_type->ldt_name, LUSTRE_OSC_NAME) == 0)
			next = NULL;
		else
			next = ldto_device_fini(env, scan);

		lu_device_put(scan);
	}

	/* purge again. */
	lu_site_purge(env, site, ~0);

	for (scan = top; scan != NULL; scan = next) {
		if (strcmp(scan->ld_type->ldt_name, LUSTRE_MDC_NAME) == 0)
			break;

		if (strcmp(scan->ld_type->ldt_name, LUSTRE_OSC_NAME) == 0)
			break;

		if (strcmp(scan->ld_type->ldt_name, LUSTRE_LOV_NAME) == 0)
			break;

		next = ldto_device_free(env, scan);
	}
}
EXPORT_SYMBOL(lu_stack_fini);

/*
 * Global counter incremented whenever key is registered, unregistered,
 * revived or quiesced. This is used to void unnecessary calls to
 * lu_context_refill(). No locking is provided, as initialization and shutdown
 * are supposed to be externally serialized.
 */
static atomic_t key_set_version = ATOMIC_INIT(0);

/* Register new key. */
int lu_context_key_register(struct lu_context_key *key)
{
	int result;
	unsigned int i;

	LASSERT(key->lct_init != NULL);
	LASSERT(key->lct_fini != NULL);
	LASSERT(key->lct_tags != 0);
	result = -ENFILE;
	atomic_set(&key->lct_used, 1);
	for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
		if (lu_keys[i])
			continue;
		key->lct_index = i;

#ifdef MODULE
		LASSERT(key->lct_owner);
		if (strncmp("osd_", module_name(key->lct_owner), 4) == 0)
			CFS_RACE_WAIT(OBD_FAIL_OBD_SETUP);
#endif

		if (cmpxchg(&lu_keys[i], NULL, key) != NULL)
			continue;

		result = 0;
		atomic_inc(&key_set_version);
		break;
	}
	if (result) {
		atomic_set(&key->lct_used, 0);
	}
	return result;
}
EXPORT_SYMBOL(lu_context_key_register);

static void key_fini(struct lu_context *ctx, int index)
{
	if (ctx->lc_value != NULL && ctx->lc_value[index] != NULL) {
		struct lu_context_key *key;

		key = lu_keys[index];
		LASSERT(key != NULL);
		LASSERT(key->lct_fini != NULL);
		LASSERT(atomic_read(&key->lct_used) > 0);

		key->lct_fini(ctx, key, ctx->lc_value[index]);
		if (atomic_dec_and_test(&key->lct_used))
			wake_up_var(&key->lct_used);

#ifdef MODULE
		LASSERT(key->lct_owner);
		if ((ctx->lc_tags & LCT_NOREF) == 0) {
			LINVRNT(module_refcount(key->lct_owner) > 0);
			module_put(key->lct_owner);
		}
#endif
		ctx->lc_value[index] = NULL;
	}
}

/* Deregister key. */
void lu_context_key_degister(struct lu_context_key *key)
{
	LASSERT(atomic_read(&key->lct_used) >= 1);
	LINVRNT(0 <= key->lct_index && key->lct_index < ARRAY_SIZE(lu_keys));

	lu_context_key_quiesce(NULL, key);

	key_fini(&lu_shrink_env.le_ctx, key->lct_index);
	key_fini(&lu_free_env.le_ctx, key->lct_index);

	/**
	 * Wait until all transient contexts referencing this key have
	 * run lu_context_key::lct_fini() method.
	 */
	atomic_dec(&key->lct_used);
	wait_var_event(&key->lct_used, atomic_read(&key->lct_used) == 0);

	smp_store_release(&lu_keys[key->lct_index], NULL); /* release key */
}
EXPORT_SYMBOL(lu_context_key_degister);

/*
 * Register a number of keys. This has to be called after all keys have been
 * initialized by a call to LU_CONTEXT_KEY_INIT().
 */
int lu_context_key_register_many(struct lu_context_key *k, ...)
{
	struct lu_context_key *key = k;
	va_list args;
	int result;

	va_start(args, k);
	do {
		result = lu_context_key_register(key);
		if (result)
			break;
		key = va_arg(args, struct lu_context_key *);
	} while (key != NULL);
	va_end(args);

	if (result != 0) {
		va_start(args, k);
		while (k != key) {
			lu_context_key_degister(k);
			k = va_arg(args, struct lu_context_key *);
		}
		va_end(args);
	}

	return result;
}
EXPORT_SYMBOL(lu_context_key_register_many);

/*
 * De-register a number of keys. This is a dual to
 * lu_context_key_register_many().
 */
void lu_context_key_degister_many(struct lu_context_key *k, ...)
{
	va_list args;

	va_start(args, k);
	do {
		lu_context_key_degister(k);
		k = va_arg(args, struct lu_context_key*);
	} while (k != NULL);
	va_end(args);
}
EXPORT_SYMBOL(lu_context_key_degister_many);

/* Revive a number of keys. */
void lu_context_key_revive_many(struct lu_context_key *k, ...)
{
	va_list args;

	va_start(args, k);
	do {
		lu_context_key_revive(k);
		k = va_arg(args, struct lu_context_key*);
	} while (k != NULL);
	va_end(args);
}
EXPORT_SYMBOL(lu_context_key_revive_many);

/* Quiescent a number of keys. */
void lu_context_key_quiesce_many(struct lu_device_type *t,
				 struct lu_context_key *k, ...)
{
	va_list args;

	va_start(args, k);
	do {
		lu_context_key_quiesce(t, k);
		k = va_arg(args, struct lu_context_key*);
	} while (k != NULL);
	va_end(args);
}
EXPORT_SYMBOL(lu_context_key_quiesce_many);

/* Return value associated with key \a key in context \a ctx. */
void *lu_context_key_get(const struct lu_context *ctx,
			 const struct lu_context_key *key)
{
	LINVRNT(ctx->lc_state == LCS_ENTERED);
	LINVRNT(0 <= key->lct_index && key->lct_index < ARRAY_SIZE(lu_keys));
	LASSERT(lu_keys[key->lct_index] == key);
	WARN(!(ctx->lc_tags & LCT_CL_INIT),
	     "Probable access of uninitialized array lc_tags:%x\n",
	      ctx->lc_tags);
	return ctx->lc_value[key->lct_index];
}
EXPORT_SYMBOL(lu_context_key_get);

/*
 * List of remembered contexts.
 */

/* lu_context tracked for lifetime (until module unload) */
static LIST_HEAD(lu_context_remembered);
/* serialization for above */
static DEFINE_SPINLOCK(lu_context_remembered_guard);

/*
 * Destroy \a key in all remembered contexts. This is used to destroy key
 * values in "shared" contexts (like service threads), when a module owning
 * the key is about to be unloaded.
 */
void lu_context_key_quiesce(struct lu_device_type *t,
			    struct lu_context_key *key)
{
	struct lu_context *ctx;

	if (key->lct_tags & LCT_QUIESCENT)
		return;
	/*
	 * The write-lock on lu_key_initing will ensure that any
	 * keys_fill() which didn't see LCT_QUIESCENT will have
	 * finished before we call key_fini().
	 */
	down_write(&lu_key_initing);
	if (!(key->lct_tags & LCT_QUIESCENT)) {
		if (t == NULL || atomic_read(&t->ldt_device_nr) == 0)
			key->lct_tags |= LCT_QUIESCENT;
		up_write(&lu_key_initing);

		spin_lock(&lu_context_remembered_guard);
		list_for_each_entry(ctx, &lu_context_remembered, lc_remember) {
			spin_until_cond(READ_ONCE(ctx->lc_state) !=
					LCS_LEAVING);
			key_fini(ctx, key->lct_index);
		}
		spin_unlock(&lu_context_remembered_guard);

		return;
	}
	up_write(&lu_key_initing);
}

void lu_context_key_revive(struct lu_context_key *key)
{
	key->lct_tags &= ~LCT_QUIESCENT;
	atomic_inc(&key_set_version);
}

static void keys_fini(struct lu_context *ctx)
{
	unsigned int i;

	if (ctx->lc_value == NULL)
		return;

	ctx->lc_tags &= ~LCT_CL_INIT;
	for (i = 0; i < ARRAY_SIZE(lu_keys); ++i)
		key_fini(ctx, i);

	OBD_FREE_PTR_ARRAY(ctx->lc_value, ARRAY_SIZE(lu_keys));
	ctx->lc_value = NULL;
}

static int keys_fill(struct lu_context *ctx)
{
	unsigned int i;
	int rc = 0;

	/*
	 * A serialisation with lu_context_key_quiesce() is needed, to
	 * ensure we see LCT_QUIESCENT and don't allocate a new value
	 * after it freed one.  The rwsem provides this.  As down_read()
	 * does optimistic spinning while the writer is active, this is
	 * unlikely to ever sleep.
	 */
	down_read(&lu_key_initing);
	ctx->lc_version = atomic_read(&key_set_version);

	LINVRNT(ctx->lc_value);
	for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
		struct lu_context_key *key;

		key = lu_keys[i];
		if (!ctx->lc_value[i] && key &&
		    (key->lct_tags & ctx->lc_tags) &&
		    /*
		     * Don't create values for a LCT_QUIESCENT key, as this
		     * will pin module owning a key.
		     */
		    !(key->lct_tags & LCT_QUIESCENT)) {
			void *value;

			LINVRNT(key->lct_init != NULL);
			LINVRNT(key->lct_index == i);

#ifdef MODULE
			LASSERT(key->lct_owner);
			if (!(ctx->lc_tags & LCT_NOREF) &&
			    try_module_get(key->lct_owner) == 0) {
				/* module is unloading, skip this key */
				continue;
			}
#endif

			value = key->lct_init(ctx, key);
			if (unlikely(IS_ERR(value))) {
				rc = PTR_ERR(value);
				break;
			}

			atomic_inc(&key->lct_used);
			/*
			 * This is the only place in the code, where an
			 * element of ctx->lc_value[] array is set to non-NULL
			 * value.
			 */
			ctx->lc_value[i] = value;
			if (key->lct_exit != NULL)
				ctx->lc_tags |= LCT_HAS_EXIT;
		}
	}

	if (rc == 0)
		ctx->lc_tags |= LCT_CL_INIT;

	up_read(&lu_key_initing);
	return rc;
}

static int keys_init(struct lu_context *ctx)
{
	OBD_ALLOC_PTR_ARRAY(ctx->lc_value, ARRAY_SIZE(lu_keys));
	if (likely(ctx->lc_value != NULL))
		return keys_fill(ctx);

	return -ENOMEM;
}

/* Initialize context data-structure. Create values for all keys. */
int lu_context_init(struct lu_context *ctx, __u32 tags)
{
	int	rc;

	memset(ctx, 0, sizeof(*ctx));
	ctx->lc_state = LCS_INITIALIZED;
	ctx->lc_tags = tags;
	if (tags & LCT_REMEMBER) {
		spin_lock(&lu_context_remembered_guard);
		list_add(&ctx->lc_remember, &lu_context_remembered);
		spin_unlock(&lu_context_remembered_guard);
	} else {
		INIT_LIST_HEAD(&ctx->lc_remember);
	}

	rc = keys_init(ctx);
	if (rc != 0)
		lu_context_fini(ctx);

	return rc;
}
EXPORT_SYMBOL(lu_context_init);

/* Finalize context data-structure. Destroy key values. */
void lu_context_fini(struct lu_context *ctx)
{
	LINVRNT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT);
	ctx->lc_state = LCS_FINALIZED;

	if ((ctx->lc_tags & LCT_REMEMBER) == 0) {
		LASSERT(list_empty(&ctx->lc_remember));
	} else {
		/* could race with key degister */
		spin_lock(&lu_context_remembered_guard);
		list_del_init(&ctx->lc_remember);
		spin_unlock(&lu_context_remembered_guard);
	}
	keys_fini(ctx);
}
EXPORT_SYMBOL(lu_context_fini);

/* Called before entering context. */
void lu_context_enter(struct lu_context *ctx)
{
	LINVRNT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT);
	ctx->lc_state = LCS_ENTERED;
}
EXPORT_SYMBOL(lu_context_enter);

/* Called after exiting from \a ctx */
void lu_context_exit(struct lu_context *ctx)
{
	unsigned int i;

	LINVRNT(ctx->lc_state == LCS_ENTERED);
	/*
	 * Disable preempt to ensure we get a warning if
	 * any lct_exit ever tries to sleep.  That would hurt
	 * lu_context_key_quiesce() which spins waiting for us.
	 * This also ensure we aren't preempted while the state
	 * is LCS_LEAVING, as that too would cause problems for
	 * lu_context_key_quiesce().
	 */
	preempt_disable();
	/*
	 * Ensure lu_context_key_quiesce() sees LCS_LEAVING
	 * or we see LCT_QUIESCENT
	 */
	smp_store_mb(ctx->lc_state, LCS_LEAVING);
	if (ctx->lc_tags & LCT_HAS_EXIT && ctx->lc_value) {
		for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
			struct lu_context_key *key;

			key = lu_keys[i];
			if (ctx->lc_value[i] &&
			    !(key->lct_tags & LCT_QUIESCENT) &&
			    key->lct_exit)
				key->lct_exit(ctx, key, ctx->lc_value[i]);
		}
	}

	smp_store_release(&ctx->lc_state, LCS_LEFT); /* release ownership  */
	preempt_enable();
}
EXPORT_SYMBOL(lu_context_exit);

/*
 * Allocate for context all missing keys that were registered after context
 * creation. key_set_version is only changed in rare cases when modules
 * are loaded and removed.
 */
int lu_context_refill(struct lu_context *ctx)
{
	if (likely(ctx->lc_version == atomic_read(&key_set_version)))
		return 0;

	return keys_fill(ctx);
}

/*
 * lu_ctx_tags/lu_ses_tags will be updated if there are new types of
 * obd being added. Currently, this is only used on client side, specifically
 * for echo device client, for other stack (like ptlrpc threads), context are
 * predefined when the lu_device type are registered, during the module probe
 * phase.
 */
u32 lu_context_tags_default = LCT_CL_THREAD;
u32 lu_session_tags_default = LCT_SESSION;

void lu_context_tags_update(__u32 tags)
{
	spin_lock(&lu_context_remembered_guard);
	lu_context_tags_default |= tags;
	atomic_inc(&key_set_version);
	spin_unlock(&lu_context_remembered_guard);
}
EXPORT_SYMBOL(lu_context_tags_update);

void lu_context_tags_clear(__u32 tags)
{
	spin_lock(&lu_context_remembered_guard);
	lu_context_tags_default &= ~tags;
	atomic_inc(&key_set_version);
	spin_unlock(&lu_context_remembered_guard);
}
EXPORT_SYMBOL(lu_context_tags_clear);

void lu_session_tags_update(__u32 tags)
{
	spin_lock(&lu_context_remembered_guard);
	lu_session_tags_default |= tags;
	atomic_inc(&key_set_version);
	spin_unlock(&lu_context_remembered_guard);
}
EXPORT_SYMBOL(lu_session_tags_update);

void lu_session_tags_clear(__u32 tags)
{
	spin_lock(&lu_context_remembered_guard);
	lu_session_tags_default &= ~tags;
	atomic_inc(&key_set_version);
	spin_unlock(&lu_context_remembered_guard);
}
EXPORT_SYMBOL(lu_session_tags_clear);

int lu_env_init(struct lu_env *env, __u32 tags)
{
	int result;

	env->le_ses = NULL;
	result = lu_context_init(&env->le_ctx, tags);
	if (likely(result == 0))
		lu_context_enter(&env->le_ctx);
	return result;
}
EXPORT_SYMBOL(lu_env_init);

void lu_env_fini(struct lu_env *env)
{
	lu_context_exit(&env->le_ctx);
	lu_context_fini(&env->le_ctx);
	env->le_ses = NULL;
}
EXPORT_SYMBOL(lu_env_fini);

int lu_env_refill(struct lu_env *env)
{
	int result;

	result = lu_context_refill(&env->le_ctx);
	if (result == 0 && env->le_ses != NULL)
		result = lu_context_refill(env->le_ses);
	return result;
}
EXPORT_SYMBOL(lu_env_refill);

/*
 * Currently, this API will only be used by echo client.
 * Because echo client and normal lustre client will share
 * same cl_env cache. So echo client needs to refresh
 * the env context after it get one from the cache, especially
 * when normal client and echo client co-exist in the same client.
 */
int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags,
			  __u32 stags)
{
	int    result;

	if ((env->le_ctx.lc_tags & ctags) != ctags) {
		env->le_ctx.lc_version = 0;
		env->le_ctx.lc_tags |= ctags;
	}

	if (env->le_ses && (env->le_ses->lc_tags & stags) != stags) {
		env->le_ses->lc_version = 0;
		env->le_ses->lc_tags |= stags;
	}

	result = lu_env_refill(env);

	return result;
}
EXPORT_SYMBOL(lu_env_refill_by_tags);


struct lu_env_item {
	struct task_struct *lei_task;	/* rhashtable key */
	struct rhash_head lei_linkage;
	struct lu_env *lei_env;
	struct rcu_head lei_rcu_head;
};

static const struct rhashtable_params lu_env_rhash_params = {
	.key_len     = sizeof(struct task_struct *),
	.key_offset  = offsetof(struct lu_env_item, lei_task),
	.head_offset = offsetof(struct lu_env_item, lei_linkage),
};

static struct rhashtable lu_env_rhash;

struct lu_env_percpu {
	struct task_struct *lep_task;
	struct lu_env *lep_env ____cacheline_aligned_in_smp;
};

static struct lu_env_percpu lu_env_percpu[NR_CPUS];

int lu_env_add_task(struct lu_env *env, struct task_struct *task)
{
	struct lu_env_item *lei, *old;

	LASSERT(env);

	OBD_ALLOC_PTR(lei);
	if (!lei)
		return -ENOMEM;

	lei->lei_task = task;
	lei->lei_env = env;

	old = rhashtable_lookup_get_insert_fast(&lu_env_rhash,
						&lei->lei_linkage,
						lu_env_rhash_params);
	LASSERT(!old);

	return 0;
}
EXPORT_SYMBOL(lu_env_add_task);

int lu_env_add(struct lu_env *env)
{
	return lu_env_add_task(env, current);
}
EXPORT_SYMBOL(lu_env_add);

void lu_env_remove(struct lu_env *env)
{
	struct lu_env_item *lei;
	const void *task = current;
	int i;

	for_each_possible_cpu(i) {
		if (lu_env_percpu[i].lep_env == env) {
			LASSERT(lu_env_percpu[i].lep_task == task);
			lu_env_percpu[i].lep_task = NULL;
			lu_env_percpu[i].lep_env = NULL;
		}
	}

	/* The rcu_lock is not taking in this case since the key
	 * used is the actual task_struct. This implies that each
	 * object is only removed by the owning thread, so there
	 * can never be a race on a particular object.
	 */
	lei = rhashtable_lookup_fast(&lu_env_rhash, &task,
				     lu_env_rhash_params);
	if (lei && rhashtable_remove_fast(&lu_env_rhash, &lei->lei_linkage,
					  lu_env_rhash_params) == 0) {
		OBD_FREE_RCU(lei, sizeof(*lei), lei_rcu_head);
	}
}
EXPORT_SYMBOL(lu_env_remove);

/**
 * lu_env_find() - return current lustre environment
 *
 * Return valid pointer to lu_env on success or NULL on failure
 */
struct lu_env *lu_env_find(void)
{
	struct lu_env *env = NULL;
	struct lu_env_item *lei;
	const void *task = current;
	int i = get_cpu();

	if (lu_env_percpu[i].lep_task == current) {
		env = lu_env_percpu[i].lep_env;
		put_cpu();
		LASSERT(env);
		return env;
	}

	lei = rhashtable_lookup_fast(&lu_env_rhash, &task,
				     lu_env_rhash_params);
	if (lei) {
		env = lei->lei_env;
		lu_env_percpu[i].lep_task = current;
		lu_env_percpu[i].lep_env = env;
	}
	put_cpu();

	return env;
}
EXPORT_SYMBOL(lu_env_find);

typedef struct lu_site_stats {
	unsigned int lss_populated;
	unsigned int lss_max_search;
	unsigned int lss_total;
	unsigned int lss_busy;
} lu_site_stats_t;

static void lu_site_stats_get(const struct lu_site *s,
			      lu_site_stats_t *stats)
{
	int cnt = atomic_read(&s->ls_obj_hash.nelems);
	/*
	 * percpu_counter_sum_positive() won't accept a const pointer
	 * as it does modify the struct by taking a spinlock
	 */
	struct lu_site *s2 = (struct lu_site *)s;

	stats->lss_busy += cnt -
		percpu_counter_sum_positive(&s2->ls_lru_len_counter);

	stats->lss_total += cnt;
	stats->lss_max_search = 0;
	stats->lss_populated = 0;
}

static void collect_free(struct lu_site *s, struct list_head *dispose)
{
	int i;
	struct lu_site_bkt_data *bkt;

	for (i = 0; i < s->ls_bkt_cnt ; i++) {
		bkt = &s->ls_bkts[i];
		spin_lock(&bkt->lsb_waitq.lock);

		list_splice_init(&bkt->lsb_free, dispose);
		spin_unlock(&bkt->lsb_waitq.lock);
	}
}

static void lu_objects_flush(struct work_struct *work)
{
	struct lu_site *s;
	struct lu_object_header *h;

	LIST_HEAD(dispose);

	down_read(&lu_sites_guard);
	list_for_each_entry(s, &lu_sites, ls_linkage) {

		atomic_set(&s->ls_free_done, 0);
		collect_free(s, &dispose);
		/*
		 * Free everything on the dispose list. This is safe against
		 * races due to the reasons described in lu_object_put().
		 */
		while ((h = list_first_entry_or_null(&dispose,
						     struct lu_object_header,
						     loh_lru)) != NULL) {
			list_del_init(&h->loh_lru);
			lu_object_free(&lu_free_env, lu_object_top(h));
		}

		atomic_set(&s->ls_free_done, 1);
		wake_up(&s->ls_freeq);
	}
	up_read(&lu_sites_guard);

	queue_delayed_work(system_long_wq, &lu_site_flush, HZ);
}

void lu_objects_destroy_delayed(void)
{
	mod_delayed_work(system_long_wq, &lu_site_flush,0);
	flush_delayed_work(&lu_site_flush);
}
EXPORT_SYMBOL(lu_objects_destroy_delayed);

/*
 * lu_cache_shrink_count() returns an approximate number of cached objects
 * that can be freed by shrink_slab(). A counter, which tracks the
 * number of items in the site's lru, is maintained in a percpu_counter
 * for each site. The percpu values are incremented and decremented as
 * objects are added or removed from the lru. The percpu values are summed
 * and saved whenever a percpu value exceeds a threshold. Thus the saved,
 * summed value at any given time may not accurately reflect the current
 * lru length. But this value is sufficiently accurate for the needs of
 * a shrinker.
 *
 * Using a per cpu counter is a compromise solution to concurrent access:
 * lu_object_put() can update the counter without locking the site and
 * lu_cache_shrink_count can sum the counters without locking each
 * ls_obj_hash bucket.
 */
static unsigned long lu_cache_shrink_count(struct shrinker *sk,
					   struct shrink_control *sc)
{
	struct lu_site *s;
	unsigned long cached = 0;

	if (!(sc->gfp_mask & __GFP_FS))
		return 0;

	if (!down_read_trylock(&lu_sites_guard))
		return 0;
	list_for_each_entry(s, &lu_sites, ls_linkage)
		cached += percpu_counter_read_positive(&s->ls_lru_len_counter);
	up_read(&lu_sites_guard);

	cached = vfs_pressure_ratio(cached);
	CDEBUG(D_INODE, "%ld objects cached, cache pressure %ld\n",
	       cached, vfs_pressure_ratio(100));

	return cached;
}

static unsigned long lu_cache_shrink_scan(struct shrinker *sk,
					  struct shrink_control *sc)
{
	struct lu_site *s;
	struct lu_site *tmp;
	unsigned long remain = sc->nr_to_scan;
	LIST_HEAD(splice);

	if (!(sc->gfp_mask & __GFP_FS))
		/* We must not take the lu_sites_guard lock when
		 * __GFP_FS is *not* set because of the deadlock
		 * possibility detailed above. Additionally,
		 * since we cannot determine the number of
		 * objects in the cache without taking this
		 * lock, we're in a particularly tough spot. As
		 * a result, we'll just lie and say our cache is
		 * empty. This _should_ be ok, as we can't
		 * reclaim objects when __GFP_FS is *not* set
		 * anyways.
		 */
		return SHRINK_STOP;

	if (!down_write_trylock(&lu_sites_guard))
		return SHRINK_STOP;

	list_for_each_entry_safe(s, tmp, &lu_sites, ls_linkage) {
		remain = lu_site_purge(&lu_shrink_env, s, remain);
		/*
		 * Move just shrunk site to the tail of site list to
		 * assure shrinking fairness.
		 */
		list_move_tail(&s->ls_linkage, &splice);
	}
	list_splice(&splice, lu_sites.prev);
	up_write(&lu_sites_guard);

	return sc->nr_to_scan - remain;
}

static struct shrinker *lu_site_shrinker;

/* Initialization of global lu_* data. */
int lu_global_init(void)
{
	char path[MAX_OBD_NAME];
	int result;

	CDEBUG(D_INFO, "Lustre LU module (%p).\n", &lu_keys);

	LU_CONTEXT_KEY_INIT(&lu_global_key);
	result = lu_context_key_register(&lu_global_key);
	if (result)
		goto out;

	/*
	 * At this level, we don't know what tags are needed, so allocate them
	 * conservatively. This should not be too bad, because this
	 * environment is global.
	 */
	down_write(&lu_sites_guard);
	result = lu_env_init(&lu_shrink_env, LCT_SHRINKER);
	up_write(&lu_sites_guard);
	if (result) {
		lu_context_key_degister(&lu_global_key);
		goto out;
	}

	down_write(&lu_sites_guard);
	result = lu_env_init(&lu_free_env, LCT_SHRINKER);
	up_write(&lu_sites_guard);
	if (result) {
		lu_context_key_degister(&lu_global_key);
		goto out_shrink_env;
	}

	/*
	 * seeks estimation: 3 seeks to read a record from oi, one to read
	 * inode, one for ea. Unfortunately setting this high value results in
	 * lu_object/inode cache consuming all the memory.
	 */
	lu_site_shrinker = ll_shrinker_alloc(0, "lu_site");
	if (IS_ERR(lu_site_shrinker)) {
		result = PTR_ERR(lu_site_shrinker);
		goto out_env;
	}

	lu_site_shrinker->count_objects = lu_cache_shrink_count;
	lu_site_shrinker->scan_objects = lu_cache_shrink_scan;

	ll_shrinker_register(lu_site_shrinker);

	scnprintf(path, sizeof(path), "../shrinker/%s",
		  shrinker_debugfs_path(lu_site_shrinker));
	debugfs_create_symlink("lu_site", debugfs_lustre_root, path);

	result = rhashtable_init(&lu_env_rhash, &lu_env_rhash_params);

	if (result)
		goto out_shrinker;

	INIT_DELAYED_WORK(&lu_site_flush, lu_objects_flush);
	queue_delayed_work(system_long_wq, &lu_site_flush, HZ);

	return result;

out_shrinker:
	ll_shrinker_free(lu_site_shrinker);
out_env:
	/* ordering here is explained in lu_global_fini() */
	lu_context_key_degister(&lu_global_key);
out_shrink_env:
	down_write(&lu_sites_guard);
	lu_env_fini(&lu_shrink_env);
	up_write(&lu_sites_guard);
out:
	return result;
}

/* Dual to lu_global_init(). */
void lu_global_fini(void)
{
	cancel_delayed_work_sync(&lu_site_flush);
	ll_shrinker_free(lu_site_shrinker);

	lu_context_key_degister(&lu_global_key);

	/*
	 * Tear shrinker environment down _after_ de-registering
	 * lu_global_key, because the latter has a value in the former.
	 */
	down_write(&lu_sites_guard);
	lu_env_fini(&lu_shrink_env);
	lu_env_fini(&lu_free_env);
	up_write(&lu_sites_guard);

	rhashtable_destroy(&lu_env_rhash);
}

static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx)
{
#ifdef CONFIG_PROC_FS
	struct lprocfs_counter ret;

	lprocfs_stats_collect(stats, idx, &ret);
	return (__u32)ret.lc_count;
#else
	return 0;
#endif
}

/*
 * Output site statistical counters into a buffer. Suitable for
 * lprocfs_rd_*()-style functions.
 */
int lu_site_stats_seq_print(const struct lu_site *s, struct seq_file *m)
{
	const struct bucket_table *tbl;
	lu_site_stats_t stats;
	unsigned int chains;

	memset(&stats, 0, sizeof(stats));
	lu_site_stats_get(s, &stats);

	rcu_read_lock();
	tbl = rht_dereference_rcu(s->ls_obj_hash.tbl,
				  &((struct lu_site *)s)->ls_obj_hash);
	chains = tbl->size;
	rcu_read_unlock();
	seq_printf(m, "%d/%d %d/%u %d %d %d %d %d %d %d\n",
		   stats.lss_busy,
		   stats.lss_total,
		   stats.lss_populated,
		   chains,
		   stats.lss_max_search,
		   ls_stats_read(s->ls_stats, LU_SS_CREATED),
		   ls_stats_read(s->ls_stats, LU_SS_CACHE_HIT),
		   ls_stats_read(s->ls_stats, LU_SS_CACHE_MISS),
		   ls_stats_read(s->ls_stats, LU_SS_CACHE_RACE),
		   ls_stats_read(s->ls_stats, LU_SS_CACHE_DEATH_RACE),
		   ls_stats_read(s->ls_stats, LU_SS_LRU_PURGED));
	return 0;
}
EXPORT_SYMBOL(lu_site_stats_seq_print);

/* Helper function to initialize a number of kmem slab caches at once. */
int lu_kmem_init(struct lu_kmem_descr *caches)
{
	int result;
	struct lu_kmem_descr *iter = caches;

	for (result = 0; iter->ckd_cache != NULL; ++iter) {
		*iter->ckd_cache = kmem_cache_create(iter->ckd_name,
						     iter->ckd_size,
						     0, 0, NULL);
		if (*iter->ckd_cache == NULL) {
			result = -ENOMEM;
			/* free all previously allocated caches */
			lu_kmem_fini(caches);
			break;
		}
	}
	return result;
}
EXPORT_SYMBOL(lu_kmem_init);

/*
 * Helper function to finalize a number of kmem slab cached at once. Dual to
 * lu_kmem_init().
 */
void lu_kmem_fini(struct lu_kmem_descr *caches)
{
	/* wait for all RCU callbacks freeing objects are done */
	rcu_barrier();
	for (; caches->ckd_cache != NULL; ++caches) {
		if (*caches->ckd_cache != NULL) {
			kmem_cache_destroy(*caches->ckd_cache);
			*caches->ckd_cache = NULL;
		}
	}
}
EXPORT_SYMBOL(lu_kmem_fini);

/*
 * Temporary solution to be able to assign fid in ->do_create()
 * till we have fully-functional OST fids
 */
void lu_object_assign_fid(const struct lu_env *env, struct lu_object *o,
			  const struct lu_fid *fid)
{
	struct lu_site		*s = o->lo_dev->ld_site;
	struct lu_fid		*old = &o->lo_header->loh_fid;
	int rc;

	LASSERT(fid_is_zero(old));
	*old = *fid;
try_again:
	rc = rhashtable_lookup_insert_fast(&s->ls_obj_hash,
					   &o->lo_header->loh_hash,
					   obj_hash_params);
	/* supposed to be unique */
	LASSERT(rc != -EEXIST);
	/* handle hash table resizing */
	if (rc == -ENOMEM || rc == -EBUSY) {
		msleep(20);
		goto try_again;
	}
	/* trim the hash if its growing to big */
	lu_object_limit(env, o->lo_dev);
	if (rc == -E2BIG)
		goto try_again;

	LASSERTF(rc == 0, "failed hashtable insertion: rc = %d\n", rc);
}
EXPORT_SYMBOL(lu_object_assign_fid);

/*
 * allocates object with 0 (non-assiged) fid
 * XXX: temporary solution to be able to assign fid in ->do_create()
 *      till we have fully-functional OST fids
 */
struct lu_object *lu_object_anon(const struct lu_env *env,
				 struct lu_device *dev,
				 const struct lu_object_conf *conf)
{
	struct lu_fid fid;
	struct lu_object *o;
	int rc;

	fid_zero(&fid);
	o = lu_object_alloc(env, dev, &fid);
	if (!IS_ERR(o)) {
		rc = lu_object_start(env, dev, o, conf);
		if (rc) {
			lu_object_free(env, o);
			return ERR_PTR(rc);
		}
	}

	return o;
}
EXPORT_SYMBOL(lu_object_anon);

struct lu_buf LU_BUF_NULL = {
	.lb_buf = NULL,
	.lb_len = 0
};
EXPORT_SYMBOL(LU_BUF_NULL);

void lu_buf_free(struct lu_buf *buf)
{
	LASSERT(buf);
	if (buf->lb_buf) {
		LASSERT(buf->lb_len > 0);
		OBD_FREE_LARGE(buf->lb_buf, buf->lb_len);
		buf->lb_buf = NULL;
		buf->lb_len = 0;
	}
}
EXPORT_SYMBOL(lu_buf_free);

void lu_buf_alloc(struct lu_buf *buf, size_t size)
{
	LASSERT(buf);
	LASSERT(buf->lb_buf == NULL);
	LASSERT(buf->lb_len == 0);
	OBD_ALLOC_LARGE(buf->lb_buf, size);
	if (likely(buf->lb_buf))
		buf->lb_len = size;
}
EXPORT_SYMBOL(lu_buf_alloc);

void lu_buf_realloc(struct lu_buf *buf, size_t size)
{
	lu_buf_free(buf);
	lu_buf_alloc(buf, size);
}
EXPORT_SYMBOL(lu_buf_realloc);

struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len)
{
	if (buf->lb_buf == NULL && buf->lb_len == 0)
		lu_buf_alloc(buf, len);

	if ((len > buf->lb_len) && (buf->lb_buf != NULL))
		lu_buf_realloc(buf, len);

	return buf;
}
EXPORT_SYMBOL(lu_buf_check_and_alloc);

/**
 * lu_buf_check_and_grow() - Increase the size of the @buf.
 * @buf: buffer to increase
 * @len: new size of the @buf
 *
 * Preserves old data in buffer. Old buffer remains unchanged on error
 *
 * Return:
 * * %0 on success
 * * %-ENOMEM on failure
 */
int lu_buf_check_and_grow(struct lu_buf *buf, size_t len)
{
	char *ptr;

	if (len <= buf->lb_len)
		return 0;

	OBD_ALLOC_LARGE(ptr, len);
	if (ptr == NULL)
		return -ENOMEM;

	/* Free the old buf */
	if (buf->lb_buf != NULL) {
		memcpy(ptr, buf->lb_buf, buf->lb_len);
		OBD_FREE_LARGE(buf->lb_buf, buf->lb_len);
	}

	buf->lb_buf = ptr;
	buf->lb_len = len;
	return 0;
}
EXPORT_SYMBOL(lu_buf_check_and_grow);

/**
 * lu_buf_check_and_shrink() - Decrease the size of the @buf.
 * @buf: buffer to shrink
 * @len: new size of the @buf
 *
 * If @len is greater than or equal to the current buffer length, the buffer is
 * left unchanged.  If @len is zero, the buffer is freed.  For smaller, non-zero
 * sizes this helper allocates a new buffer of @len bytes, copies the first
 * @len bytes from the old buffer, and then frees the old one.
 *
 * On allocation failure the old buffer remains unchanged.
 *
 * Return:
 * * %0 on success
 * * %-ENOMEM on failure
 */
int lu_buf_check_and_shrink(struct lu_buf *buf, size_t len)
{
	char *ptr;

	/* Nothing to do if new length is not smaller. */
	if (len >= buf->lb_len)
		return 0;

	/* len == 0 is treated as freeing the buffer. */
	if (len == 0) {
		lu_buf_free(buf);
		return 0;
	}

	OBD_ALLOC_LARGE(ptr, len);
	if (ptr == NULL)
		return -ENOMEM;

	if (buf->lb_buf != NULL) {
		memcpy(ptr, buf->lb_buf, len);
		OBD_FREE_LARGE(buf->lb_buf, buf->lb_len);
	}

	buf->lb_buf = ptr;
	buf->lb_len = len;

	return 0;
}
EXPORT_SYMBOL(lu_buf_check_and_shrink);