]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: David Teigland <teigland@redhat.com> |
2 | commit 43279e5376017c40b4be9af5bc79cbb4ef6f53d7 | |
3 | Author: David Teigland <teigland@redhat.com> | |
4 | Date: Wed Jan 28 14:37:54 2009 -0600 | |
5 | Subject: dlm: clear defunct cancel state | |
6 | ||
7 | When a conversion completes successfully and finds that a cancel | |
8 | of the convert is still in progress (which is now a moot point), | |
9 | preemptively clear the state associated with outstanding cancel. | |
10 | That state could cause a subsequent conversion to be ignored. | |
11 | ||
12 | Also, improve the consistency and content of error and debug | |
13 | messages in this area. | |
14 | ||
15 | Signed-off-by: David Teigland <teigland@redhat.com> | |
16 | Signed-off-by: Coly Li <coly.li@suse.de> | |
17 | ||
18 | diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c | |
19 | index 01e7d39..8cb9204 100644 | |
20 | --- a/fs/dlm/lock.c | |
21 | +++ b/fs/dlm/lock.c | |
22 | @@ -835,7 +835,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |
23 | lkb->lkb_wait_count++; | |
24 | hold_lkb(lkb); | |
25 | ||
26 | - log_debug(ls, "add overlap %x cur %d new %d count %d flags %x", | |
27 | + log_debug(ls, "addwait %x cur %d overlap %d count %d f %x", | |
28 | lkb->lkb_id, lkb->lkb_wait_type, mstype, | |
29 | lkb->lkb_wait_count, lkb->lkb_flags); | |
30 | goto out; | |
31 | @@ -851,7 +851,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |
32 | list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); | |
33 | out: | |
34 | if (error) | |
35 | - log_error(ls, "add_to_waiters %x error %d flags %x %d %d %s", | |
36 | + log_error(ls, "addwait error %x %d flags %x %d %d %s", | |
37 | lkb->lkb_id, error, lkb->lkb_flags, mstype, | |
38 | lkb->lkb_wait_type, lkb->lkb_resource->res_name); | |
39 | mutex_unlock(&ls->ls_waiters_mutex); | |
40 | @@ -863,23 +863,55 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |
41 | request reply on the requestqueue) between dlm_recover_waiters_pre() which | |
42 | set RESEND and dlm_recover_waiters_post() */ | |
43 | ||
44 | -static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |
45 | +static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype, | |
46 | + struct dlm_message *ms) | |
47 | { | |
48 | struct dlm_ls *ls = lkb->lkb_resource->res_ls; | |
49 | int overlap_done = 0; | |
50 | ||
51 | if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) { | |
52 | + log_debug(ls, "remwait %x unlock_reply overlap", lkb->lkb_id); | |
53 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; | |
54 | overlap_done = 1; | |
55 | goto out_del; | |
56 | } | |
57 | ||
58 | if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) { | |
59 | + log_debug(ls, "remwait %x cancel_reply overlap", lkb->lkb_id); | |
60 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; | |
61 | overlap_done = 1; | |
62 | goto out_del; | |
63 | } | |
64 | ||
65 | + /* Cancel state was preemptively cleared by a successful convert, | |
66 | + see next comment, nothing to do. */ | |
67 | + | |
68 | + if ((mstype == DLM_MSG_CANCEL_REPLY) && | |
69 | + (lkb->lkb_wait_type != DLM_MSG_CANCEL)) { | |
70 | + log_debug(ls, "remwait %x cancel_reply wait_type %d", | |
71 | + lkb->lkb_id, lkb->lkb_wait_type); | |
72 | + return -1; | |
73 | + } | |
74 | + | |
75 | + /* Remove for the convert reply, and premptively remove for the | |
76 | + cancel reply. A convert has been granted while there's still | |
77 | + an outstanding cancel on it (the cancel is moot and the result | |
78 | + in the cancel reply should be 0). We preempt the cancel reply | |
79 | + because the app gets the convert result and then can follow up | |
80 | + with another op, like convert. This subsequent op would see the | |
81 | + lingering state of the cancel and fail with -EBUSY. */ | |
82 | + | |
83 | + if ((mstype == DLM_MSG_CONVERT_REPLY) && | |
84 | + (lkb->lkb_wait_type == DLM_MSG_CONVERT) && | |
85 | + is_overlap_cancel(lkb) && ms && !ms->m_result) { | |
86 | + log_debug(ls, "remwait %x convert_reply zap overlap_cancel", | |
87 | + lkb->lkb_id); | |
88 | + lkb->lkb_wait_type = 0; | |
89 | + lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; | |
90 | + lkb->lkb_wait_count--; | |
91 | + goto out_del; | |
92 | + } | |
93 | + | |
94 | /* N.B. type of reply may not always correspond to type of original | |
95 | msg due to lookup->request optimization, verify others? */ | |
96 | ||
97 | @@ -888,8 +920,8 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |
98 | goto out_del; | |
99 | } | |
100 | ||
101 | - log_error(ls, "remove_from_waiters lkid %x flags %x types %d %d", | |
102 | - lkb->lkb_id, lkb->lkb_flags, mstype, lkb->lkb_wait_type); | |
103 | + log_error(ls, "remwait error %x reply %d flags %x no wait_type", | |
104 | + lkb->lkb_id, mstype, lkb->lkb_flags); | |
105 | return -1; | |
106 | ||
107 | out_del: | |
108 | @@ -899,7 +931,7 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |
109 | this would happen */ | |
110 | ||
111 | if (overlap_done && lkb->lkb_wait_type) { | |
112 | - log_error(ls, "remove_from_waiters %x reply %d give up on %d", | |
113 | + log_error(ls, "remwait error %x reply %d wait_type %d overlap", | |
114 | lkb->lkb_id, mstype, lkb->lkb_wait_type); | |
115 | lkb->lkb_wait_count--; | |
116 | lkb->lkb_wait_type = 0; | |
117 | @@ -921,7 +953,7 @@ static int remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |
118 | int error; | |
119 | ||
120 | mutex_lock(&ls->ls_waiters_mutex); | |
121 | - error = _remove_from_waiters(lkb, mstype); | |
122 | + error = _remove_from_waiters(lkb, mstype, NULL); | |
123 | mutex_unlock(&ls->ls_waiters_mutex); | |
124 | return error; | |
125 | } | |
126 | @@ -936,7 +968,7 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms) | |
127 | ||
128 | if (ms != &ls->ls_stub_ms) | |
129 | mutex_lock(&ls->ls_waiters_mutex); | |
130 | - error = _remove_from_waiters(lkb, ms->m_type); | |
131 | + error = _remove_from_waiters(lkb, ms->m_type, ms); | |
132 | if (ms != &ls->ls_stub_ms) | |
133 | mutex_unlock(&ls->ls_waiters_mutex); | |
134 | return error; | |
135 | @@ -2083,6 +2115,11 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |
136 | lkb->lkb_timeout_cs = args->timeout; | |
137 | rv = 0; | |
138 | out: | |
139 | + if (rv) | |
140 | + log_debug(ls, "validate_lock_args %d %x %x %x %d %d %s", | |
141 | + rv, lkb->lkb_id, lkb->lkb_flags, args->flags, | |
142 | + lkb->lkb_status, lkb->lkb_wait_type, | |
143 | + lkb->lkb_resource->res_name); | |
144 | return rv; | |
145 | } | |
146 |