]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/dlm-clear-defunct-cancel-state.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / dlm-clear-defunct-cancel-state.patch
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