*/
struct hlist_node lr_hash;
+ /** Reference count for this resource */
+ atomic_t lr_refcount;
+
/** Spinlock to protect locks under this resource. */
spinlock_t lr_lock;
struct list_head lr_waiting;
/** @} */
- /* XXX No longer needed? Remove ASAP */
- ldlm_mode_t lr_most_restr;
-
- /** Type of locks this resource can hold. Only one type per resource. */
- ldlm_type_t lr_type; /* LDLM_{PLAIN,EXTENT,FLOCK,IBITS} */
-
/** Resource name */
struct ldlm_res_id lr_name;
- /** Reference count for this resource */
- atomic_t lr_refcount;
/**
* Interval trees (only for extent locks) for all modes of this resource
*/
- struct ldlm_interval_tree lr_itree[LCK_MODE_NUM];
+ struct ldlm_interval_tree *lr_itree;
+
+ union {
+ /**
+ * When the resource was considered as contended,
+ * used only on server side. */
+ cfs_time_t lr_contention_time;
+ /**
+ * Associated inode, used only on client side.
+ */
+ struct inode *lr_lvb_inode;
+ };
+
+ /** Type of locks this resource can hold. Only one type per resource. */
+ ldlm_type_t lr_type; /* LDLM_{PLAIN,EXTENT,FLOCK,IBITS} */
/**
* Server-side-only lock value block elements.
* To serialize lvbo_init.
*/
- struct mutex lr_lvb_mutex;
int lr_lvb_len;
- /** is lvb initialized ? */
- bool lr_lvb_initialized;
+ struct mutex lr_lvb_mutex;
/** protected by lr_lock */
void *lr_lvb_data;
+ /** is lvb initialized ? */
+ bool lr_lvb_initialized;
- /** When the resource was considered as contended. */
- cfs_time_t lr_contention_time;
/** List of references to this resource. For debugging. */
struct lu_ref lr_reference;
-
- struct inode *lr_lvb_inode;
};
static inline bool ldlm_has_layout(struct ldlm_lock *lock)
/* ldlm_resource.c */
extern struct kmem_cache *ldlm_resource_slab;
extern struct kmem_cache *ldlm_lock_slab;
+extern struct kmem_cache *ldlm_interval_tree_slab;
int ldlm_resource_putref_locked(struct ldlm_resource *res);
void ldlm_resource_insert_lock_after(struct ldlm_lock *original,
else
ldlm_resource_add_lock(res, &res->lr_granted, lock);
- if (lock->l_granted_mode < res->lr_most_restr)
- res->lr_most_restr = lock->l_granted_mode;
-
ldlm_pool_add(&ldlm_res_to_ns(res)->ns_pool, lock);
EXIT;
}
ldlm_lock_slab = kmem_cache_create("ldlm_locks",
sizeof(struct ldlm_lock), 0,
SLAB_HWCACHE_ALIGN | SLAB_DESTROY_BY_RCU, NULL);
- if (ldlm_lock_slab == NULL) {
- kmem_cache_destroy(ldlm_resource_slab);
- return -ENOMEM;
- }
+ if (ldlm_lock_slab == NULL)
+ goto out_resource;
ldlm_interval_slab = kmem_cache_create("interval_node",
sizeof(struct ldlm_interval),
0, SLAB_HWCACHE_ALIGN, NULL);
- if (ldlm_interval_slab == NULL) {
- kmem_cache_destroy(ldlm_resource_slab);
- kmem_cache_destroy(ldlm_lock_slab);
- return -ENOMEM;
- }
+ if (ldlm_interval_slab == NULL)
+ goto out_lock;
+
+ ldlm_interval_tree_slab = kmem_cache_create("interval_tree",
+ sizeof(struct ldlm_interval_tree) * LCK_MODE_NUM,
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (ldlm_interval_tree_slab == NULL)
+ goto out_interval;
+
#if LUSTRE_TRACKS_LOCK_EXP_REFS
- class_export_dump_hook = ldlm_dump_export_locks;
+ class_export_dump_hook = ldlm_dump_export_locks;
#endif
- return 0;
+ return 0;
+
+out_interval:
+ kmem_cache_destroy(ldlm_interval_slab);
+out_lock:
+ kmem_cache_destroy(ldlm_lock_slab);
+out_resource:
+ kmem_cache_destroy(ldlm_resource_slab);
+
+ return -ENOMEM;
}
void ldlm_exit(void)
synchronize_rcu();
kmem_cache_destroy(ldlm_lock_slab);
kmem_cache_destroy(ldlm_interval_slab);
+ kmem_cache_destroy(ldlm_interval_tree_slab);
}
#include "ldlm_internal.h"
struct kmem_cache *ldlm_resource_slab, *ldlm_lock_slab;
+struct kmem_cache *ldlm_interval_tree_slab;
int ldlm_srv_namespace_nr = 0;
int ldlm_cli_namespace_nr = 0;
}
/** Create and initialize new resource. */
-static struct ldlm_resource *ldlm_resource_new(void)
+static struct ldlm_resource *ldlm_resource_new(ldlm_type_t type)
{
struct ldlm_resource *res;
int idx;
if (res == NULL)
return NULL;
+ if (type == LDLM_EXTENT) {
+ OBD_SLAB_ALLOC(res->lr_itree, ldlm_interval_tree_slab,
+ sizeof(*res->lr_itree) * LCK_MODE_NUM);
+ if (res->lr_itree == NULL) {
+ OBD_SLAB_FREE_PTR(res, ldlm_resource_slab);
+ return NULL;
+ }
+ /* Initialize interval trees for each lock mode. */
+ for (idx = 0; idx < LCK_MODE_NUM; idx++) {
+ res->lr_itree[idx].lit_size = 0;
+ res->lr_itree[idx].lit_mode = 1 << idx;
+ res->lr_itree[idx].lit_root = NULL;
+ }
+ }
+
INIT_LIST_HEAD(&res->lr_granted);
INIT_LIST_HEAD(&res->lr_converting);
INIT_LIST_HEAD(&res->lr_waiting);
- /* Initialize interval trees for each lock mode. */
- for (idx = 0; idx < LCK_MODE_NUM; idx++) {
- res->lr_itree[idx].lit_size = 0;
- res->lr_itree[idx].lit_mode = 1 << idx;
- res->lr_itree[idx].lit_root = NULL;
- }
-
atomic_set(&res->lr_refcount, 1);
spin_lock_init(&res->lr_lock);
lu_ref_init(&res->lr_reference);
LASSERTF(type >= LDLM_MIN_TYPE && type < LDLM_MAX_TYPE,
"type: %d\n", type);
- res = ldlm_resource_new();
+ res = ldlm_resource_new(type);
if (res == NULL)
return ERR_PTR(-ENOMEM);
res->lr_ns_bucket = cfs_hash_bd_extra_get(ns->ns_rs_hash, &bd);
res->lr_name = *name;
res->lr_type = type;
- res->lr_most_restr = LCK_NL;
cfs_hash_bd_lock(ns->ns_rs_hash, &bd, 1);
hnode = (version == cfs_hash_bd_version_get(&bd)) ? NULL :
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
/* Clean lu_ref for failed resource. */
lu_ref_fini(&res->lr_reference);
+ if (res->lr_itree != NULL)
+ OBD_SLAB_FREE(res->lr_itree, ldlm_interval_tree_slab,
+ sizeof(*res->lr_itree) * LCK_MODE_NUM);
OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
found:
res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
ns->ns_lvbo->lvbo_free(res);
+ if (res->lr_itree != NULL)
+ OBD_SLAB_FREE(res->lr_itree, ldlm_interval_tree_slab,
+ sizeof(*res->lr_itree) * LCK_MODE_NUM);
OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
return 1;
}
*/
if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
ns->ns_lvbo->lvbo_free(res);
+ if (res->lr_itree != NULL)
+ OBD_SLAB_FREE(res->lr_itree, ldlm_interval_tree_slab,
+ sizeof(*res->lr_itree) * LCK_MODE_NUM);
OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
cfs_hash_bd_lock(ns->ns_rs_hash, &bd, 1);