[LCK_CW] "CW",
[LCK_CR] "CR",
[LCK_NL] "NL",
- [LCK_GROUP] "GROUP"
+ [LCK_GROUP] "GROUP",
+ [LCK_COS] "COS"
};
char *ldlm_typename[] = {
lock->l_readers++;
lu_ref_add_atomic(&lock->l_reference, "reader", lock);
}
- if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP)) {
+ if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
lock->l_writers++;
lu_ref_add_atomic(&lock->l_reference, "writer", lock);
}
lu_ref_del(&lock->l_reference, "reader", lock);
lock->l_readers--;
}
- if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP)) {
+ if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
LASSERT(lock->l_writers > 0);
lu_ref_del(&lock->l_reference, "writer", lock);
lock->l_writers--;
ldlm_lock2desc(lock->l_blocking_lock, &d);
- LDLM_LOCK_RELEASE(lock->l_blocking_lock);
- lock->l_blocking_lock = NULL;
lock->l_blocking_ast(lock, &d, (void *)arg,
LDLM_CB_BLOCKING);
+ LDLM_LOCK_RELEASE(lock->l_blocking_lock);
+ lock->l_blocking_lock = NULL;
LDLM_LOCK_RELEASE(lock);
RETURN(1);
ldlm_cancel_locks_for_export_cb, exp);
}
+/**
+ * Downgrade an exclusive lock.
+ *
+ * A fast variant of ldlm_lock_convert for convertion of exclusive
+ * locks. The convertion is always successful.
+ *
+ * \param lock A lock to convert
+ * \param new_mode new lock mode
+ */
+void ldlm_lock_downgrade(struct ldlm_lock *lock, int new_mode)
+{
+ ENTRY;
+
+ LASSERT(lock->l_granted_mode & (LCK_PW | LCK_EX));
+ LASSERT(new_mode == LCK_COS);
+
+ lock_res_and_lock(lock);
+ ldlm_resource_unlink_lock(lock);
+ lock->l_req_mode = new_mode;
+ ldlm_grant_lock(lock, NULL);
+ unlock_res_and_lock(lock);
+ ldlm_reprocess_all(lock->l_resource);
+
+ EXIT;
+}
+
struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
__u32 *flags)
{
if (node == NULL) /* Actually, this causes EDEADLOCK to be returned */
RETURN(NULL);
- LASSERTF(new_mode == LCK_PW && lock->l_granted_mode == LCK_PR,
+ LASSERTF((new_mode == LCK_PW && lock->l_granted_mode == LCK_PR),
"new_mode %u, granted %u\n", new_mode, lock->l_granted_mode);
lock_res_and_lock(lock);