1
2
3
4
5
6
7
8
9
10
11
12
13#include "dlm_internal.h"
14#include "member.h"
15#include "lock.h"
16#include "dir.h"
17#include "config.h"
18#include "requestqueue.h"
19
20struct rq_entry {
21 struct list_head list;
22 uint32_t recover_seq;
23 int nodeid;
24 struct dlm_message request;
25};
26
27
28
29
30
31
32
33
34void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms)
35{
36 struct rq_entry *e;
37 int length = ms->m_header.h_length - sizeof(struct dlm_message);
38
39 e = kmalloc(sizeof(struct rq_entry) + length, GFP_NOFS);
40 if (!e) {
41 log_print("dlm_add_requestqueue: out of memory len %d", length);
42 return;
43 }
44
45 e->recover_seq = ls->ls_recover_seq & 0xFFFFFFFF;
46 e->nodeid = nodeid;
47 memcpy(&e->request, ms, ms->m_header.h_length);
48
49 mutex_lock(&ls->ls_requestqueue_mutex);
50 list_add_tail(&e->list, &ls->ls_requestqueue);
51 mutex_unlock(&ls->ls_requestqueue_mutex);
52}
53
54
55
56
57
58
59
60
61
62
63
64
65int dlm_process_requestqueue(struct dlm_ls *ls)
66{
67 struct rq_entry *e;
68 struct dlm_message *ms;
69 int error = 0;
70
71 mutex_lock(&ls->ls_requestqueue_mutex);
72
73 for (;;) {
74 if (list_empty(&ls->ls_requestqueue)) {
75 mutex_unlock(&ls->ls_requestqueue_mutex);
76 error = 0;
77 break;
78 }
79 e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list);
80 mutex_unlock(&ls->ls_requestqueue_mutex);
81
82 ms = &e->request;
83
84 log_limit(ls, "dlm_process_requestqueue msg %d from %d "
85 "lkid %x remid %x result %d seq %u",
86 ms->m_type, ms->m_header.h_nodeid,
87 ms->m_lkid, ms->m_remid, ms->m_result,
88 e->recover_seq);
89
90 dlm_receive_message_saved(ls, &e->request, e->recover_seq);
91
92 mutex_lock(&ls->ls_requestqueue_mutex);
93 list_del(&e->list);
94 kfree(e);
95
96 if (dlm_locking_stopped(ls)) {
97 log_debug(ls, "process_requestqueue abort running");
98 mutex_unlock(&ls->ls_requestqueue_mutex);
99 error = -EINTR;
100 break;
101 }
102 schedule();
103 }
104
105 return error;
106}
107
108
109
110
111
112
113
114
115
116
117
118void dlm_wait_requestqueue(struct dlm_ls *ls)
119{
120 for (;;) {
121 mutex_lock(&ls->ls_requestqueue_mutex);
122 if (list_empty(&ls->ls_requestqueue))
123 break;
124 mutex_unlock(&ls->ls_requestqueue_mutex);
125 schedule();
126 }
127 mutex_unlock(&ls->ls_requestqueue_mutex);
128}
129
130static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid)
131{
132 uint32_t type = ms->m_type;
133
134
135 if (!ls->ls_count)
136 return 1;
137
138 if (dlm_is_removed(ls, nodeid))
139 return 1;
140
141
142
143
144 if (type == DLM_MSG_REMOVE ||
145 type == DLM_MSG_LOOKUP ||
146 type == DLM_MSG_LOOKUP_REPLY)
147 return 1;
148
149 if (!dlm_no_directory(ls))
150 return 0;
151
152 return 1;
153}
154
155void dlm_purge_requestqueue(struct dlm_ls *ls)
156{
157 struct dlm_message *ms;
158 struct rq_entry *e, *safe;
159
160 mutex_lock(&ls->ls_requestqueue_mutex);
161 list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) {
162 ms = &e->request;
163
164 if (purge_request(ls, ms, e->nodeid)) {
165 list_del(&e->list);
166 kfree(e);
167 }
168 }
169 mutex_unlock(&ls->ls_requestqueue_mutex);
170}
171
172