-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
#include <libcfs/libcfs.h>
EXPORT_SYMBOL(lu_object_put);
/**
+ * 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)
+{
+ cfs_set_bit(LU_OBJECT_HEARD_BANSHEE,
+ &o->lo_header->loh_flags);
+ return lu_object_put(env, o);
+}
+EXPORT_SYMBOL(lu_object_put_nocache);
+
+/**
* Allocate new object.
*
* This follows object creation protocol, described in the comment within
* lu_global_init().
*/
struct lu_context_key lu_global_key = {
- .lct_tags = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD,
+ .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD |
+ LCT_MG_THREAD | LCT_CL_THREAD,
.lct_init = lu_global_key_init,
.lct_fini = lu_global_key_fini
};
.hs_put_locked = lu_obj_hop_put_locked,
};
+void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d)
+{
+ cfs_spin_lock(&s->ls_ld_lock);
+ if (cfs_list_empty(&d->ld_linkage))
+ cfs_list_add(&d->ld_linkage, &s->ls_ld_linkage);
+ cfs_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)
+{
+ cfs_spin_lock(&s->ls_ld_lock);
+ cfs_list_del_init(&d->ld_linkage);
+ cfs_spin_unlock(&s->ls_ld_lock);
+}
+EXPORT_SYMBOL(lu_dev_del_linkage);
+
/**
* Initialize site \a s, with \a d as the top level device.
*/
CFS_INIT_LIST_HEAD(&s->ls_ld_linkage);
cfs_spin_lock_init(&s->ls_ld_lock);
- cfs_spin_lock(&s->ls_ld_lock);
- cfs_list_add(&top->ld_linkage, &s->ls_ld_linkage);
- cfs_spin_unlock(&s->ls_ld_lock);
+ lu_dev_add_linkage(s, top);
RETURN(0);
}
/* purge again. */
lu_site_purge(env, site, ~0);
- if (!cfs_hash_is_empty(site->ls_obj_hash)) {
- /*
- * Uh-oh, objects still exist.
- */
- LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_ERROR, NULL);
-
- lu_site_print(env, site, &msgdata, lu_cdebug_printer);
- }
-
for (scan = top; scan != NULL; scan = next) {
const struct lu_device_type *ldt = scan->ld_type;
struct obd_type *type;
static struct lu_context_key *lu_keys[LU_CONTEXT_KEY_NR] = { NULL, };
-static cfs_spinlock_t lu_keys_guard = CFS_SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lu_keys_guard);
/**
* Global counter incremented whenever key is registered, unregistered,
key->lct_fini(ctx, key, ctx->lc_value[index]);
lu_ref_del(&key->lct_reference, "ctx", ctx);
cfs_atomic_dec(&key->lct_used);
- LASSERT(key->lct_owner != NULL);
- if (!(ctx->lc_tags & LCT_NOREF)) {
- LASSERT(cfs_module_refcount(key->lct_owner) > 0);
- cfs_module_put(key->lct_owner);
- }
- ctx->lc_value[index] = NULL;
- }
+
+ LASSERT(key->lct_owner != NULL);
+ if ((ctx->lc_tags & LCT_NOREF) == 0) {
+ LINVRNT(cfs_module_refcount(key->lct_owner) > 0);
+ cfs_module_put(key->lct_owner);
+ }
+ ctx->lc_value[index] = NULL;
+ }
}
/**
static void keys_fini(struct lu_context *ctx)
{
- int i;
+ int i;
- cfs_spin_lock(&lu_keys_guard);
- if (ctx->lc_value != NULL) {
- for (i = 0; i < ARRAY_SIZE(lu_keys); ++i)
- key_fini(ctx, i);
- OBD_FREE(ctx->lc_value,
- ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
- ctx->lc_value = NULL;
- }
- cfs_spin_unlock(&lu_keys_guard);
+ if (ctx->lc_value == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(lu_keys); ++i)
+ key_fini(ctx, i);
+
+ OBD_FREE(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+ ctx->lc_value = NULL;
}
static int keys_fill(struct lu_context *ctx)
{
int i;
+ LINVRNT(ctx->lc_value != NULL);
for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
struct lu_context_key *key;
static int keys_init(struct lu_context *ctx)
{
- int result;
-
- OBD_ALLOC(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
- if (likely(ctx->lc_value != NULL))
- result = keys_fill(ctx);
- else
- result = -ENOMEM;
+ OBD_ALLOC(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+ if (likely(ctx->lc_value != NULL))
+ return keys_fill(ctx);
- if (result != 0)
- keys_fini(ctx);
- return result;
+ return -ENOMEM;
}
/**
*/
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;
cfs_spin_lock(&lu_keys_guard);
cfs_list_add(&ctx->lc_remember, &lu_context_remembered);
cfs_spin_unlock(&lu_keys_guard);
- } else
- CFS_INIT_LIST_HEAD(&ctx->lc_remember);
- return keys_init(ctx);
+ } else {
+ CFS_INIT_LIST_HEAD(&ctx->lc_remember);
+ }
+
+ rc = keys_init(ctx);
+ if (rc != 0)
+ lu_context_fini(ctx);
+
+ return rc;
}
EXPORT_SYMBOL(lu_context_init);
*/
void lu_context_fini(struct lu_context *ctx)
{
- LINVRNT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT);
- ctx->lc_state = LCS_FINALIZED;
- keys_fini(ctx);
- cfs_spin_lock(&lu_keys_guard);
- cfs_list_del_init(&ctx->lc_remember);
- cfs_spin_unlock(&lu_keys_guard);
+ LINVRNT(ctx->lc_state == LCS_INITIALIZED || ctx->lc_state == LCS_LEFT);
+ ctx->lc_state = LCS_FINALIZED;
+
+ if ((ctx->lc_tags & LCT_REMEMBER) == 0) {
+ LASSERT(cfs_list_empty(&ctx->lc_remember));
+ keys_fini(ctx);
+
+ } else { /* could race with key degister */
+ cfs_spin_lock(&lu_keys_guard);
+ keys_fini(ctx);
+ cfs_list_del_init(&ctx->lc_remember);
+ cfs_spin_unlock(&lu_keys_guard);
+ }
}
EXPORT_SYMBOL(lu_context_fini);
/**
* Allocate for context all missing keys that were registered after context
- * creation.
+ * creation. key_set_version is only changed in rare cases when modules
+ * are loaded and removed.
*/
int lu_context_refill(struct lu_context *ctx)
{
- LINVRNT(ctx->lc_value != NULL);
- return ctx->lc_version == key_set_version ? 0 : keys_fill(ctx);
+ return likely(ctx->lc_version == key_set_version) ? 0 : keys_fill(ctx);
}
EXPORT_SYMBOL(lu_context_refill);
}
}
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;
+ struct lu_site_bkt_data *bkt;
+ struct lu_object *shadow;
+ cfs_waitlink_t waiter;
+ cfs_hash_t *hs;
+ cfs_hash_bd_t bd;
+ __u64 version = 0;
+
+ LASSERT(fid_is_zero(old));
+
+ hs = s->ls_obj_hash;
+ cfs_hash_bd_get_and_lock(hs, (void *)fid, &bd, 1);
+ shadow = htable_lookup(s, &bd, fid, &waiter, &version);
+ /* supposed to be unique */
+ LASSERT(shadow == NULL);
+ *old = *fid;
+ bkt = cfs_hash_bd_extra_get(hs, &bd);
+ cfs_hash_bd_add_locked(hs, &bd, &o->lo_header->loh_hash);
+ bkt->lsb_busy++;
+ cfs_hash_bd_unlock(hs, &bd, 1);
+}
+EXPORT_SYMBOL(lu_object_assign_fid);