void lu_object_put(struct lu_object *o)
{
- struct lu_object_header *top;
- struct lu_site *site;
-
- top = o->lo_header;
- site = o->lo_dev->ld_site;
- spin_lock(&site->ls_guard);
- if (-- top->loh_ref == 0) {
- list_for_each_entry(o, &top->loh_layers, lo_linkage) {
- if (lu_object_ops(o)->ldo_object_release != NULL)
- lu_object_ops(o)->ldo_object_release(o);
- }
- -- site->ls_busy;
- if (lu_object_is_dying(top)) {
- hlist_del_init(&top->loh_hash);
- list_del_init(&top->loh_lru);
- }
- }
- spin_unlock(&site->ls_guard);
- if (lu_object_is_dying(top))
- /*
- * Object was already removed from hash and lru above, can
- * kill it.
- */
- lu_object_free(o);
+ struct lu_object_header *top;
+ struct lu_site *site;
+
+ top = o->lo_header;
+ site = o->lo_dev->ld_site;
+ spin_lock(&site->ls_guard);
+ if (-- top->loh_ref == 0) {
+ list_for_each_entry(o, &top->loh_layers, lo_linkage) {
+ if (lu_object_ops(o)->ldo_object_release != NULL)
+ lu_object_ops(o)->ldo_object_release(o);
+ }
+ -- site->ls_busy;
+ if (lu_object_is_dying(top)) {
+ hlist_del_init(&top->loh_hash);
+ list_del_init(&top->loh_lru);
+ }
+ }
+ spin_unlock(&site->ls_guard);
+ if (lu_object_is_dying(top))
+ /*
+ * Object was already removed from hash and lru above, can
+ * kill it.
+ */
+ lu_object_free(o);
}
EXPORT_SYMBOL(lu_object_put);
struct lu_object *lu_object_alloc(struct lu_site *s, const struct ll_fid *f)
{
- struct lu_object *scan;
- struct lu_object *top;
- int clean;
- int result;
-
- top = s->ls_top_dev->ld_ops->ldo_object_alloc(s->ls_top_dev);
- if (IS_ERR(top))
- return top;
+ struct lu_object *scan;
+ struct lu_object *top;
+ int clean;
+ int result;
+
+ top = s->ls_top_dev->ld_ops->ldo_object_alloc(s->ls_top_dev);
+ if (IS_ERR(top))
+ return top;
*lu_object_fid(top) = *f;
- do {
- clean = 1;
- list_for_each_entry(scan,
- &top->lo_header->loh_layers, lo_linkage) {
- if (scan->lo_flags & LU_OBJECT_ALLOCATED)
- continue;
- clean = 0;
- result = lu_object_ops(scan)->ldo_object_init(scan);
- if (result != 0) {
- lu_object_free(top);
- return ERR_PTR(result);
- }
- scan->lo_flags |= LU_OBJECT_ALLOCATED;
- }
- } while (!clean);
- s->ls_stats.s_created ++;
- return top;
+ do {
+ clean = 1;
+ list_for_each_entry(scan,
+ &top->lo_header->loh_layers, lo_linkage) {
+ if (scan->lo_flags & LU_OBJECT_ALLOCATED)
+ continue;
+ clean = 0;
+ scan->lo_header = top->lo_header;
+ result = lu_object_ops(scan)->ldo_object_init(scan);
+ if (result != 0) {
+ lu_object_free(top);
+ return ERR_PTR(result);
+ }
+ scan->lo_flags |= LU_OBJECT_ALLOCATED;
+ }
+ } while (!clean);
+ s->ls_stats.s_created ++;
+ return top;
}
static void lu_object_free(struct lu_object *o)
{
- struct list_head splice;
-
- -- o->lo_dev->ld_site->ls_total;
- INIT_LIST_HEAD(&splice);
- list_splice_init(&o->lo_header->loh_layers, &splice);
- while (!list_empty(&splice)) {
- o = container_of(splice.next, struct lu_object, lo_linkage);
- list_del_init(&o->lo_linkage);
- LASSERT(lu_object_ops(o)->ldo_object_free != NULL);
- lu_object_ops(o)->ldo_object_free(o);
- }
+ struct list_head splice;
+
+ -- o->lo_dev->ld_site->ls_total;
+ INIT_LIST_HEAD(&splice);
+ list_splice_init(&o->lo_header->loh_layers, &splice);
+ while (!list_empty(&splice)) {
+ o = container_of(splice.next, struct lu_object, lo_linkage);
+ list_del_init(&o->lo_linkage);
+ LASSERT(lu_object_ops(o)->ldo_object_free != NULL);
+ lu_object_ops(o)->ldo_object_free(o);
+ }
}
void lu_site_purge(struct lu_site *s, int nr)
{
- struct list_head dispose;
- struct lu_object_header *h;
- struct lu_object_header *temp;
-
- INIT_LIST_HEAD(&dispose);
- spin_lock(&s->ls_guard);
- list_for_each_entry_safe(h, temp, &s->ls_lru, loh_lru) {
- if (nr-- == 0)
- break;
- if (h->loh_ref > 0)
- continue;
- hlist_del_init(&h->loh_hash);
- list_move(&h->loh_lru, &dispose);
- }
- spin_unlock(&s->ls_guard);
- while (!list_empty(&dispose)) {
- h = container_of(dispose.next,
- struct lu_object_header, loh_lru);
- list_del_init(&h->loh_lru);
- lu_object_free(lu_object_top(h));
- s->ls_stats.s_lru_purged ++;
- }
+ struct list_head dispose;
+ struct lu_object_header *h;
+ struct lu_object_header *temp;
+
+ INIT_LIST_HEAD(&dispose);
+ spin_lock(&s->ls_guard);
+ list_for_each_entry_safe(h, temp, &s->ls_lru, loh_lru) {
+ if (nr-- == 0)
+ break;
+ if (h->loh_ref > 0)
+ continue;
+ hlist_del_init(&h->loh_hash);
+ list_move(&h->loh_lru, &dispose);
+ }
+ spin_unlock(&s->ls_guard);
+ while (!list_empty(&dispose)) {
+ h = container_of(dispose.next,
+ struct lu_object_header, loh_lru);
+ list_del_init(&h->loh_lru);
+ lu_object_free(lu_object_top(h));
+ s->ls_stats.s_lru_purged ++;
+ }
}
EXPORT_SYMBOL(lu_site_purge);
int lu_object_print(struct seq_file *f, const struct lu_object *o)
{
static char ruler[] = "........................................";
- const struct lu_object *scan;
- int nob;
- int depth;
+ const struct lu_object *scan;
+ int nob;
+ int depth;
- nob = 0;
+ nob = 0;
scan = o;
- list_for_each_entry_continue(scan, &o->lo_linkage, lo_linkage) {
- depth = scan->lo_depth;
- if (depth <= o->lo_depth && scan != o)
- break;
- LASSERT(lu_object_ops(scan)->ldo_object_print != NULL);
- nob += seq_printf(f, "%*.*s", depth, depth, ruler);
- nob += lu_object_ops(scan)->ldo_object_print(f, scan);
- nob += seq_printf(f, "\n");
- }
- return nob;
+ list_for_each_entry_continue(scan, &o->lo_linkage, lo_linkage) {
+ depth = scan->lo_depth;
+ if (depth <= o->lo_depth && scan != o)
+ break;
+ LASSERT(lu_object_ops(scan)->ldo_object_print != NULL);
+ nob += seq_printf(f, "%*.*s", depth, depth, ruler);
+ nob += lu_object_ops(scan)->ldo_object_print(f, scan);
+ nob += seq_printf(f, "\n");
+ }
+ return nob;
}
EXPORT_SYMBOL(lu_object_print);
static struct lu_object *htable_lookup(struct lu_site *s,
- const struct hlist_head *bucket,
- const struct ll_fid *f)
+ const struct hlist_head *bucket,
+ const struct ll_fid *f)
{
- struct lu_object_header *h;
- struct hlist_node *scan;
-
- hlist_for_each_entry(h, scan, bucket, loh_hash) {
- s->ls_stats.s_cache_check ++;
- if (lfid_eq(&h->loh_fid, f) && !lu_object_is_dying(h)) {
- /* bump reference count... */
- if (h->loh_ref ++ == 0)
- ++ s->ls_busy;
- /* and move to the head of the LRU */
- list_move_tail(&h->loh_lru, &s->ls_lru);
- s->ls_stats.s_cache_hit ++;
- return lu_object_top(h);
- }
- }
- s->ls_stats.s_cache_miss ++;
- return NULL;
+ struct lu_object_header *h;
+ struct hlist_node *scan;
+
+ hlist_for_each_entry(h, scan, bucket, loh_hash) {
+ s->ls_stats.s_cache_check ++;
+ if (lfid_eq(&h->loh_fid, f) && !lu_object_is_dying(h)) {
+ /* bump reference count... */
+ if (h->loh_ref ++ == 0)
+ ++ s->ls_busy;
+ /* and move to the head of the LRU */
+ list_move_tail(&h->loh_lru, &s->ls_lru);
+ s->ls_stats.s_cache_hit ++;
+ return lu_object_top(h);
+ }
+ }
+ s->ls_stats.s_cache_miss ++;
+ return NULL;
}
static __u32 fid_hash(const struct ll_fid *f)
struct lu_object *lu_object_find(struct lu_site *s, const struct ll_fid *f)
{
- struct lu_object *o;
- struct lu_object *shadow;
- struct hlist_head *bucket;
-
- bucket = s->ls_hash + (fid_hash(f) & s->ls_hash_mask);
- spin_lock(&s->ls_guard);
- o = htable_lookup(s, bucket, f);
- spin_unlock(&s->ls_guard);
- if (o != NULL)
- return o;
-
- o = lu_object_alloc(s, f);
- if (IS_ERR(o))
- return o;
-
- ++ s->ls_total;
- LASSERT(lfid_eq(lu_object_fid(o), f));
-
- spin_lock(&s->ls_guard);
- shadow = htable_lookup(s, bucket, f);
- if (shadow == NULL) {
- hlist_add_head(&o->lo_header->loh_hash, bucket);
- list_add_tail(&s->ls_lru, &o->lo_header->loh_lru);
- shadow = o;
- o = NULL;
- } else
- s->ls_stats.s_cache_race ++;
- spin_unlock(&s->ls_guard);
- if (o != NULL)
- lu_object_free(o);
- return shadow;
+ struct lu_object *o;
+ struct lu_object *shadow;
+ struct hlist_head *bucket;
+
+ bucket = s->ls_hash + (fid_hash(f) & s->ls_hash_mask);
+ spin_lock(&s->ls_guard);
+ o = htable_lookup(s, bucket, f);
+ spin_unlock(&s->ls_guard);
+ if (o != NULL)
+ return o;
+
+ o = lu_object_alloc(s, f);
+ if (IS_ERR(o))
+ return o;
+
+ ++ s->ls_total;
+ LASSERT(lfid_eq(lu_object_fid(o), f));
+
+ spin_lock(&s->ls_guard);
+ shadow = htable_lookup(s, bucket, f);
+ if (shadow == NULL) {
+ hlist_add_head(&o->lo_header->loh_hash, bucket);
+ list_add_tail(&s->ls_lru, &o->lo_header->loh_lru);
+ shadow = o;
+ o = NULL;
+ } else
+ s->ls_stats.s_cache_race ++;
+ spin_unlock(&s->ls_guard);
+ if (o != NULL)
+ lu_object_free(o);
+ return shadow;
}
EXPORT_SYMBOL(lu_object_find);