X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_lock.c;h=d9b1ca22fd878581d15319db642fe63e13401314;hp=5e7afe6d271a6669238c669391d1b598eb662e87;hb=05e6ccd344e7eba44e43230fa2fa0a1b3b6115c4;hpb=75a417fa0065d52a31215daaaaf41c0fa9751a89 diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 5e7afe6..d9b1ca2 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -27,7 +27,6 @@ */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. * * lustre/ldlm/ldlm_lock.c * @@ -136,8 +135,6 @@ const char *ldlm_it2str(enum ldlm_intent_flags it) } 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, @@ -151,6 +148,19 @@ ldlm_processing_policy ldlm_get_processing_policy(struct ldlm_resource *res) 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) @@ -174,11 +184,20 @@ EXPORT_SYMBOL(ldlm_register_intent); */ struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock) { - atomic_inc(&lock->l_refc); + refcount_inc(&lock->l_handle.h_ref); return lock; } EXPORT_SYMBOL(ldlm_lock_get); +static void lock_handle_free(struct rcu_head *rcu) +{ + struct ldlm_lock *lock = container_of(rcu, struct ldlm_lock, + l_handle.h_rcu); + + OBD_FREE_PRE(lock, sizeof(*lock), "slab-freed"); + kmem_cache_free(ldlm_lock_slab, lock); +} + /** * Release lock reference. * @@ -189,8 +208,8 @@ void ldlm_lock_put(struct ldlm_lock *lock) ENTRY; LASSERT(lock->l_resource != LP_POISON); - LASSERT(atomic_read(&lock->l_refc) > 0); - if (atomic_dec_and_test(&lock->l_refc)) { + LASSERT(refcount_read(&lock->l_handle.h_ref) > 0); + if (refcount_dec_and_test(&lock->l_handle.h_ref)) { struct ldlm_resource *res; LDLM_DEBUG(lock, @@ -205,8 +224,6 @@ void ldlm_lock_put(struct ldlm_lock *lock) 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; @@ -215,9 +232,17 @@ void ldlm_lock_put(struct ldlm_lock *lock) 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); + call_rcu(&lock->l_handle.h_rcu, lock_handle_free); } EXIT; @@ -421,22 +446,7 @@ void ldlm_lock_destroy_nolock(struct ldlm_lock *lock) EXIT; } -/* this is called by portals_handle2object with the handle lock taken */ -static void lock_handle_addref(void *lock) -{ - LDLM_LOCK_GET((struct ldlm_lock *)lock); -} - -static void lock_handle_free(void *lock, int size) -{ - LASSERT(size == sizeof(struct ldlm_lock)); - OBD_SLAB_FREE(lock, ldlm_lock_slab, size); -} - -static struct portals_handle_ops lock_handle_ops = { - .hop_addref = lock_handle_addref, - .hop_free = lock_handle_free, -}; +static const char lock_handle_owner[] = "ldlm"; /** * @@ -458,11 +468,10 @@ static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource) if (lock == NULL) RETURN(NULL); - spin_lock_init(&lock->l_lock); - lock->l_resource = resource; + RCU_INIT_POINTER(lock->l_resource, resource); lu_ref_add(&resource->lr_reference, "lock", lock); - atomic_set(&lock->l_refc, 2); + refcount_set(&lock->l_handle.h_ref, 2); INIT_LIST_HEAD(&lock->l_res_link); INIT_LIST_HEAD(&lock->l_lru); INIT_LIST_HEAD(&lock->l_pending_chain); @@ -476,24 +485,24 @@ static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource) INIT_HLIST_NODE(&lock->l_exp_hash); INIT_HLIST_NODE(&lock->l_exp_flock_hash); - lprocfs_counter_incr(ldlm_res_to_ns(resource)->ns_stats, - LDLM_NSS_LOCKS); - INIT_LIST_HEAD_RCU(&lock->l_handle.h_link); - class_handle_hash(&lock->l_handle, &lock_handle_ops); + lprocfs_counter_incr(ldlm_res_to_ns(resource)->ns_stats, + LDLM_NSS_LOCKS); + INIT_HLIST_NODE(&lock->l_handle.h_link); + class_handle_hash(&lock->l_handle, lock_handle_owner); - lu_ref_init(&lock->l_reference); - lu_ref_add(&lock->l_reference, "hash", lock); - lock->l_callback_timeout = 0; + lu_ref_init(&lock->l_reference); + lu_ref_add(&lock->l_reference, "hash", lock); + lock->l_callback_timestamp = 0; lock->l_activity = 0; #if LUSTRE_TRACKS_LOCK_EXP_REFS INIT_LIST_HEAD(&lock->l_exp_refs_link); - lock->l_exp_refs_nr = 0; - lock->l_exp_refs_target = NULL; + lock->l_exp_refs_nr = 0; + lock->l_exp_refs_target = NULL; #endif INIT_LIST_HEAD(&lock->l_exp_list); - RETURN(lock); + RETURN(lock); } /** @@ -504,16 +513,16 @@ static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource) int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock, const struct ldlm_res_id *new_resid) { - struct ldlm_resource *oldres = lock->l_resource; + struct ldlm_resource *oldres; struct ldlm_resource *newres; int type; ENTRY; LASSERT(ns_is_client(ns)); - lock_res_and_lock(lock); - if (memcmp(new_resid, &lock->l_resource->lr_name, - sizeof(lock->l_resource->lr_name)) == 0) { + oldres = lock_res_and_lock(lock); + if (memcmp(new_resid, &oldres->lr_name, + sizeof(oldres->lr_name)) == 0) { /* Nothing to do */ unlock_res_and_lock(lock); RETURN(0); @@ -533,12 +542,13 @@ int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock, lu_ref_add(&newres->lr_reference, "lock", lock); /* - * To flip the lock from the old to the new resource, lock, oldres and - * newres have to be locked. Resource spin-locks are nested within - * lock->l_lock, and are taken in the memory address order to avoid - * dead-locks. + * To flip the lock from the old to the new resource, oldres + * and newres have to be locked. Resource spin-locks are taken + * in the memory address order to avoid dead-locks. + * As this is the only circumstance where ->l_resource + * can change, and this cannot race with itself, it is safe + * to access lock->l_resource without being careful about locking. */ - spin_lock(&lock->l_lock); oldres = lock->l_resource; if (oldres < newres) { lock_res(oldres); @@ -549,9 +559,9 @@ int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock, } LASSERT(memcmp(new_resid, &oldres->lr_name, sizeof oldres->lr_name) != 0); - lock->l_resource = newres; + rcu_assign_pointer(lock->l_resource, newres); unlock_res(oldres); - unlock_res_and_lock(lock); + unlock_res(newres); /* ...and the flowers are still standing! */ lu_ref_del(&oldres->lr_reference, "lock", lock); @@ -589,7 +599,10 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, LASSERT(handle); - lock = class_handle2object(handle->cookie, NULL); + if (!lustre_handle_is_used(handle)) + RETURN(NULL); + + lock = class_handle2object(handle->cookie, lock_handle_owner); if (lock == NULL) RETURN(NULL); @@ -603,7 +616,7 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, /* It's unlikely but possible that someone marked the lock as * destroyed after we did handle2object on it */ if ((flags == 0) && !ldlm_is_destroyed(lock)) { - lu_ref_add(&lock->l_reference, "handle", current); + lu_ref_add_atomic(&lock->l_reference, "handle", lock); RETURN(lock); } @@ -611,7 +624,7 @@ struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle, LASSERT(lock->l_resource != NULL); - lu_ref_add_atomic(&lock->l_reference, "handle", current); + lu_ref_add_atomic(&lock->l_reference, "handle", lock); if (unlikely(ldlm_is_destroyed(lock))) { unlock_res_and_lock(lock); CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock); @@ -830,14 +843,15 @@ void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock, */ void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode) { - struct ldlm_namespace *ns; - ENTRY; + struct ldlm_namespace *ns; - lock_res_and_lock(lock); + ENTRY; + + lock_res_and_lock(lock); - ns = ldlm_lock_to_ns(lock); + ns = ldlm_lock_to_ns(lock); - ldlm_lock_decref_internal_nolock(lock, mode); + ldlm_lock_decref_internal_nolock(lock, mode); if ((ldlm_is_local(lock) || lock->l_req_mode == LCK_GROUP) && !lock->l_readers && !lock->l_writers) { @@ -854,52 +868,49 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode) } if (!lock->l_readers && !lock->l_writers && ldlm_is_cbpending(lock)) { + unsigned int mask = D_DLMTRACE; + /* If we received a blocked AST and this was the last reference, * run the callback. */ if (ldlm_is_ns_srv(lock) && lock->l_export) - CERROR("FL_CBPENDING set on non-local lock--just a " - "warning\n"); - - LDLM_DEBUG(lock, "final decref done on cbpending lock"); + mask |= D_WARNING; + LDLM_DEBUG_LIMIT(mask, lock, + "final decref done on %sCBPENDING lock", + mask & D_WARNING ? "non-local " : ""); - LDLM_LOCK_GET(lock); /* dropped by bl thread */ - ldlm_lock_remove_from_lru(lock); - unlock_res_and_lock(lock); + LDLM_LOCK_GET(lock); /* dropped by bl thread */ + ldlm_lock_remove_from_lru(lock); + unlock_res_and_lock(lock); if (ldlm_is_fail_loc(lock)) - OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE); + OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE); if (ldlm_is_atomic_cb(lock) || ldlm_bl_to_thread_lock(ns, NULL, lock) != 0) - ldlm_handle_bl_callback(ns, NULL, lock); + ldlm_handle_bl_callback(ns, NULL, lock); } else if (ns_is_client(ns) && - !lock->l_readers && !lock->l_writers && + !lock->l_readers && !lock->l_writers && !ldlm_is_no_lru(lock) && !ldlm_is_bl_ast(lock) && !ldlm_is_converting(lock)) { - LDLM_DEBUG(lock, "add lock into lru list"); - - /* If this is a client-side namespace and this was the last - * reference, put it on the LRU. */ - ldlm_lock_add_to_lru(lock); - unlock_res_and_lock(lock); + /* If this is a client-side namespace and this was the last + * reference, put it on the LRU. + */ + ldlm_lock_add_to_lru(lock); + unlock_res_and_lock(lock); + LDLM_DEBUG(lock, "add lock into lru list"); if (ldlm_is_fail_loc(lock)) - OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE); - - /* Call ldlm_cancel_lru() only if EARLY_CANCEL and LRU RESIZE - * are not supported by the server, otherwise, it is done on - * enqueue. */ - if (!exp_connect_cancelset(lock->l_conn_export) && - !ns_connect_lru_resize(ns)) - ldlm_cancel_lru(ns, 0, LCF_ASYNC, 0); - } else { - LDLM_DEBUG(lock, "do not add lock into lru list"); - unlock_res_and_lock(lock); - } + OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE); - EXIT; + ldlm_pool_recalc(&ns->ns_pool, true); + } else { + LDLM_DEBUG(lock, "do not add lock into lru list"); + unlock_res_and_lock(lock); + } + + EXIT; } /** @@ -1035,7 +1046,6 @@ static void search_granted_lock(struct list_head *queue, prev->mode_link = &req->l_sl_mode; prev->policy_link = &req->l_sl_policy; EXIT; - return; } /** @@ -1084,7 +1094,7 @@ void ldlm_grant_lock_with_skiplist(struct ldlm_lock *lock) { struct sl_insert_point prev; - LASSERT(lock->l_req_mode == lock->l_granted_mode); + LASSERT(ldlm_is_granted(lock)); search_granted_lock(&lock->l_resource->lr_granted, lock, &prev); ldlm_granted_list_add_lock(lock, &prev); @@ -1138,36 +1148,26 @@ void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list) } /** - * Describe the overlap between two locks. itree_overlap_cb data. - */ -struct lock_match_data { - struct ldlm_lock *lmd_old; - struct ldlm_lock *lmd_lock; - enum ldlm_mode *lmd_mode; - union ldlm_policy_data *lmd_policy; - __u64 lmd_flags; - int lmd_unref; -}; - -/** * Check if the given @lock meets the criteria for a match. * A reference on the lock is taken if matched. * - * \param lock test-against this lock - * \param data parameters + * @lock test-against this lock + * @data parameters + * + * RETURN returns true if @lock matches @data, false otherwise */ -static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) +static bool lock_matches(struct ldlm_lock *lock, struct ldlm_match_data *data) { union ldlm_policy_data *lpol = &lock->l_policy_data; - enum ldlm_mode match; + enum ldlm_mode match = LCK_MINMODE; if (lock == data->lmd_old) - return INTERVAL_ITER_STOP; + return true; /* Check if this lock can be matched. * Used by LU-2919(exclusive open) for open lease lock */ if (ldlm_is_excl(lock)) - return INTERVAL_ITER_CONT; + return false; /* llite sometimes wants to match locks that will be * canceled when their users drop, but we allow it to match @@ -1177,25 +1177,39 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) * can still happen. */ if (ldlm_is_cbpending(lock) && !(data->lmd_flags & LDLM_FL_CBPENDING)) - return INTERVAL_ITER_CONT; - if (!data->lmd_unref && ldlm_is_cbpending(lock) && + return false; + + if (!(data->lmd_match & LDLM_MATCH_UNREF) && ldlm_is_cbpending(lock) && lock->l_readers == 0 && lock->l_writers == 0) - return INTERVAL_ITER_CONT; + return false; if (!(lock->l_req_mode & *data->lmd_mode)) - return INTERVAL_ITER_CONT; + return false; + + /* When we search for ast_data, we are not doing a traditional match, + * so we don't worry about IBITS or extent matching. + */ + if (data->lmd_match & (LDLM_MATCH_AST | LDLM_MATCH_AST_ANY)) { + if (!lock->l_ast_data) + return false; + + if (data->lmd_match & LDLM_MATCH_AST_ANY) + goto matched; + } + match = lock->l_req_mode; switch (lock->l_resource->lr_type) { case LDLM_EXTENT: - if (lpol->l_extent.start > data->lmd_policy->l_extent.start || - lpol->l_extent.end < data->lmd_policy->l_extent.end) - return INTERVAL_ITER_CONT; + if (!(data->lmd_match & LDLM_MATCH_RIGHT) && + (lpol->l_extent.start > data->lmd_policy->l_extent.start || + lpol->l_extent.end < data->lmd_policy->l_extent.end)) + return false; if (unlikely(match == LCK_GROUP) && data->lmd_policy->l_extent.gid != LDLM_GID_ANY && lpol->l_extent.gid != data->lmd_policy->l_extent.gid) - return INTERVAL_ITER_CONT; + return false; break; case LDLM_IBITS: /* We match if we have existing lock with same or wider set @@ -1203,7 +1217,13 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) if ((lpol->l_inodebits.bits & data->lmd_policy->l_inodebits.bits) != data->lmd_policy->l_inodebits.bits) - return INTERVAL_ITER_CONT; + return false; + + if (unlikely(match == LCK_GROUP) && + data->lmd_policy->l_inodebits.li_gid != LDLM_GID_ANY && + lpol->l_inodebits.li_gid != + data->lmd_policy->l_inodebits.li_gid) + return false; break; default: ; @@ -1211,12 +1231,17 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) /* We match if we have existing lock with same or wider set of bits. */ - if (!data->lmd_unref && LDLM_HAVE_MASK(lock, GONE)) - return INTERVAL_ITER_CONT; + if (!(data->lmd_match & LDLM_MATCH_UNREF) && LDLM_HAVE_MASK(lock, GONE)) + return false; if (!equi(data->lmd_flags & LDLM_FL_LOCAL_ONLY, ldlm_is_local(lock))) - return INTERVAL_ITER_CONT; + return false; + /* Filter locks by skipping flags */ + if (data->lmd_skip_flags & lock->l_flags) + return false; + +matched: if (data->lmd_flags & LDLM_FL_TEST_LOCK) { LDLM_LOCK_GET(lock); ldlm_lock_touch_in_lru(lock); @@ -1227,19 +1252,17 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data) *data->lmd_mode = match; data->lmd_lock = lock; - return INTERVAL_ITER_STOP; + return true; } static unsigned int itree_overlap_cb(struct interval_node *in, void *args) { struct ldlm_interval *node = to_ldlm_interval(in); - struct lock_match_data *data = args; + struct ldlm_match_data *data = args; struct ldlm_lock *lock; - int rc; list_for_each_entry(lock, &node->li_group, l_sl_policy) { - rc = lock_matches(lock, data); - if (rc == INTERVAL_ITER_STOP) + if (lock_matches(lock, data)) return INTERVAL_ITER_STOP; } return INTERVAL_ITER_CONT; @@ -1253,8 +1276,8 @@ static unsigned int itree_overlap_cb(struct interval_node *in, void *args) * * \retval a referenced lock or NULL. */ -static struct ldlm_lock *search_itree(struct ldlm_resource *res, - struct lock_match_data *data) +struct ldlm_lock *search_itree(struct ldlm_resource *res, + struct ldlm_match_data *data) { struct interval_node_extent ext = { .start = data->lmd_policy->l_extent.start, @@ -1262,6 +1285,11 @@ static struct ldlm_lock *search_itree(struct ldlm_resource *res, }; int idx; + data->lmd_lock = NULL; + + if (data->lmd_match & LDLM_MATCH_RIGHT) + ext.end = OBD_OBJECT_EOF; + for (idx = 0; idx < LCK_MODE_NUM; idx++) { struct ldlm_interval_tree *tree = &res->lr_itree[idx]; @@ -1273,9 +1301,13 @@ static struct ldlm_lock *search_itree(struct ldlm_resource *res, interval_search(tree->lit_root, &ext, itree_overlap_cb, data); + if (data->lmd_lock) + return data->lmd_lock; } - return data->lmd_lock; + + return NULL; } +EXPORT_SYMBOL(search_itree); /** @@ -1287,16 +1319,16 @@ static struct ldlm_lock *search_itree(struct ldlm_resource *res, * \retval a referenced lock or NULL. */ static struct ldlm_lock *search_queue(struct list_head *queue, - struct lock_match_data *data) + struct ldlm_match_data *data) { struct ldlm_lock *lock; - int rc; - list_for_each_entry(lock, queue, l_res_link) { - rc = lock_matches(lock, data); - if (rc == INTERVAL_ITER_STOP) + data->lmd_lock = NULL; + + list_for_each_entry(lock, queue, l_res_link) + if (lock_matches(lock, data)) return data->lmd_lock; - } + return NULL; } @@ -1304,7 +1336,7 @@ void ldlm_lock_fail_match_locked(struct ldlm_lock *lock) { if ((lock->l_flags & LDLM_FL_FAIL_NOTIFIED) == 0) { lock->l_flags |= LDLM_FL_FAIL_NOTIFIED; - wake_up_all(&lock->l_waitq); + wake_up(&lock->l_waitq); } } EXPORT_SYMBOL(ldlm_lock_fail_match_locked); @@ -1326,7 +1358,7 @@ void ldlm_lock_fail_match(struct ldlm_lock *lock) void ldlm_lock_allow_match_locked(struct ldlm_lock *lock) { ldlm_set_lvb_ready(lock); - wake_up_all(&lock->l_waitq); + wake_up(&lock->l_waitq); } EXPORT_SYMBOL(ldlm_lock_allow_match_locked); @@ -1372,24 +1404,28 @@ EXPORT_SYMBOL(ldlm_lock_allow_match); * keep caller code unchanged), the context failure will be discovered by * caller sometime later. */ -enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags, - const struct ldlm_res_id *res_id, - enum ldlm_type type, - union ldlm_policy_data *policy, - enum ldlm_mode mode, - struct lustre_handle *lockh, int unref) -{ - struct lock_match_data data = { - .lmd_old = NULL, - .lmd_lock = NULL, - .lmd_mode = &mode, - .lmd_policy = policy, - .lmd_flags = flags, - .lmd_unref = unref, +enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns, + __u64 flags, __u64 skip_flags, + const struct ldlm_res_id *res_id, + enum ldlm_type type, + union ldlm_policy_data *policy, + enum ldlm_mode mode, + struct lustre_handle *lockh, + enum ldlm_match_flags match_flags) +{ + struct ldlm_match_data data = { + .lmd_old = NULL, + .lmd_lock = NULL, + .lmd_mode = &mode, + .lmd_policy = policy, + .lmd_flags = flags, + .lmd_skip_flags = skip_flags, + .lmd_match = match_flags, }; struct ldlm_resource *res; struct ldlm_lock *lock; - int rc = 0; + int matched; + ENTRY; if (ns == NULL) { @@ -1410,98 +1446,76 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags, LDLM_RESOURCE_ADDREF(res); lock_res(res); - if (res->lr_type == LDLM_EXTENT) lock = search_itree(res, &data); else lock = search_queue(&res->lr_granted, &data); - if (lock != NULL) - GOTO(out, rc = 1); - if (flags & LDLM_FL_BLOCK_GRANTED) - GOTO(out, rc = 0); - lock = search_queue(&res->lr_waiting, &data); - if (lock != NULL) - GOTO(out, rc = 1); - - EXIT; - out: - unlock_res(res); - LDLM_RESOURCE_DELREF(res); - ldlm_resource_putref(res); + if (!lock && !(flags & LDLM_FL_BLOCK_GRANTED)) + lock = search_queue(&res->lr_waiting, &data); + matched = lock ? mode : 0; + unlock_res(res); + LDLM_RESOURCE_DELREF(res); + ldlm_resource_putref(res); - if (lock) { - ldlm_lock2handle(lock, lockh); - if ((flags & LDLM_FL_LVB_READY) && + if (lock) { + ldlm_lock2handle(lock, lockh); + if ((flags & LDLM_FL_LVB_READY) && (!ldlm_is_lvb_ready(lock))) { __u64 wait_flags = LDLM_FL_LVB_READY | LDLM_FL_DESTROYED | LDLM_FL_FAIL_NOTIFIED; - struct l_wait_info lwi; - if (lock->l_completion_ast) { - int err = lock->l_completion_ast(lock, - LDLM_FL_WAIT_NOREPROC, - NULL); - if (err) { - if (flags & LDLM_FL_TEST_LOCK) - LDLM_LOCK_RELEASE(lock); - else - ldlm_lock_decref_internal(lock, - mode); - rc = 0; - goto out2; - } - } - lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(obd_timeout), - NULL, LWI_ON_SIGNAL_NOOP, NULL); - - /* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */ - l_wait_event(lock->l_waitq, - lock->l_flags & wait_flags, - &lwi); - if (!ldlm_is_lvb_ready(lock)) { - if (flags & LDLM_FL_TEST_LOCK) - LDLM_LOCK_RELEASE(lock); - else - ldlm_lock_decref_internal(lock, mode); - rc = 0; - } - } - } - out2: - if (rc) { - LDLM_DEBUG(lock, "matched (%llu %llu)", - (type == LDLM_PLAIN || type == LDLM_IBITS) ? - res_id->name[2] : policy->l_extent.start, - (type == LDLM_PLAIN || type == LDLM_IBITS) ? - res_id->name[3] : policy->l_extent.end); - - /* check user's security context */ - if (lock->l_conn_export && - sptlrpc_import_check_ctx( - class_exp2cliimp(lock->l_conn_export))) { - if (!(flags & LDLM_FL_TEST_LOCK)) - ldlm_lock_decref_internal(lock, mode); - rc = 0; - } + if (lock->l_completion_ast) { + int err = lock->l_completion_ast(lock, + LDLM_FL_WAIT_NOREPROC, + NULL); + if (err) + GOTO(out_fail_match, matched = 0); + } + + wait_event_idle_timeout( + lock->l_waitq, + lock->l_flags & wait_flags, + cfs_time_seconds(obd_timeout)); - if (flags & LDLM_FL_TEST_LOCK) - LDLM_LOCK_RELEASE(lock); + if (!ldlm_is_lvb_ready(lock)) + GOTO(out_fail_match, matched = 0); + } + + /* check user's security context */ + if (lock->l_conn_export && + sptlrpc_import_check_ctx( + class_exp2cliimp(lock->l_conn_export))) + GOTO(out_fail_match, matched = 0); + + LDLM_DEBUG(lock, "matched (%llu %llu)", + (type == LDLM_PLAIN || type == LDLM_IBITS) ? + res_id->name[2] : policy->l_extent.start, + (type == LDLM_PLAIN || type == LDLM_IBITS) ? + res_id->name[3] : policy->l_extent.end); + +out_fail_match: + if (flags & LDLM_FL_TEST_LOCK) + LDLM_LOCK_RELEASE(lock); + else if (!matched) + ldlm_lock_decref_internal(lock, mode); + } - } else if (!(flags & LDLM_FL_TEST_LOCK)) {/*less verbose for test-only*/ - LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res " + /* less verbose for test-only */ + if (!matched && !(flags & LDLM_FL_TEST_LOCK)) { + LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res " "%llu/%llu (%llu %llu)", ns, - type, mode, res_id->name[0], res_id->name[1], - (type == LDLM_PLAIN || type == LDLM_IBITS) ? - res_id->name[2] :policy->l_extent.start, - (type == LDLM_PLAIN || type == LDLM_IBITS) ? - res_id->name[3] : policy->l_extent.end); - } + type, mode, res_id->name[0], res_id->name[1], + (type == LDLM_PLAIN || type == LDLM_IBITS) ? + res_id->name[2] : policy->l_extent.start, + (type == LDLM_PLAIN || type == LDLM_IBITS) ? + res_id->name[3] : policy->l_extent.end); + } if (data.lmd_old != NULL) LDLM_LOCK_PUT(data.lmd_old); - return rc ? mode : 0; + return matched; } -EXPORT_SYMBOL(ldlm_lock_match); +EXPORT_SYMBOL(ldlm_lock_match_with_skip); enum ldlm_mode ldlm_revalidate_lock_handle(const struct lustre_handle *lockh, __u64 *bits) @@ -1663,7 +1677,7 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns, lock->l_req_mode = mode; lock->l_ast_data = data; - lock->l_pid = current_pid(); + lock->l_pid = current->pid; if (ns_is_server(ns)) ldlm_set_ns_srv(lock); if (cbs) { @@ -1672,11 +1686,18 @@ struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns, 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; @@ -1703,19 +1724,16 @@ static enum ldlm_error ldlm_lock_enqueue_helper(struct ldlm_lock *lock, { struct ldlm_resource *res = lock->l_resource; enum ldlm_error rc = ELDLM_OK; - struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); + LIST_HEAD(rpc_list); ldlm_processing_policy policy; + ENTRY; - policy = ldlm_processing_policy_table[res->lr_type]; -restart: + policy = ldlm_get_processing_policy(res); policy(lock, flags, LDLM_PROCESS_ENQUEUE, &rc, &rpc_list); if (rc == ELDLM_OK && lock->l_granted_mode != lock->l_req_mode && - res->lr_type != LDLM_FLOCK) { + res->lr_type != LDLM_FLOCK) rc = ldlm_handle_conflict_lock(lock, flags, &rpc_list); - if (rc == -ERESTART) - GOTO(restart, rc); - } if (!list_empty(&rpc_list)) ldlm_discard_bl_list(&rpc_list); @@ -1740,10 +1758,13 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env, void *cookie, __u64 *flags) { struct ldlm_lock *lock = *lockp; - struct ldlm_resource *res = lock->l_resource; - int local = ns_is_client(ldlm_res_to_ns(res)); + struct ldlm_resource *res; + int local = ns_is_client(ns); enum ldlm_error rc = ELDLM_OK; struct ldlm_interval *node = NULL; +#ifdef HAVE_SERVER_SUPPORT + bool reconstruct = false; +#endif ENTRY; /* policies are not executed on the client or during replay */ @@ -1763,7 +1784,7 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env, *flags |= LDLM_FL_LOCK_CHANGED; RETURN(0); } else if (rc != ELDLM_OK && - lock->l_req_mode == lock->l_granted_mode) { + ldlm_is_granted(lock)) { LASSERT(*flags & LDLM_FL_RESENT); /* It may happen that ns_policy returns an error in * resend case, object may be unlinked or just some @@ -1786,21 +1807,39 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env, * Take NO_TIMEOUT from the lock as it is inherited through * LDLM_FL_INHERIT_MASK */ *flags |= LDLM_FL_LOCK_CHANGED; - if (lock->l_req_mode != lock->l_granted_mode) + if (!ldlm_is_granted(lock)) *flags |= LDLM_FL_BLOCK_GRANTED; *flags |= lock->l_flags & LDLM_FL_NO_TIMEOUT; RETURN(ELDLM_OK); } +#ifdef HAVE_SERVER_SUPPORT /* For a replaying lock, it might be already in granted list. So * unlinking the lock will cause the interval node to be freed, we * have to allocate the interval node early otherwise we can't regrant - * this lock in the future. - jay */ - if (!local && (*flags & LDLM_FL_REPLAY) && res->lr_type == LDLM_EXTENT) + * this lock in the future. - jay + * + * The only time the ldlm_resource changes for the ldlm_lock is when + * ldlm_lock_change_resource() is called and that only happens for + * the Lustre client case. + */ + if (!local && (*flags & LDLM_FL_REPLAY) && + lock->l_resource->lr_type == LDLM_EXTENT) OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, GFP_NOFS); - lock_res_and_lock(lock); - if (local && lock->l_req_mode == lock->l_granted_mode) { + reconstruct = !local && lock->l_resource->lr_type == LDLM_FLOCK && + !(*flags & LDLM_FL_TEST_LOCK); + if (reconstruct) { + rc = req_can_reconstruct(cookie, NULL); + if (rc != 0) { + if (rc == 1) + rc = 0; + RETURN(rc); + } + } +#endif + res = lock_res_and_lock(lock); + if (local && ldlm_is_granted(lock)) { /* The server returned a blocked lock, but it was granted * before we got a chance to actually enqueue it. We don't * need to do anything else. */ @@ -1872,6 +1911,16 @@ enum ldlm_error ldlm_lock_enqueue(const struct lu_env *env, out: unlock_res_and_lock(lock); + +#ifdef HAVE_SERVER_SUPPORT + if (reconstruct) { + struct ptlrpc_request *req = cookie; + + tgt_mk_reply_data(NULL, NULL, + &req->rq_export->exp_target_data, + req, 0, NULL, false, 0); + } +#endif if (node) OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node)); return rc; @@ -1886,19 +1935,20 @@ out: */ 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, __u64 hint) { struct list_head *tmp, *pos; ldlm_processing_policy policy; __u64 flags; int rc = LDLM_ITER_CONTINUE; enum ldlm_error err; - struct list_head bl_ast_list = LIST_HEAD_INIT(bl_ast_list); + LIST_HEAD(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); @@ -1906,7 +1956,7 @@ int ldlm_reprocess_queue(struct ldlm_resource *res, struct list_head *queue, restart: list_for_each_safe(tmp, pos, queue) { struct ldlm_lock *pending; - struct list_head rpc_list = LIST_HEAD_INIT(rpc_list); + LIST_HEAD(rpc_list); pending = list_entry(tmp, struct ldlm_lock, l_res_link); @@ -1986,6 +2036,9 @@ int ldlm_handle_conflict_lock(struct ldlm_lock *lock, __u64 *flags, !ns_is_client(ldlm_res_to_ns(res))) class_fail_export(lock->l_export); + if (rc == -ERESTART) + ldlm_reprocess_all(res, 0); + lock_res(res); if (rc == -ERESTART) { /* 15715: The lock was granted and destroyed after @@ -1997,7 +2050,7 @@ int ldlm_handle_conflict_lock(struct ldlm_lock *lock, __u64 *flags, RETURN(-EAGAIN); /* lock was granted while resource was unlocked. */ - if (lock->l_granted_mode == lock->l_req_mode) { + if (ldlm_is_granted(lock)) { /* bug 11300: if the lock has been granted, * break earlier because otherwise, we will go * to restart and ldlm_resource_unlink will be @@ -2005,10 +2058,8 @@ int ldlm_handle_conflict_lock(struct ldlm_lock *lock, __u64 *flags, * freed. Then we will fail at * ldlm_extent_add_lock() */ *flags &= ~LDLM_FL_BLOCKED_MASK; - RETURN(0); } - RETURN(rc); } *flags |= LDLM_FL_BLOCK_GRANTED; @@ -2160,8 +2211,11 @@ int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) arg->gl_interpret_data = gl_work->gl_interpret_data; /* invoke the actual glimpse callback */ - if (lock->l_glimpse_ast(lock, (void*)arg) == 0) - rc = 1; + rc = lock->l_glimpse_ast(lock, (void *)arg); + if (rc == 0) + rc = 1; /* update LVB if this is server lock */ + else if (rc == -ELDLM_NO_LOCK_DATA) + ldlm_lvbo_update(lock->l_resource, lock, NULL, 1); LDLM_LOCK_RELEASE(lock); if (gl_work->gl_flags & LDLM_GL_WORK_SLAB_ALLOCATED) @@ -2293,20 +2347,22 @@ out: * 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, + __u64 hint) { - struct list_head rpc_list; + LIST_HEAD(rpc_list); #ifdef HAVE_SERVER_SUPPORT + ldlm_reprocessing_policy reprocess; struct obd_device *obd; - int rc; - ENTRY; + int rc; - INIT_LIST_HEAD(&rpc_list); - /* Local lock trees don't get reprocessed. */ - if (ns_is_client(ldlm_res_to_ns(res))) { - EXIT; - return; - } + ENTRY; + + /* 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. @@ -2317,31 +2373,32 @@ static void __ldlm_reprocess_all(struct ldlm_resource *res, 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, LDLM_WORK_CP_AST); if (rc == -ERESTART) { LASSERT(list_empty(&rpc_list)); + hint = 0; 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, __u64 hint) { - __ldlm_reprocess_all(res, LDLM_PROCESS_RESCAN); + __ldlm_reprocess_all(res, LDLM_PROCESS_RESCAN, hint); } EXPORT_SYMBOL(ldlm_reprocess_all); @@ -2351,7 +2408,7 @@ static int ldlm_reprocess_res(struct cfs_hash *hs, struct cfs_hash_bd *bd, 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, 0); return 0; } @@ -2380,24 +2437,22 @@ void ldlm_cancel_callback(struct ldlm_lock *lock) if (!ldlm_is_cancel(lock)) { ldlm_set_cancel(lock); if (lock->l_blocking_ast) { - unlock_res_and_lock(lock); - lock->l_blocking_ast(lock, NULL, lock->l_ast_data, - LDLM_CB_CANCELING); - lock_res_and_lock(lock); - } else { - LDLM_DEBUG(lock, "no blocking ast"); - } + unlock_res_and_lock(lock); + lock->l_blocking_ast(lock, NULL, lock->l_ast_data, + LDLM_CB_CANCELING); + lock_res_and_lock(lock); + } else { + LDLM_DEBUG(lock, "no blocking ast"); + } /* only canceller can set bl_done bit */ ldlm_set_bl_done(lock); - wake_up_all(&lock->l_waitq); + wake_up(&lock->l_waitq); } else if (!ldlm_is_bl_done(lock)) { - struct l_wait_info lwi = { 0 }; - /* The lock is guaranteed to have been canceled once * returning from this function. */ unlock_res_and_lock(lock); - l_wait_event(lock->l_waitq, is_bl_done(lock), &lwi); + wait_event_idle(lock->l_waitq, is_bl_done(lock)); lock_res_and_lock(lock); } } @@ -2451,8 +2506,8 @@ void ldlm_lock_cancel(struct ldlm_lock *lock) ldlm_resource_unlink_lock(lock); ldlm_lock_destroy_nolock(lock); - if (lock->l_granted_mode == lock->l_req_mode) - ldlm_pool_del(&ns->ns_pool, lock); + if (ldlm_is_granted(lock)) + ldlm_pool_del(&ns->ns_pool, lock); /* Make sure we will not be called again for same lock what is possible * if not to zero out lock->l_granted_mode */ @@ -2497,10 +2552,10 @@ static void ldlm_cancel_lock_for_export(struct obd_export *exp, res = ldlm_resource_getref(lock->l_resource); - ldlm_lvbo_update(ecl->ecl_env, res, lock, NULL, 1); + 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->l_policy_data.l_inodebits.bits); ldlm_resource_putref(res); ecl->ecl_loop++; @@ -2615,7 +2670,7 @@ int ldlm_export_cancel_locks(struct obd_export *exp) } /** - * Downgrade an PW/EX lock to COS mode. + * Downgrade an PW/EX lock to COS | CR mode. * * A lock mode convertion from PW/EX mode to less conflict mode. The * convertion may fail if lock was canceled before downgrade, but it doesn't @@ -2627,6 +2682,8 @@ int ldlm_export_cancel_locks(struct obd_export *exp) * things are cleared, so any pending or new blocked lock on that lock will * cause new call to blocking_ast and force resource object commit. * + * Also used by layout_change to replace EX lock to CR lock. + * * \param lock A lock to convert * \param new_mode new lock mode */ @@ -2635,7 +2692,7 @@ void ldlm_lock_mode_downgrade(struct ldlm_lock *lock, enum ldlm_mode new_mode) #ifdef HAVE_SERVER_SUPPORT ENTRY; - LASSERT(new_mode == LCK_COS); + LASSERT(new_mode == LCK_COS || new_mode == LCK_CR); lock_res_and_lock(lock); @@ -2663,7 +2720,8 @@ void ldlm_lock_mode_downgrade(struct ldlm_lock *lock, enum ldlm_mode new_mode) ldlm_grant_lock(lock, NULL); unlock_res_and_lock(lock); - ldlm_reprocess_all(lock->l_resource); + ldlm_reprocess_all(lock->l_resource, + lock->l_policy_data.l_inodebits.bits); EXIT; #endif @@ -2703,19 +2761,18 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, va_list args; struct obd_export *exp = lock->l_export; struct ldlm_resource *resource = NULL; + struct va_format vaf; char *nid = "local"; - /* on server-side resource of lock doesn't change */ - if ((lock->l_flags & LDLM_FL_NS_SRV) != 0) { - if (lock->l_resource != NULL) - resource = ldlm_resource_getref(lock->l_resource); - } else if (spin_trylock(&lock->l_lock)) { - if (lock->l_resource != NULL) - resource = ldlm_resource_getref(lock->l_resource); - spin_unlock(&lock->l_lock); - } + rcu_read_lock(); + resource = rcu_dereference(lock->l_resource); + if (resource && !atomic_inc_not_zero(&resource->lr_refcount)) + resource = NULL; + rcu_read_unlock(); va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; if (exp && exp->exp_connection) { nid = obd_export_nid2str(exp); @@ -2725,111 +2782,112 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, } if (resource == NULL) { - libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lld " - "lvb_type: %d\n", - lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type); + libcfs_debug_msg(msgdata, + "%pV ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n", + &vaf, + lock, + lock->l_handle.h_cookie, + refcount_read(&lock->l_handle.h_ref), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + lock->l_flags, nid, + lock->l_remote_handle.cookie, + exp ? refcount_read(&exp->exp_handle.h_ref) : -99, + lock->l_pid, lock->l_callback_timestamp, + lock->l_lvb_type); va_end(args); return; } switch (resource->lr_type) { case LDLM_EXTENT: - libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s [%llu->%llu] " - "(req %llu->%llu) flags: %#llx nid: %s remote: " - "%#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_extent.start, - lock->l_policy_data.l_extent.end, - lock->l_req_extent.start, lock->l_req_extent.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + libcfs_debug_msg(msgdata, + "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s [%llu->%llu] (req %llu->%llu) gid %llu flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n", + &vaf, + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, + refcount_read(&lock->l_handle.h_ref), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_extent.start, + lock->l_policy_data.l_extent.end, + lock->l_req_extent.start, lock->l_req_extent.end, + lock->l_req_extent.gid, + lock->l_flags, nid, + lock->l_remote_handle.cookie, + exp ? refcount_read(&exp->exp_handle.h_ref) : -99, + lock->l_pid, lock->l_callback_timestamp, + lock->l_lvb_type); break; case LDLM_FLOCK: - libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s pid: %d " - "[%llu->%llu] flags: %#llx nid: %s " - "remote: %#llx expref: %d pid: %u timeout: %lld\n", - ldlm_lock_to_ns_name(lock), lock, - lock->l_handle.h_cookie, atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_policy_data.l_flock.pid, - lock->l_policy_data.l_flock.start, - lock->l_policy_data.l_flock.end, - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout); + libcfs_debug_msg(msgdata, + "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s pid: %d [%llu->%llu] flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld\n", + &vaf, + ldlm_lock_to_ns_name(lock), lock, + lock->l_handle.h_cookie, + refcount_read(&lock->l_handle.h_ref), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_flock.pid, + lock->l_policy_data.l_flock.start, + lock->l_policy_data.l_flock.end, + lock->l_flags, nid, + lock->l_remote_handle.cookie, + exp ? refcount_read(&exp->exp_handle.h_ref) : -99, + lock->l_pid, lock->l_callback_timestamp); break; case LDLM_IBITS: - libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" bits %#llx/%#llx rrc: %d type: %s " - "flags: %#llx nid: %s remote: %#llx expref: %d " - "pid: %u timeout: %lld lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - lock->l_policy_data.l_inodebits.bits, - lock->l_policy_data.l_inodebits.try_bits, - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + libcfs_debug_msg(msgdata, + "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " bits %#llx/%#llx rrc: %d type: %s gid %llu flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n", + &vaf, + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + refcount_read(&lock->l_handle.h_ref), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + lock->l_policy_data.l_inodebits.bits, + lock->l_policy_data.l_inodebits.try_bits, + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_policy_data.l_inodebits.li_gid, + lock->l_flags, nid, + lock->l_remote_handle.cookie, + exp ? refcount_read(&exp->exp_handle.h_ref) : -99, + lock->l_pid, lock->l_callback_timestamp, + lock->l_lvb_type); break; default: - libcfs_debug_vmsg2(msgdata, fmt, args, - " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s " - "res: "DLDLMRES" rrc: %d type: %s flags: %#llx " - "nid: %s remote: %#llx expref: %d pid: %u " - "timeout: %lld lvb_type: %d\n", - ldlm_lock_to_ns_name(lock), - lock, lock->l_handle.h_cookie, - atomic_read(&lock->l_refc), - lock->l_readers, lock->l_writers, - ldlm_lockname[lock->l_granted_mode], - ldlm_lockname[lock->l_req_mode], - PLDLMRES(resource), - atomic_read(&resource->lr_refcount), - ldlm_typename[resource->lr_type], - lock->l_flags, nid, lock->l_remote_handle.cookie, - exp ? atomic_read(&exp->exp_refcount) : -99, - lock->l_pid, lock->l_callback_timeout, - lock->l_lvb_type); + libcfs_debug_msg(msgdata, + "%pV ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s res: " DLDLMRES " rrc: %d type: %s flags: %#llx nid: %s remote: %#llx expref: %d pid: %u timeout: %lld lvb_type: %d\n", + &vaf, + ldlm_lock_to_ns_name(lock), + lock, lock->l_handle.h_cookie, + refcount_read(&lock->l_handle.h_ref), + lock->l_readers, lock->l_writers, + ldlm_lockname[lock->l_granted_mode], + ldlm_lockname[lock->l_req_mode], + PLDLMRES(resource), + atomic_read(&resource->lr_refcount), + ldlm_typename[resource->lr_type], + lock->l_flags, nid, + lock->l_remote_handle.cookie, + exp ? refcount_read(&exp->exp_handle.h_ref) : -99, + lock->l_pid, lock->l_callback_timestamp, + lock->l_lvb_type); break; } va_end(args);