Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54473
b: refs/heads/master
c: 7d3c1fe
h: refs/heads/master
i:
  54471: 5fde2a3
v: v3
  • Loading branch information
David Teigland authored and Steven Whitehouse committed May 1, 2007
1 parent 1b92ffc commit c733c56
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5f8820960cf4fb621483d4a37c24939ad831bfe7
refs/heads/master: 7d3c1feb80913ba4253c3517d48b9b3741c44fc9
82 changes: 80 additions & 2 deletions trunk/fs/dlm/lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ static inline int is_demoted(struct dlm_lkb *lkb)
return (lkb->lkb_sbflags & DLM_SBF_DEMOTED);
}

static inline int is_altmode(struct dlm_lkb *lkb)
{
return (lkb->lkb_sbflags & DLM_SBF_ALTMODE);
}

static inline int is_granted(struct dlm_lkb *lkb)
{
return (lkb->lkb_status == DLM_LKSTS_GRANTED);
}

static inline int is_remote(struct dlm_rsb *r)
{
DLM_ASSERT(r->res_nodeid >= 0, dlm_print_rsb(r););
Expand Down Expand Up @@ -1191,6 +1201,50 @@ static void grant_lock_pending(struct dlm_rsb *r, struct dlm_lkb *lkb)
queue_cast(r, lkb, 0);
}

/* The special CONVDEADLK, ALTPR and ALTCW flags allow the master to
change the granted/requested modes. We're munging things accordingly in
the process copy.
CONVDEADLK: our grmode may have been forced down to NL to resolve a
conversion deadlock
ALTPR/ALTCW: our rqmode may have been changed to PR or CW to become
compatible with other granted locks */

static void munge_demoted(struct dlm_lkb *lkb, struct dlm_message *ms)
{
if (ms->m_type != DLM_MSG_CONVERT_REPLY) {
log_print("munge_demoted %x invalid reply type %d",
lkb->lkb_id, ms->m_type);
return;
}

if (lkb->lkb_rqmode == DLM_LOCK_IV || lkb->lkb_grmode == DLM_LOCK_IV) {
log_print("munge_demoted %x invalid modes gr %d rq %d",
lkb->lkb_id, lkb->lkb_grmode, lkb->lkb_rqmode);
return;
}

lkb->lkb_grmode = DLM_LOCK_NL;
}

static void munge_altmode(struct dlm_lkb *lkb, struct dlm_message *ms)
{
if (ms->m_type != DLM_MSG_REQUEST_REPLY &&
ms->m_type != DLM_MSG_GRANT) {
log_print("munge_altmode %x invalid reply type %d",
lkb->lkb_id, ms->m_type);
return;
}

if (lkb->lkb_exflags & DLM_LKF_ALTPR)
lkb->lkb_rqmode = DLM_LOCK_PR;
else if (lkb->lkb_exflags & DLM_LKF_ALTCW)
lkb->lkb_rqmode = DLM_LOCK_CW;
else {
log_print("munge_altmode invalid exflags %x", lkb->lkb_exflags);
dlm_print_lkb(lkb);
}
}

static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head)
{
struct dlm_lkb *first = list_entry(head->next, struct dlm_lkb,
Expand Down Expand Up @@ -1965,9 +2019,24 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
goto out;
}

if (can_be_queued(lkb)) {
if (is_demoted(lkb))
/* is_demoted() means the can_be_granted() above set the grmode
to NL, and left us on the granted queue. This auto-demotion
(due to CONVDEADLK) might mean other locks, and/or this lock, are
now grantable. We have to try to grant other converting locks
before we try again to grant this one. */

if (is_demoted(lkb)) {
grant_pending_convert(r, DLM_LOCK_IV);
if (_can_be_granted(r, lkb, 1)) {
grant_lock(r, lkb);
queue_cast(r, lkb, 0);
grant_pending_locks(r);
goto out;
}
/* else fall through and move to convert queue */
}

if (can_be_queued(lkb)) {
error = -EINPROGRESS;
del_lkb(r, lkb);
add_lkb(r, lkb, DLM_LKSTS_CONVERT);
Expand Down Expand Up @@ -2908,6 +2977,8 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
lock_rsb(r);

receive_flags_reply(lkb, ms);
if (is_altmode(lkb))
munge_altmode(lkb, ms);
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);

Expand Down Expand Up @@ -3038,6 +3109,8 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
/* request was queued or granted on remote master */
receive_flags_reply(lkb, ms);
lkb->lkb_remid = ms->m_lkid;
if (is_altmode(lkb))
munge_altmode(lkb, ms);
if (result)
add_lkb(r, lkb, DLM_LKSTS_WAITING);
else {
Expand Down Expand Up @@ -3101,13 +3174,18 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,

case -EINPROGRESS:
/* convert was queued on remote master */
receive_flags_reply(lkb, ms);
if (is_demoted(lkb))
munge_demoted(lkb, ms);
del_lkb(r, lkb);
add_lkb(r, lkb, DLM_LKSTS_CONVERT);
break;

case 0:
/* convert was granted on remote master */
receive_flags_reply(lkb, ms);
if (is_demoted(lkb))
munge_demoted(lkb, ms);
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);
break;
Expand Down

0 comments on commit c733c56

Please sign in to comment.