diff options
Diffstat (limited to 'fs/dlm/member.c')
-rw-r--r-- | fs/dlm/member.c | 486 |
1 files changed, 408 insertions, 78 deletions
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index b12532e553f8..862640a36d5c 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) 2005-2009 Red Hat, Inc. All rights reserved. | 4 | ** Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved. |
5 | ** | 5 | ** |
6 | ** This copyrighted material is made available to anyone wishing to use, | 6 | ** This copyrighted material is made available to anyone wishing to use, |
7 | ** modify, copy, or redistribute it subject to the terms and conditions | 7 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -19,6 +19,280 @@ | |||
19 | #include "config.h" | 19 | #include "config.h" |
20 | #include "lowcomms.h" | 20 | #include "lowcomms.h" |
21 | 21 | ||
22 | int dlm_slots_version(struct dlm_header *h) | ||
23 | { | ||
24 | if ((h->h_version & 0x0000FFFF) < DLM_HEADER_SLOTS) | ||
25 | return 0; | ||
26 | return 1; | ||
27 | } | ||
28 | |||
29 | void dlm_slot_save(struct dlm_ls *ls, struct dlm_rcom *rc, | ||
30 | struct dlm_member *memb) | ||
31 | { | ||
32 | struct rcom_config *rf = (struct rcom_config *)rc->rc_buf; | ||
33 | |||
34 | if (!dlm_slots_version(&rc->rc_header)) | ||
35 | return; | ||
36 | |||
37 | memb->slot = le16_to_cpu(rf->rf_our_slot); | ||
38 | memb->generation = le32_to_cpu(rf->rf_generation); | ||
39 | } | ||
40 | |||
41 | void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc) | ||
42 | { | ||
43 | struct dlm_slot *slot; | ||
44 | struct rcom_slot *ro; | ||
45 | int i; | ||
46 | |||
47 | ro = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config)); | ||
48 | |||
49 | /* ls_slots array is sparse, but not rcom_slots */ | ||
50 | |||
51 | for (i = 0; i < ls->ls_slots_size; i++) { | ||
52 | slot = &ls->ls_slots[i]; | ||
53 | if (!slot->nodeid) | ||
54 | continue; | ||
55 | ro->ro_nodeid = cpu_to_le32(slot->nodeid); | ||
56 | ro->ro_slot = cpu_to_le16(slot->slot); | ||
57 | ro++; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | #define SLOT_DEBUG_LINE 128 | ||
62 | |||
63 | static void log_debug_slots(struct dlm_ls *ls, uint32_t gen, int num_slots, | ||
64 | struct rcom_slot *ro0, struct dlm_slot *array, | ||
65 | int array_size) | ||
66 | { | ||
67 | char line[SLOT_DEBUG_LINE]; | ||
68 | int len = SLOT_DEBUG_LINE - 1; | ||
69 | int pos = 0; | ||
70 | int ret, i; | ||
71 | |||
72 | if (!dlm_config.ci_log_debug) | ||
73 | return; | ||
74 | |||
75 | memset(line, 0, sizeof(line)); | ||
76 | |||
77 | if (array) { | ||
78 | for (i = 0; i < array_size; i++) { | ||
79 | if (!array[i].nodeid) | ||
80 | continue; | ||
81 | |||
82 | ret = snprintf(line + pos, len - pos, " %d:%d", | ||
83 | array[i].slot, array[i].nodeid); | ||
84 | if (ret >= len - pos) | ||
85 | break; | ||
86 | pos += ret; | ||
87 | } | ||
88 | } else if (ro0) { | ||
89 | for (i = 0; i < num_slots; i++) { | ||
90 | ret = snprintf(line + pos, len - pos, " %d:%d", | ||
91 | ro0[i].ro_slot, ro0[i].ro_nodeid); | ||
92 | if (ret >= len - pos) | ||
93 | break; | ||
94 | pos += ret; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | log_debug(ls, "generation %u slots %d%s", gen, num_slots, line); | ||
99 | } | ||
100 | |||
101 | int dlm_slots_copy_in(struct dlm_ls *ls) | ||
102 | { | ||
103 | struct dlm_member *memb; | ||
104 | struct dlm_rcom *rc = ls->ls_recover_buf; | ||
105 | struct rcom_config *rf = (struct rcom_config *)rc->rc_buf; | ||
106 | struct rcom_slot *ro0, *ro; | ||
107 | int our_nodeid = dlm_our_nodeid(); | ||
108 | int i, num_slots; | ||
109 | uint32_t gen; | ||
110 | |||
111 | if (!dlm_slots_version(&rc->rc_header)) | ||
112 | return -1; | ||
113 | |||
114 | gen = le32_to_cpu(rf->rf_generation); | ||
115 | if (gen <= ls->ls_generation) { | ||
116 | log_error(ls, "dlm_slots_copy_in gen %u old %u", | ||
117 | gen, ls->ls_generation); | ||
118 | } | ||
119 | ls->ls_generation = gen; | ||
120 | |||
121 | num_slots = le16_to_cpu(rf->rf_num_slots); | ||
122 | if (!num_slots) | ||
123 | return -1; | ||
124 | |||
125 | ro0 = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config)); | ||
126 | |||
127 | for (i = 0, ro = ro0; i < num_slots; i++, ro++) { | ||
128 | ro->ro_nodeid = le32_to_cpu(ro->ro_nodeid); | ||
129 | ro->ro_slot = le16_to_cpu(ro->ro_slot); | ||
130 | } | ||
131 | |||
132 | log_debug_slots(ls, gen, num_slots, ro0, NULL, 0); | ||
133 | |||
134 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
135 | for (i = 0, ro = ro0; i < num_slots; i++, ro++) { | ||
136 | if (ro->ro_nodeid != memb->nodeid) | ||
137 | continue; | ||
138 | memb->slot = ro->ro_slot; | ||
139 | memb->slot_prev = memb->slot; | ||
140 | break; | ||
141 | } | ||
142 | |||
143 | if (memb->nodeid == our_nodeid) { | ||
144 | if (ls->ls_slot && ls->ls_slot != memb->slot) { | ||
145 | log_error(ls, "dlm_slots_copy_in our slot " | ||
146 | "changed %d %d", ls->ls_slot, | ||
147 | memb->slot); | ||
148 | return -1; | ||
149 | } | ||
150 | |||
151 | if (!ls->ls_slot) | ||
152 | ls->ls_slot = memb->slot; | ||
153 | } | ||
154 | |||
155 | if (!memb->slot) { | ||
156 | log_error(ls, "dlm_slots_copy_in nodeid %d no slot", | ||
157 | memb->nodeid); | ||
158 | return -1; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | /* for any nodes that do not support slots, we will not have set memb->slot | ||
166 | in wait_status_all(), so memb->slot will remain -1, and we will not | ||
167 | assign slots or set ls_num_slots here */ | ||
168 | |||
169 | int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size, | ||
170 | struct dlm_slot **slots_out, uint32_t *gen_out) | ||
171 | { | ||
172 | struct dlm_member *memb; | ||
173 | struct dlm_slot *array; | ||
174 | int our_nodeid = dlm_our_nodeid(); | ||
175 | int array_size, max_slots, i; | ||
176 | int need = 0; | ||
177 | int max = 0; | ||
178 | int num = 0; | ||
179 | uint32_t gen = 0; | ||
180 | |||
181 | /* our own memb struct will have slot -1 gen 0 */ | ||
182 | |||
183 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
184 | if (memb->nodeid == our_nodeid) { | ||
185 | memb->slot = ls->ls_slot; | ||
186 | memb->generation = ls->ls_generation; | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
192 | if (memb->generation > gen) | ||
193 | gen = memb->generation; | ||
194 | |||
195 | /* node doesn't support slots */ | ||
196 | |||
197 | if (memb->slot == -1) | ||
198 | return -1; | ||
199 | |||
200 | /* node needs a slot assigned */ | ||
201 | |||
202 | if (!memb->slot) | ||
203 | need++; | ||
204 | |||
205 | /* node has a slot assigned */ | ||
206 | |||
207 | num++; | ||
208 | |||
209 | if (!max || max < memb->slot) | ||
210 | max = memb->slot; | ||
211 | |||
212 | /* sanity check, once slot is assigned it shouldn't change */ | ||
213 | |||
214 | if (memb->slot_prev && memb->slot && memb->slot_prev != memb->slot) { | ||
215 | log_error(ls, "nodeid %d slot changed %d %d", | ||
216 | memb->nodeid, memb->slot_prev, memb->slot); | ||
217 | return -1; | ||
218 | } | ||
219 | memb->slot_prev = memb->slot; | ||
220 | } | ||
221 | |||
222 | array_size = max + need; | ||
223 | |||
224 | array = kzalloc(array_size * sizeof(struct dlm_slot), GFP_NOFS); | ||
225 | if (!array) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | num = 0; | ||
229 | |||
230 | /* fill in slots (offsets) that are used */ | ||
231 | |||
232 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
233 | if (!memb->slot) | ||
234 | continue; | ||
235 | |||
236 | if (memb->slot > array_size) { | ||
237 | log_error(ls, "invalid slot number %d", memb->slot); | ||
238 | kfree(array); | ||
239 | return -1; | ||
240 | } | ||
241 | |||
242 | array[memb->slot - 1].nodeid = memb->nodeid; | ||
243 | array[memb->slot - 1].slot = memb->slot; | ||
244 | num++; | ||
245 | } | ||
246 | |||
247 | /* assign new slots from unused offsets */ | ||
248 | |||
249 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
250 | if (memb->slot) | ||
251 | continue; | ||
252 | |||
253 | for (i = 0; i < array_size; i++) { | ||
254 | if (array[i].nodeid) | ||
255 | continue; | ||
256 | |||
257 | memb->slot = i + 1; | ||
258 | memb->slot_prev = memb->slot; | ||
259 | array[i].nodeid = memb->nodeid; | ||
260 | array[i].slot = memb->slot; | ||
261 | num++; | ||
262 | |||
263 | if (!ls->ls_slot && memb->nodeid == our_nodeid) | ||
264 | ls->ls_slot = memb->slot; | ||
265 | break; | ||
266 | } | ||
267 | |||
268 | if (!memb->slot) { | ||
269 | log_error(ls, "no free slot found"); | ||
270 | kfree(array); | ||
271 | return -1; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | gen++; | ||
276 | |||
277 | log_debug_slots(ls, gen, num, NULL, array, array_size); | ||
278 | |||
279 | max_slots = (dlm_config.ci_buffer_size - sizeof(struct dlm_rcom) - | ||
280 | sizeof(struct rcom_config)) / sizeof(struct rcom_slot); | ||
281 | |||
282 | if (num > max_slots) { | ||
283 | log_error(ls, "num_slots %d exceeds max_slots %d", | ||
284 | num, max_slots); | ||
285 | kfree(array); | ||
286 | return -1; | ||
287 | } | ||
288 | |||
289 | *gen_out = gen; | ||
290 | *slots_out = array; | ||
291 | *slots_size = array_size; | ||
292 | *num_slots = num; | ||
293 | return 0; | ||
294 | } | ||
295 | |||
22 | static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new) | 296 | static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new) |
23 | { | 297 | { |
24 | struct dlm_member *memb = NULL; | 298 | struct dlm_member *memb = NULL; |
@@ -43,59 +317,51 @@ static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new) | |||
43 | } | 317 | } |
44 | } | 318 | } |
45 | 319 | ||
46 | static int dlm_add_member(struct dlm_ls *ls, int nodeid) | 320 | static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node) |
47 | { | 321 | { |
48 | struct dlm_member *memb; | 322 | struct dlm_member *memb; |
49 | int w, error; | 323 | int error; |
50 | 324 | ||
51 | memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS); | 325 | memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS); |
52 | if (!memb) | 326 | if (!memb) |
53 | return -ENOMEM; | 327 | return -ENOMEM; |
54 | 328 | ||
55 | w = dlm_node_weight(ls->ls_name, nodeid); | 329 | error = dlm_lowcomms_connect_node(node->nodeid); |
56 | if (w < 0) { | ||
57 | kfree(memb); | ||
58 | return w; | ||
59 | } | ||
60 | |||
61 | error = dlm_lowcomms_connect_node(nodeid); | ||
62 | if (error < 0) { | 330 | if (error < 0) { |
63 | kfree(memb); | 331 | kfree(memb); |
64 | return error; | 332 | return error; |
65 | } | 333 | } |
66 | 334 | ||
67 | memb->nodeid = nodeid; | 335 | memb->nodeid = node->nodeid; |
68 | memb->weight = w; | 336 | memb->weight = node->weight; |
337 | memb->comm_seq = node->comm_seq; | ||
69 | add_ordered_member(ls, memb); | 338 | add_ordered_member(ls, memb); |
70 | ls->ls_num_nodes++; | 339 | ls->ls_num_nodes++; |
71 | return 0; | 340 | return 0; |
72 | } | 341 | } |
73 | 342 | ||
74 | static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb) | 343 | static struct dlm_member *find_memb(struct list_head *head, int nodeid) |
75 | { | ||
76 | list_move(&memb->list, &ls->ls_nodes_gone); | ||
77 | ls->ls_num_nodes--; | ||
78 | } | ||
79 | |||
80 | int dlm_is_member(struct dlm_ls *ls, int nodeid) | ||
81 | { | 344 | { |
82 | struct dlm_member *memb; | 345 | struct dlm_member *memb; |
83 | 346 | ||
84 | list_for_each_entry(memb, &ls->ls_nodes, list) { | 347 | list_for_each_entry(memb, head, list) { |
85 | if (memb->nodeid == nodeid) | 348 | if (memb->nodeid == nodeid) |
86 | return 1; | 349 | return memb; |
87 | } | 350 | } |
351 | return NULL; | ||
352 | } | ||
353 | |||
354 | int dlm_is_member(struct dlm_ls *ls, int nodeid) | ||
355 | { | ||
356 | if (find_memb(&ls->ls_nodes, nodeid)) | ||
357 | return 1; | ||
88 | return 0; | 358 | return 0; |
89 | } | 359 | } |
90 | 360 | ||
91 | int dlm_is_removed(struct dlm_ls *ls, int nodeid) | 361 | int dlm_is_removed(struct dlm_ls *ls, int nodeid) |
92 | { | 362 | { |
93 | struct dlm_member *memb; | 363 | if (find_memb(&ls->ls_nodes_gone, nodeid)) |
94 | 364 | return 1; | |
95 | list_for_each_entry(memb, &ls->ls_nodes_gone, list) { | ||
96 | if (memb->nodeid == nodeid) | ||
97 | return 1; | ||
98 | } | ||
99 | return 0; | 365 | return 0; |
100 | } | 366 | } |
101 | 367 | ||
@@ -176,7 +442,7 @@ static int ping_members(struct dlm_ls *ls) | |||
176 | error = dlm_recovery_stopped(ls); | 442 | error = dlm_recovery_stopped(ls); |
177 | if (error) | 443 | if (error) |
178 | break; | 444 | break; |
179 | error = dlm_rcom_status(ls, memb->nodeid); | 445 | error = dlm_rcom_status(ls, memb->nodeid, 0); |
180 | if (error) | 446 | if (error) |
181 | break; | 447 | break; |
182 | } | 448 | } |
@@ -186,10 +452,88 @@ static int ping_members(struct dlm_ls *ls) | |||
186 | return error; | 452 | return error; |
187 | } | 453 | } |
188 | 454 | ||
455 | static void dlm_lsop_recover_prep(struct dlm_ls *ls) | ||
456 | { | ||
457 | if (!ls->ls_ops || !ls->ls_ops->recover_prep) | ||
458 | return; | ||
459 | ls->ls_ops->recover_prep(ls->ls_ops_arg); | ||
460 | } | ||
461 | |||
462 | static void dlm_lsop_recover_slot(struct dlm_ls *ls, struct dlm_member *memb) | ||
463 | { | ||
464 | struct dlm_slot slot; | ||
465 | uint32_t seq; | ||
466 | int error; | ||
467 | |||
468 | if (!ls->ls_ops || !ls->ls_ops->recover_slot) | ||
469 | return; | ||
470 | |||
471 | /* if there is no comms connection with this node | ||
472 | or the present comms connection is newer | ||
473 | than the one when this member was added, then | ||
474 | we consider the node to have failed (versus | ||
475 | being removed due to dlm_release_lockspace) */ | ||
476 | |||
477 | error = dlm_comm_seq(memb->nodeid, &seq); | ||
478 | |||
479 | if (!error && seq == memb->comm_seq) | ||
480 | return; | ||
481 | |||
482 | slot.nodeid = memb->nodeid; | ||
483 | slot.slot = memb->slot; | ||
484 | |||
485 | ls->ls_ops->recover_slot(ls->ls_ops_arg, &slot); | ||
486 | } | ||
487 | |||
488 | void dlm_lsop_recover_done(struct dlm_ls *ls) | ||
489 | { | ||
490 | struct dlm_member *memb; | ||
491 | struct dlm_slot *slots; | ||
492 | int i, num; | ||
493 | |||
494 | if (!ls->ls_ops || !ls->ls_ops->recover_done) | ||
495 | return; | ||
496 | |||
497 | num = ls->ls_num_nodes; | ||
498 | |||
499 | slots = kzalloc(num * sizeof(struct dlm_slot), GFP_KERNEL); | ||
500 | if (!slots) | ||
501 | return; | ||
502 | |||
503 | i = 0; | ||
504 | list_for_each_entry(memb, &ls->ls_nodes, list) { | ||
505 | if (i == num) { | ||
506 | log_error(ls, "dlm_lsop_recover_done bad num %d", num); | ||
507 | goto out; | ||
508 | } | ||
509 | slots[i].nodeid = memb->nodeid; | ||
510 | slots[i].slot = memb->slot; | ||
511 | i++; | ||
512 | } | ||
513 | |||
514 | ls->ls_ops->recover_done(ls->ls_ops_arg, slots, num, | ||
515 | ls->ls_slot, ls->ls_generation); | ||
516 | out: | ||
517 | kfree(slots); | ||
518 | } | ||
519 | |||
520 | static struct dlm_config_node *find_config_node(struct dlm_recover *rv, | ||
521 | int nodeid) | ||
522 | { | ||
523 | int i; | ||
524 | |||
525 | for (i = 0; i < rv->nodes_count; i++) { | ||
526 | if (rv->nodes[i].nodeid == nodeid) | ||
527 | return &rv->nodes[i]; | ||
528 | } | ||
529 | return NULL; | ||
530 | } | ||
531 | |||
189 | int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | 532 | int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) |
190 | { | 533 | { |
191 | struct dlm_member *memb, *safe; | 534 | struct dlm_member *memb, *safe; |
192 | int i, error, found, pos = 0, neg = 0, low = -1; | 535 | struct dlm_config_node *node; |
536 | int i, error, neg = 0, low = -1; | ||
193 | 537 | ||
194 | /* previously removed members that we've not finished removing need to | 538 | /* previously removed members that we've not finished removing need to |
195 | count as a negative change so the "neg" recovery steps will happen */ | 539 | count as a negative change so the "neg" recovery steps will happen */ |
@@ -202,46 +546,32 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
202 | /* move departed members from ls_nodes to ls_nodes_gone */ | 546 | /* move departed members from ls_nodes to ls_nodes_gone */ |
203 | 547 | ||
204 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { | 548 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { |
205 | found = 0; | 549 | node = find_config_node(rv, memb->nodeid); |
206 | for (i = 0; i < rv->node_count; i++) { | 550 | if (node && !node->new) |
207 | if (memb->nodeid == rv->nodeids[i]) { | 551 | continue; |
208 | found = 1; | ||
209 | break; | ||
210 | } | ||
211 | } | ||
212 | 552 | ||
213 | if (!found) { | 553 | if (!node) { |
214 | neg++; | ||
215 | dlm_remove_member(ls, memb); | ||
216 | log_debug(ls, "remove member %d", memb->nodeid); | 554 | log_debug(ls, "remove member %d", memb->nodeid); |
555 | } else { | ||
556 | /* removed and re-added */ | ||
557 | log_debug(ls, "remove member %d comm_seq %u %u", | ||
558 | memb->nodeid, memb->comm_seq, node->comm_seq); | ||
217 | } | 559 | } |
218 | } | ||
219 | |||
220 | /* Add an entry to ls_nodes_gone for members that were removed and | ||
221 | then added again, so that previous state for these nodes will be | ||
222 | cleared during recovery. */ | ||
223 | |||
224 | for (i = 0; i < rv->new_count; i++) { | ||
225 | if (!dlm_is_member(ls, rv->new[i])) | ||
226 | continue; | ||
227 | log_debug(ls, "new nodeid %d is a re-added member", rv->new[i]); | ||
228 | 560 | ||
229 | memb = kzalloc(sizeof(struct dlm_member), GFP_NOFS); | ||
230 | if (!memb) | ||
231 | return -ENOMEM; | ||
232 | memb->nodeid = rv->new[i]; | ||
233 | list_add_tail(&memb->list, &ls->ls_nodes_gone); | ||
234 | neg++; | 561 | neg++; |
562 | list_move(&memb->list, &ls->ls_nodes_gone); | ||
563 | ls->ls_num_nodes--; | ||
564 | dlm_lsop_recover_slot(ls, memb); | ||
235 | } | 565 | } |
236 | 566 | ||
237 | /* add new members to ls_nodes */ | 567 | /* add new members to ls_nodes */ |
238 | 568 | ||
239 | for (i = 0; i < rv->node_count; i++) { | 569 | for (i = 0; i < rv->nodes_count; i++) { |
240 | if (dlm_is_member(ls, rv->nodeids[i])) | 570 | node = &rv->nodes[i]; |
571 | if (dlm_is_member(ls, node->nodeid)) | ||
241 | continue; | 572 | continue; |
242 | dlm_add_member(ls, rv->nodeids[i]); | 573 | dlm_add_member(ls, node); |
243 | pos++; | 574 | log_debug(ls, "add member %d", node->nodeid); |
244 | log_debug(ls, "add member %d", rv->nodeids[i]); | ||
245 | } | 575 | } |
246 | 576 | ||
247 | list_for_each_entry(memb, &ls->ls_nodes, list) { | 577 | list_for_each_entry(memb, &ls->ls_nodes, list) { |
@@ -251,7 +581,6 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
251 | ls->ls_low_nodeid = low; | 581 | ls->ls_low_nodeid = low; |
252 | 582 | ||
253 | make_member_array(ls); | 583 | make_member_array(ls); |
254 | dlm_set_recover_status(ls, DLM_RS_NODES); | ||
255 | *neg_out = neg; | 584 | *neg_out = neg; |
256 | 585 | ||
257 | error = ping_members(ls); | 586 | error = ping_members(ls); |
@@ -261,12 +590,8 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
261 | ls->ls_members_result = error; | 590 | ls->ls_members_result = error; |
262 | complete(&ls->ls_members_done); | 591 | complete(&ls->ls_members_done); |
263 | } | 592 | } |
264 | if (error) | ||
265 | goto out; | ||
266 | 593 | ||
267 | error = dlm_recover_members_wait(ls); | 594 | log_debug(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes); |
268 | out: | ||
269 | log_debug(ls, "total members %d error %d", ls->ls_num_nodes, error); | ||
270 | return error; | 595 | return error; |
271 | } | 596 | } |
272 | 597 | ||
@@ -327,26 +652,35 @@ int dlm_ls_stop(struct dlm_ls *ls) | |||
327 | */ | 652 | */ |
328 | 653 | ||
329 | dlm_recoverd_suspend(ls); | 654 | dlm_recoverd_suspend(ls); |
655 | |||
656 | spin_lock(&ls->ls_recover_lock); | ||
657 | kfree(ls->ls_slots); | ||
658 | ls->ls_slots = NULL; | ||
659 | ls->ls_num_slots = 0; | ||
660 | ls->ls_slots_size = 0; | ||
330 | ls->ls_recover_status = 0; | 661 | ls->ls_recover_status = 0; |
662 | spin_unlock(&ls->ls_recover_lock); | ||
663 | |||
331 | dlm_recoverd_resume(ls); | 664 | dlm_recoverd_resume(ls); |
332 | 665 | ||
333 | if (!ls->ls_recover_begin) | 666 | if (!ls->ls_recover_begin) |
334 | ls->ls_recover_begin = jiffies; | 667 | ls->ls_recover_begin = jiffies; |
668 | |||
669 | dlm_lsop_recover_prep(ls); | ||
335 | return 0; | 670 | return 0; |
336 | } | 671 | } |
337 | 672 | ||
338 | int dlm_ls_start(struct dlm_ls *ls) | 673 | int dlm_ls_start(struct dlm_ls *ls) |
339 | { | 674 | { |
340 | struct dlm_recover *rv = NULL, *rv_old; | 675 | struct dlm_recover *rv = NULL, *rv_old; |
341 | int *ids = NULL, *new = NULL; | 676 | struct dlm_config_node *nodes; |
342 | int error, ids_count = 0, new_count = 0; | 677 | int error, count; |
343 | 678 | ||
344 | rv = kzalloc(sizeof(struct dlm_recover), GFP_NOFS); | 679 | rv = kzalloc(sizeof(struct dlm_recover), GFP_NOFS); |
345 | if (!rv) | 680 | if (!rv) |
346 | return -ENOMEM; | 681 | return -ENOMEM; |
347 | 682 | ||
348 | error = dlm_nodeid_list(ls->ls_name, &ids, &ids_count, | 683 | error = dlm_config_nodes(ls->ls_name, &nodes, &count); |
349 | &new, &new_count); | ||
350 | if (error < 0) | 684 | if (error < 0) |
351 | goto fail; | 685 | goto fail; |
352 | 686 | ||
@@ -361,10 +695,8 @@ int dlm_ls_start(struct dlm_ls *ls) | |||
361 | goto fail; | 695 | goto fail; |
362 | } | 696 | } |
363 | 697 | ||
364 | rv->nodeids = ids; | 698 | rv->nodes = nodes; |
365 | rv->node_count = ids_count; | 699 | rv->nodes_count = count; |
366 | rv->new = new; | ||
367 | rv->new_count = new_count; | ||
368 | rv->seq = ++ls->ls_recover_seq; | 700 | rv->seq = ++ls->ls_recover_seq; |
369 | rv_old = ls->ls_recover_args; | 701 | rv_old = ls->ls_recover_args; |
370 | ls->ls_recover_args = rv; | 702 | ls->ls_recover_args = rv; |
@@ -372,9 +704,8 @@ int dlm_ls_start(struct dlm_ls *ls) | |||
372 | 704 | ||
373 | if (rv_old) { | 705 | if (rv_old) { |
374 | log_error(ls, "unused recovery %llx %d", | 706 | log_error(ls, "unused recovery %llx %d", |
375 | (unsigned long long)rv_old->seq, rv_old->node_count); | 707 | (unsigned long long)rv_old->seq, rv_old->nodes_count); |
376 | kfree(rv_old->nodeids); | 708 | kfree(rv_old->nodes); |
377 | kfree(rv_old->new); | ||
378 | kfree(rv_old); | 709 | kfree(rv_old); |
379 | } | 710 | } |
380 | 711 | ||
@@ -383,8 +714,7 @@ int dlm_ls_start(struct dlm_ls *ls) | |||
383 | 714 | ||
384 | fail: | 715 | fail: |
385 | kfree(rv); | 716 | kfree(rv); |
386 | kfree(ids); | 717 | kfree(nodes); |
387 | kfree(new); | ||
388 | return error; | 718 | return error; |
389 | } | 719 | } |
390 | 720 | ||