}
EXPORT_SYMBOL(ldlm_it2str);
-extern struct kmem_cache *ldlm_lock_slab;
-
#ifdef HAVE_SERVER_SUPPORT
static ldlm_processing_policy ldlm_processing_policy_table[] = {
[LDLM_PLAIN] = ldlm_process_plain_lock,
return ldlm_processing_policy_table[res->lr_type];
}
EXPORT_SYMBOL(ldlm_get_processing_policy);
+
+static ldlm_reprocessing_policy ldlm_reprocessing_policy_table[] = {
+ [LDLM_PLAIN] = ldlm_reprocess_queue,
+ [LDLM_EXTENT] = ldlm_reprocess_queue,
+ [LDLM_FLOCK] = ldlm_reprocess_queue,
+ [LDLM_IBITS] = ldlm_reprocess_inodebits_queue,
+};
+
+ldlm_reprocessing_policy ldlm_get_reprocessing_policy(struct ldlm_resource *res)
+{
+ return ldlm_reprocessing_policy_table[res->lr_type];
+}
+
#endif /* HAVE_SERVER_SUPPORT */
void ldlm_register_intent(struct ldlm_namespace *ns, ldlm_res_policy arg)
lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
LDLM_NSS_LOCKS);
lu_ref_del(&res->lr_reference, "lock", lock);
- ldlm_resource_putref(res);
- lock->l_resource = NULL;
if (lock->l_export) {
class_export_lock_put(lock->l_export, lock);
lock->l_export = NULL;
if (lock->l_lvb_data != NULL)
OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len);
- ldlm_interval_free(ldlm_interval_detach(lock));
+ if (res->lr_type == LDLM_EXTENT) {
+ ldlm_interval_free(ldlm_interval_detach(lock));
+ } else if (res->lr_type == LDLM_IBITS) {
+ if (lock->l_ibits_node != NULL)
+ OBD_SLAB_FREE_PTR(lock->l_ibits_node,
+ ldlm_inodebits_slab);
+ }
+ ldlm_resource_putref(res);
+ lock->l_resource = NULL;
lu_ref_fini(&lock->l_reference);
OBD_FREE_RCU(lock, sizeof(*lock), &lock->l_handle);
}
LASSERT(handle);
- lock = class_handle2object(handle->cookie, NULL);
+ lock = class_handle2object(handle->cookie, &lock_handle_ops);
if (lock == NULL)
RETURN(NULL);
lock->l_glimpse_ast = cbs->lcs_glimpse;
}
- lock->l_tree_node = NULL;
- /* if this is the extent lock, allocate the interval tree node */
- if (type == LDLM_EXTENT)
- if (ldlm_interval_alloc(lock) == NULL)
- GOTO(out, rc = -ENOMEM);
+ switch (type) {
+ case LDLM_EXTENT:
+ rc = ldlm_extent_alloc_lock(lock);
+ break;
+ case LDLM_IBITS:
+ rc = ldlm_inodebits_alloc_lock(lock);
+ break;
+ default:
+ rc = 0;
+ }
+ if (rc)
+ GOTO(out, rc);
if (lvb_len) {
lock->l_lvb_len = lvb_len;
enum ldlm_error rc = ELDLM_OK;
struct list_head rpc_list = LIST_HEAD_INIT(rpc_list);
ldlm_processing_policy policy;
+
ENTRY;
- policy = ldlm_processing_policy_table[res->lr_type];
+ policy = ldlm_get_processing_policy(res);
restart:
policy(lock, flags, LDLM_PROCESS_ENQUEUE, &rc, &rpc_list);
if (rc == ELDLM_OK && lock->l_granted_mode != lock->l_req_mode &&
*/
int ldlm_reprocess_queue(struct ldlm_resource *res, struct list_head *queue,
struct list_head *work_list,
- enum ldlm_process_intention intention)
+ enum ldlm_process_intention intention,
+ struct ldlm_lock *hint)
{
struct list_head *tmp, *pos;
ldlm_processing_policy policy;
int rc = LDLM_ITER_CONTINUE;
enum ldlm_error err;
struct list_head bl_ast_list = LIST_HEAD_INIT(bl_ast_list);
+
ENTRY;
check_res_locked(res);
- policy = ldlm_processing_policy_table[res->lr_type];
+ policy = ldlm_get_processing_policy(res);
LASSERT(policy);
LASSERT(intention == LDLM_PROCESS_RESCAN ||
intention == LDLM_PROCESS_RECOVERY);
* if anything could be granted as a result of the cancellation.
*/
static void __ldlm_reprocess_all(struct ldlm_resource *res,
- enum ldlm_process_intention intention)
+ enum ldlm_process_intention intention,
+ struct ldlm_lock *hint)
{
struct list_head rpc_list;
#ifdef HAVE_SERVER_SUPPORT
+ ldlm_reprocessing_policy reprocess;
struct obd_device *obd;
- int rc;
- ENTRY;
+ int rc;
+
+ ENTRY;
INIT_LIST_HEAD(&rpc_list);
- /* Local lock trees don't get reprocessed. */
- if (ns_is_client(ldlm_res_to_ns(res))) {
- EXIT;
- return;
- }
+ /* Local lock trees don't get reprocessed. */
+ if (ns_is_client(ldlm_res_to_ns(res))) {
+ EXIT;
+ return;
+ }
/* Disable reprocess during lock replay stage but allow during
* request replay stage.
RETURN_EXIT;
restart:
lock_res(res);
- ldlm_reprocess_queue(res, &res->lr_waiting, &rpc_list, intention);
+ reprocess = ldlm_get_reprocessing_policy(res);
+ reprocess(res, &res->lr_waiting, &rpc_list, intention, hint);
unlock_res(res);
rc = ldlm_run_ast_work(ldlm_res_to_ns(res), &rpc_list,
goto restart;
}
#else
- ENTRY;
+ ENTRY;
INIT_LIST_HEAD(&rpc_list);
- if (!ns_is_client(ldlm_res_to_ns(res))) {
- CERROR("This is client-side-only module, cannot handle "
- "LDLM_NAMESPACE_SERVER resource type lock.\n");
- LBUG();
- }
+ if (!ns_is_client(ldlm_res_to_ns(res))) {
+ CERROR("This is client-side-only module, cannot handle "
+ "LDLM_NAMESPACE_SERVER resource type lock.\n");
+ LBUG();
+ }
#endif
- EXIT;
+ EXIT;
}
-void ldlm_reprocess_all(struct ldlm_resource *res)
+void ldlm_reprocess_all(struct ldlm_resource *res, struct ldlm_lock *hint)
{
- __ldlm_reprocess_all(res, LDLM_PROCESS_RESCAN);
+ __ldlm_reprocess_all(res, LDLM_PROCESS_RESCAN, hint);
}
EXPORT_SYMBOL(ldlm_reprocess_all);
struct ldlm_resource *res = cfs_hash_object(hs, hnode);
/* This is only called once after recovery done. LU-8306. */
- __ldlm_reprocess_all(res, LDLM_PROCESS_RECOVERY);
+ __ldlm_reprocess_all(res, LDLM_PROCESS_RECOVERY, NULL);
return 0;
}
ldlm_lvbo_update(res, lock, NULL, 1);
ldlm_lock_cancel(lock);
if (!exp->exp_obd->obd_stopping)
- ldlm_reprocess_all(res);
+ ldlm_reprocess_all(res, lock);
ldlm_resource_putref(res);
ecl->ecl_loop++;
ldlm_grant_lock(lock, NULL);
unlock_res_and_lock(lock);
- ldlm_reprocess_all(lock->l_resource);
+ ldlm_reprocess_all(lock->l_resource, lock);
EXIT;
#endif