28 #include <linux/module.h>
30 #include <linux/types.h>
33 #include <linux/sysctl.h>
34 #include <linux/random.h>
36 #include <linux/socket.h>
48 #define MLOG_MASK_PREFIX ML_DLM
51 #define DLM_UNLOCK_FREE_LOCK 0x00000001
52 #define DLM_UNLOCK_CALL_AST 0x00000002
53 #define DLM_UNLOCK_REMOVE_LOCK 0x00000004
54 #define DLM_UNLOCK_REGRANT_LOCK 0x00000008
55 #define DLM_UNLOCK_CLEAR_CONVERT_TYPE 0x00000010
102 int flags,
int *call_ast,
110 mlog(0,
"master_node = %d, valblk = %d\n", master_node,
121 in_use = !list_empty(&lock->
ast_list);
124 mlog(
ML_ERROR,
"lockres %.*s: Someone is calling dlmunlock "
125 "while waiting for an ast!", res->
lockname.len,
132 if (master_node && !(flags & LKM_CANCEL)) {
138 __dlm_wait_on_lockres(res);
155 if (flags & LKM_CANCEL)
156 status = dlm_get_cancel_actions(dlm, res, lock, lksb, &actions);
158 status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
176 if (flags & LKM_CANCEL)
182 status = dlm_send_remote_unlock_request(dlm, res, lock, lksb,
198 mlog(0,
"%s:%.*s: clearing actions, %s\n",
206 if (flags & LKM_CANCEL)
218 list_del_init(&lock->
list);
226 mlog(0,
"clearing convert_type at %smaster node\n",
227 master_node ?
"" :
"non-");
236 if (!dlm_lock_on_list(&res->
converting, lock))
247 BUG_ON(!(actions & DLM_UNLOCK_REMOVE_LOCK));
248 mlog(0,
"lock %u:%llu should be gone now! refs=%d\n",
269 list_del_init(&lock->
list);
287 return dlmunlock_common(dlm, res, lock, lksb, flags, call_ast, 1);
294 int flags,
int *call_ast)
296 return dlmunlock_common(dlm, res, lock, lksb, flags, call_ast, 0);
326 mlog(0,
"%s:%.*s: this node became the master due to a "
327 "migration, re-evaluate now\n", dlm->
name,
332 memset(&unlock, 0,
sizeof(unlock));
335 unlock.cookie = lock->
ml.cookie;
340 vec[0].iov_base = &unlock;
345 vec[1].iov_base = lock->
lksb->lvb;
350 vec, veclen, owner, &status);
354 mlog(0,
"master was in-progress. retry\n");
357 mlog(
ML_ERROR,
"Error %d when sending message %u (key 0x%x) to "
370 ret = dlm_err_to_dlm_status(tmpret);
403 mlog(
ML_ERROR,
"bad args! GET_LVB specified on unlock!\n");
407 if ((flags & (LKM_PUT_LVB|LKM_CANCEL)) == (LKM_PUT_LVB|LKM_CANCEL)) {
408 mlog(
ML_ERROR,
"bad args! cannot modify lvb on a CANCEL "
414 mlog(
ML_ERROR,
"Invalid name length in unlock handler!\n");
422 "Domain %s not fully joined!\n", dlm->
name);
424 mlog(0,
"lvb: %s\n", flags & LKM_PUT_LVB ?
"put lvb" :
"none");
431 mlog(0,
"returning DLM_FORWARD -- res no longer exists\n");
441 mlog(0,
"returning DLM_RECOVERING\n");
448 mlog(0,
"returning DLM_MIGRATING\n");
455 mlog(0,
"returning DLM_FORWARD -- not master\n");
460 for (
i=0;
i<3;
i++) {
463 if (lock->
ml.cookie == unlock->
cookie &&
483 if (flags & (LKM_VALBLK|LKM_PUT_LVB) &&
488 if (flags & LKM_PUT_LVB) {
495 status = dlmunlock_master(dlm, res, lock, lksb, flags, &ignore);
497 mlog(0,
"lockres is in progress\n");
499 if (flags & LKM_PUT_LVB)
532 if (dlm_lock_on_list(&res->
blocked, lock)) {
535 *actions = (DLM_UNLOCK_CALL_AST |
537 }
else if (dlm_lock_on_list(&res->
converting, lock)) {
540 *actions = (DLM_UNLOCK_CALL_AST |
541 DLM_UNLOCK_REMOVE_LOCK |
542 DLM_UNLOCK_REGRANT_LOCK |
544 }
else if (dlm_lock_on_list(&res->
granted, lock)) {
565 if (!dlm_lock_on_list(&res->
granted, lock)) {
572 *actions = (DLM_UNLOCK_FREE_LOCK |
573 DLM_UNLOCK_CALL_AST |
589 int call_ast, is_master;
601 if ((flags & (LKM_VALBLK | LKM_CANCEL)) == (LKM_VALBLK | LKM_CANCEL)) {
602 mlog(0,
"VALBLK given with CANCEL: ignoring VALBLK\n");
603 flags &= ~LKM_VALBLK;
617 dlm_lockres_get(res);
621 mlog(0,
"lock=%p res=%p\n", lock, res);
626 flags &= ~LKM_VALBLK;
630 status = dlmunlock_master(dlm, res, lock, lksb, flags,
632 mlog(0,
"done calling dlmunlock_master: returned %d, "
633 "call_ast is %d\n", status, call_ast);
635 status = dlmunlock_remote(dlm, res, lock, lksb, flags,
637 mlog(0,
"done calling dlmunlock_remote: returned %d, "
638 "call_ast is %d\n", status, call_ast);
654 mlog(0,
"retrying unlock due to pending recovery/"
655 "migration/in-progress\n");
660 mlog(0,
"calling unlockast(%p, %d)\n", data, status);
679 mlog(0,
"kicking the thread\n");
688 mlog(0,
"returning status=%d!\n", status);