~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/dlm/member.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/dlm/member.c (Version linux-6.12-rc7) and /fs/dlm/member.c (Version linux-6.8.12)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*********************************************      2 /******************************************************************************
  3 **********************************************      3 *******************************************************************************
  4 **                                                  4 **
  5 **  Copyright (C) 2005-2011 Red Hat, Inc.  All      5 **  Copyright (C) 2005-2011 Red Hat, Inc.  All rights reserved.
  6 **                                                  6 **
  7 **                                                  7 **
  8 **********************************************      8 *******************************************************************************
  9 **********************************************      9 ******************************************************************************/
 10                                                    10 
 11 #include "dlm_internal.h"                          11 #include "dlm_internal.h"
 12 #include "lockspace.h"                             12 #include "lockspace.h"
 13 #include "member.h"                                13 #include "member.h"
 14 #include "recoverd.h"                              14 #include "recoverd.h"
 15 #include "recover.h"                               15 #include "recover.h"
 16 #include "rcom.h"                                  16 #include "rcom.h"
 17 #include "config.h"                                17 #include "config.h"
 18 #include "midcomms.h"                              18 #include "midcomms.h"
 19 #include "lowcomms.h"                              19 #include "lowcomms.h"
 20                                                    20 
 21 int dlm_slots_version(const struct dlm_header      21 int dlm_slots_version(const struct dlm_header *h)
 22 {                                                  22 {
 23         if ((le32_to_cpu(h->h_version) & 0x000     23         if ((le32_to_cpu(h->h_version) & 0x0000FFFF) < DLM_HEADER_SLOTS)
 24                 return 0;                          24                 return 0;
 25         return 1;                                  25         return 1;
 26 }                                                  26 }
 27                                                    27 
 28 void dlm_slot_save(struct dlm_ls *ls, struct d     28 void dlm_slot_save(struct dlm_ls *ls, struct dlm_rcom *rc,
 29                    struct dlm_member *memb)        29                    struct dlm_member *memb)
 30 {                                                  30 {
 31         struct rcom_config *rf = (struct rcom_     31         struct rcom_config *rf = (struct rcom_config *)rc->rc_buf;
 32                                                    32 
 33         if (!dlm_slots_version(&rc->rc_header)     33         if (!dlm_slots_version(&rc->rc_header))
 34                 return;                            34                 return;
 35                                                    35 
 36         memb->slot = le16_to_cpu(rf->rf_our_sl     36         memb->slot = le16_to_cpu(rf->rf_our_slot);
 37         memb->generation = le32_to_cpu(rf->rf_     37         memb->generation = le32_to_cpu(rf->rf_generation);
 38 }                                                  38 }
 39                                                    39 
 40 void dlm_slots_copy_out(struct dlm_ls *ls, str     40 void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc)
 41 {                                                  41 {
 42         struct dlm_slot *slot;                     42         struct dlm_slot *slot;
 43         struct rcom_slot *ro;                      43         struct rcom_slot *ro;
 44         int i;                                     44         int i;
 45                                                    45 
 46         ro = (struct rcom_slot *)(rc->rc_buf +     46         ro = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config));
 47                                                    47 
 48         /* ls_slots array is sparse, but not r     48         /* ls_slots array is sparse, but not rcom_slots */
 49                                                    49 
 50         for (i = 0; i < ls->ls_slots_size; i++     50         for (i = 0; i < ls->ls_slots_size; i++) {
 51                 slot = &ls->ls_slots[i];           51                 slot = &ls->ls_slots[i];
 52                 if (!slot->nodeid)                 52                 if (!slot->nodeid)
 53                         continue;                  53                         continue;
 54                 ro->ro_nodeid = cpu_to_le32(sl     54                 ro->ro_nodeid = cpu_to_le32(slot->nodeid);
 55                 ro->ro_slot = cpu_to_le16(slot     55                 ro->ro_slot = cpu_to_le16(slot->slot);
 56                 ro++;                              56                 ro++;
 57         }                                          57         }
 58 }                                                  58 }
 59                                                    59 
 60 #define SLOT_DEBUG_LINE 128                        60 #define SLOT_DEBUG_LINE 128
 61                                                    61 
 62 static void log_slots(struct dlm_ls *ls, uint3     62 static void log_slots(struct dlm_ls *ls, uint32_t gen, int num_slots,
 63                       struct rcom_slot *ro0, s     63                       struct rcom_slot *ro0, struct dlm_slot *array,
 64                       int array_size)              64                       int array_size)
 65 {                                                  65 {
 66         char line[SLOT_DEBUG_LINE];                66         char line[SLOT_DEBUG_LINE];
 67         int len = SLOT_DEBUG_LINE - 1;             67         int len = SLOT_DEBUG_LINE - 1;
 68         int pos = 0;                               68         int pos = 0;
 69         int ret, i;                                69         int ret, i;
 70                                                    70 
 71         memset(line, 0, sizeof(line));             71         memset(line, 0, sizeof(line));
 72                                                    72 
 73         if (array) {                               73         if (array) {
 74                 for (i = 0; i < array_size; i+     74                 for (i = 0; i < array_size; i++) {
 75                         if (!array[i].nodeid)      75                         if (!array[i].nodeid)
 76                                 continue;          76                                 continue;
 77                                                    77 
 78                         ret = snprintf(line +      78                         ret = snprintf(line + pos, len - pos, " %d:%d",
 79                                        array[i     79                                        array[i].slot, array[i].nodeid);
 80                         if (ret >= len - pos)      80                         if (ret >= len - pos)
 81                                 break;             81                                 break;
 82                         pos += ret;                82                         pos += ret;
 83                 }                                  83                 }
 84         } else if (ro0) {                          84         } else if (ro0) {
 85                 for (i = 0; i < num_slots; i++     85                 for (i = 0; i < num_slots; i++) {
 86                         ret = snprintf(line +      86                         ret = snprintf(line + pos, len - pos, " %d:%d",
 87                                        ro0[i].     87                                        ro0[i].ro_slot, ro0[i].ro_nodeid);
 88                         if (ret >= len - pos)      88                         if (ret >= len - pos)
 89                                 break;             89                                 break;
 90                         pos += ret;                90                         pos += ret;
 91                 }                                  91                 }
 92         }                                          92         }
 93                                                    93 
 94         log_rinfo(ls, "generation %u slots %d%     94         log_rinfo(ls, "generation %u slots %d%s", gen, num_slots, line);
 95 }                                                  95 }
 96                                                    96 
 97 int dlm_slots_copy_in(struct dlm_ls *ls)           97 int dlm_slots_copy_in(struct dlm_ls *ls)
 98 {                                                  98 {
 99         struct dlm_member *memb;                   99         struct dlm_member *memb;
100         struct dlm_rcom *rc = ls->ls_recover_b    100         struct dlm_rcom *rc = ls->ls_recover_buf;
101         struct rcom_config *rf = (struct rcom_    101         struct rcom_config *rf = (struct rcom_config *)rc->rc_buf;
102         struct rcom_slot *ro0, *ro;               102         struct rcom_slot *ro0, *ro;
103         int our_nodeid = dlm_our_nodeid();        103         int our_nodeid = dlm_our_nodeid();
104         int i, num_slots;                         104         int i, num_slots;
105         uint32_t gen;                             105         uint32_t gen;
106                                                   106 
107         if (!dlm_slots_version(&rc->rc_header)    107         if (!dlm_slots_version(&rc->rc_header))
108                 return -1;                        108                 return -1;
109                                                   109 
110         gen = le32_to_cpu(rf->rf_generation);     110         gen = le32_to_cpu(rf->rf_generation);
111         if (gen <= ls->ls_generation) {           111         if (gen <= ls->ls_generation) {
112                 log_error(ls, "dlm_slots_copy_    112                 log_error(ls, "dlm_slots_copy_in gen %u old %u",
113                           gen, ls->ls_generati    113                           gen, ls->ls_generation);
114         }                                         114         }
115         ls->ls_generation = gen;                  115         ls->ls_generation = gen;
116                                                   116 
117         num_slots = le16_to_cpu(rf->rf_num_slo    117         num_slots = le16_to_cpu(rf->rf_num_slots);
118         if (!num_slots)                           118         if (!num_slots)
119                 return -1;                        119                 return -1;
120                                                   120 
121         ro0 = (struct rcom_slot *)(rc->rc_buf     121         ro0 = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config));
122                                                   122 
123         log_slots(ls, gen, num_slots, ro0, NUL    123         log_slots(ls, gen, num_slots, ro0, NULL, 0);
124                                                   124 
125         list_for_each_entry(memb, &ls->ls_node    125         list_for_each_entry(memb, &ls->ls_nodes, list) {
126                 for (i = 0, ro = ro0; i < num_    126                 for (i = 0, ro = ro0; i < num_slots; i++, ro++) {
127                         if (le32_to_cpu(ro->ro    127                         if (le32_to_cpu(ro->ro_nodeid) != memb->nodeid)
128                                 continue;         128                                 continue;
129                         memb->slot = le16_to_c    129                         memb->slot = le16_to_cpu(ro->ro_slot);
130                         memb->slot_prev = memb    130                         memb->slot_prev = memb->slot;
131                         break;                    131                         break;
132                 }                                 132                 }
133                                                   133 
134                 if (memb->nodeid == our_nodeid    134                 if (memb->nodeid == our_nodeid) {
135                         if (ls->ls_slot && ls-    135                         if (ls->ls_slot && ls->ls_slot != memb->slot) {
136                                 log_error(ls,     136                                 log_error(ls, "dlm_slots_copy_in our slot "
137                                           "cha    137                                           "changed %d %d", ls->ls_slot,
138                                           memb    138                                           memb->slot);
139                                 return -1;        139                                 return -1;
140                         }                         140                         }
141                                                   141 
142                         if (!ls->ls_slot)         142                         if (!ls->ls_slot)
143                                 ls->ls_slot =     143                                 ls->ls_slot = memb->slot;
144                 }                                 144                 }
145                                                   145 
146                 if (!memb->slot) {                146                 if (!memb->slot) {
147                         log_error(ls, "dlm_slo    147                         log_error(ls, "dlm_slots_copy_in nodeid %d no slot",
148                                    memb->nodei    148                                    memb->nodeid);
149                         return -1;                149                         return -1;
150                 }                                 150                 }
151         }                                         151         }
152                                                   152 
153         return 0;                                 153         return 0;
154 }                                                 154 }
155                                                   155 
156 /* for any nodes that do not support slots, we    156 /* for any nodes that do not support slots, we will not have set memb->slot
157    in wait_status_all(), so memb->slot will re    157    in wait_status_all(), so memb->slot will remain -1, and we will not
158    assign slots or set ls_num_slots here */       158    assign slots or set ls_num_slots here */
159                                                   159 
160 int dlm_slots_assign(struct dlm_ls *ls, int *n    160 int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size,
161                      struct dlm_slot **slots_o    161                      struct dlm_slot **slots_out, uint32_t *gen_out)
162 {                                                 162 {
163         struct dlm_member *memb;                  163         struct dlm_member *memb;
164         struct dlm_slot *array;                   164         struct dlm_slot *array;
165         int our_nodeid = dlm_our_nodeid();        165         int our_nodeid = dlm_our_nodeid();
166         int array_size, max_slots, i;             166         int array_size, max_slots, i;
167         int need = 0;                             167         int need = 0;
168         int max = 0;                              168         int max = 0;
169         int num = 0;                              169         int num = 0;
170         uint32_t gen = 0;                         170         uint32_t gen = 0;
171                                                   171 
172         /* our own memb struct will have slot     172         /* our own memb struct will have slot -1 gen 0 */
173                                                   173 
174         list_for_each_entry(memb, &ls->ls_node    174         list_for_each_entry(memb, &ls->ls_nodes, list) {
175                 if (memb->nodeid == our_nodeid    175                 if (memb->nodeid == our_nodeid) {
176                         memb->slot = ls->ls_sl    176                         memb->slot = ls->ls_slot;
177                         memb->generation = ls-    177                         memb->generation = ls->ls_generation;
178                         break;                    178                         break;
179                 }                                 179                 }
180         }                                         180         }
181                                                   181 
182         list_for_each_entry(memb, &ls->ls_node    182         list_for_each_entry(memb, &ls->ls_nodes, list) {
183                 if (memb->generation > gen)       183                 if (memb->generation > gen)
184                         gen = memb->generation    184                         gen = memb->generation;
185                                                   185 
186                 /* node doesn't support slots     186                 /* node doesn't support slots */
187                                                   187 
188                 if (memb->slot == -1)             188                 if (memb->slot == -1)
189                         return -1;                189                         return -1;
190                                                   190 
191                 /* node needs a slot assigned     191                 /* node needs a slot assigned */
192                                                   192 
193                 if (!memb->slot)                  193                 if (!memb->slot)
194                         need++;                   194                         need++;
195                                                   195 
196                 /* node has a slot assigned */    196                 /* node has a slot assigned */
197                                                   197 
198                 num++;                            198                 num++;
199                                                   199 
200                 if (!max || max < memb->slot)     200                 if (!max || max < memb->slot)
201                         max = memb->slot;         201                         max = memb->slot;
202                                                   202 
203                 /* sanity check, once slot is     203                 /* sanity check, once slot is assigned it shouldn't change */
204                                                   204 
205                 if (memb->slot_prev && memb->s    205                 if (memb->slot_prev && memb->slot && memb->slot_prev != memb->slot) {
206                         log_error(ls, "nodeid     206                         log_error(ls, "nodeid %d slot changed %d %d",
207                                   memb->nodeid    207                                   memb->nodeid, memb->slot_prev, memb->slot);
208                         return -1;                208                         return -1;
209                 }                                 209                 }
210                 memb->slot_prev = memb->slot;     210                 memb->slot_prev = memb->slot;
211         }                                         211         }
212                                                   212 
213         array_size = max + need;                  213         array_size = max + need;
214         array = kcalloc(array_size, sizeof(*ar    214         array = kcalloc(array_size, sizeof(*array), GFP_NOFS);
215         if (!array)                               215         if (!array)
216                 return -ENOMEM;                   216                 return -ENOMEM;
217                                                   217 
218         num = 0;                                  218         num = 0;
219                                                   219 
220         /* fill in slots (offsets) that are us    220         /* fill in slots (offsets) that are used */
221                                                   221 
222         list_for_each_entry(memb, &ls->ls_node    222         list_for_each_entry(memb, &ls->ls_nodes, list) {
223                 if (!memb->slot)                  223                 if (!memb->slot)
224                         continue;                 224                         continue;
225                                                   225 
226                 if (memb->slot > array_size) {    226                 if (memb->slot > array_size) {
227                         log_error(ls, "invalid    227                         log_error(ls, "invalid slot number %d", memb->slot);
228                         kfree(array);             228                         kfree(array);
229                         return -1;                229                         return -1;
230                 }                                 230                 }
231                                                   231 
232                 array[memb->slot - 1].nodeid =    232                 array[memb->slot - 1].nodeid = memb->nodeid;
233                 array[memb->slot - 1].slot = m    233                 array[memb->slot - 1].slot = memb->slot;
234                 num++;                            234                 num++;
235         }                                         235         }
236                                                   236 
237         /* assign new slots from unused offset    237         /* assign new slots from unused offsets */
238                                                   238 
239         list_for_each_entry(memb, &ls->ls_node    239         list_for_each_entry(memb, &ls->ls_nodes, list) {
240                 if (memb->slot)                   240                 if (memb->slot)
241                         continue;                 241                         continue;
242                                                   242 
243                 for (i = 0; i < array_size; i+    243                 for (i = 0; i < array_size; i++) {
244                         if (array[i].nodeid)      244                         if (array[i].nodeid)
245                                 continue;         245                                 continue;
246                                                   246 
247                         memb->slot = i + 1;       247                         memb->slot = i + 1;
248                         memb->slot_prev = memb    248                         memb->slot_prev = memb->slot;
249                         array[i].nodeid = memb    249                         array[i].nodeid = memb->nodeid;
250                         array[i].slot = memb->    250                         array[i].slot = memb->slot;
251                         num++;                    251                         num++;
252                                                   252 
253                         if (!ls->ls_slot && me    253                         if (!ls->ls_slot && memb->nodeid == our_nodeid)
254                                 ls->ls_slot =     254                                 ls->ls_slot = memb->slot;
255                         break;                    255                         break;
256                 }                                 256                 }
257                                                   257 
258                 if (!memb->slot) {                258                 if (!memb->slot) {
259                         log_error(ls, "no free    259                         log_error(ls, "no free slot found");
260                         kfree(array);             260                         kfree(array);
261                         return -1;                261                         return -1;
262                 }                                 262                 }
263         }                                         263         }
264                                                   264 
265         gen++;                                    265         gen++;
266                                                   266 
267         log_slots(ls, gen, num, NULL, array, a    267         log_slots(ls, gen, num, NULL, array, array_size);
268                                                   268 
269         max_slots = (DLM_MAX_APP_BUFSIZE - siz    269         max_slots = (DLM_MAX_APP_BUFSIZE - sizeof(struct dlm_rcom) -
270                      sizeof(struct rcom_config    270                      sizeof(struct rcom_config)) / sizeof(struct rcom_slot);
271                                                   271 
272         if (num > max_slots) {                    272         if (num > max_slots) {
273                 log_error(ls, "num_slots %d ex    273                 log_error(ls, "num_slots %d exceeds max_slots %d",
274                           num, max_slots);        274                           num, max_slots);
275                 kfree(array);                     275                 kfree(array);
276                 return -1;                        276                 return -1;
277         }                                         277         }
278                                                   278 
279         *gen_out = gen;                           279         *gen_out = gen;
280         *slots_out = array;                       280         *slots_out = array;
281         *slots_size = array_size;                 281         *slots_size = array_size;
282         *num_slots = num;                         282         *num_slots = num;
283         return 0;                                 283         return 0;
284 }                                                 284 }
285                                                   285 
286 static void add_ordered_member(struct dlm_ls *    286 static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new)
287 {                                                 287 {
288         struct dlm_member *memb = NULL;           288         struct dlm_member *memb = NULL;
289         struct list_head *tmp;                    289         struct list_head *tmp;
290         struct list_head *newlist = &new->list    290         struct list_head *newlist = &new->list;
291         struct list_head *head = &ls->ls_nodes    291         struct list_head *head = &ls->ls_nodes;
292                                                   292 
293         list_for_each(tmp, head) {                293         list_for_each(tmp, head) {
294                 memb = list_entry(tmp, struct     294                 memb = list_entry(tmp, struct dlm_member, list);
295                 if (new->nodeid < memb->nodeid    295                 if (new->nodeid < memb->nodeid)
296                         break;                    296                         break;
297         }                                         297         }
298                                                   298 
299         if (!memb)                                299         if (!memb)
300                 list_add_tail(newlist, head);     300                 list_add_tail(newlist, head);
301         else {                                    301         else {
302                 /* FIXME: can use list macro h    302                 /* FIXME: can use list macro here */
303                 newlist->prev = tmp->prev;        303                 newlist->prev = tmp->prev;
304                 newlist->next = tmp;              304                 newlist->next = tmp;
305                 tmp->prev->next = newlist;        305                 tmp->prev->next = newlist;
306                 tmp->prev = newlist;              306                 tmp->prev = newlist;
307         }                                         307         }
308 }                                                 308 }
309                                                   309 
310 static int add_remote_member(int nodeid)          310 static int add_remote_member(int nodeid)
311 {                                                 311 {
312         int error;                                312         int error;
313                                                   313 
314         if (nodeid == dlm_our_nodeid())           314         if (nodeid == dlm_our_nodeid())
315                 return 0;                         315                 return 0;
316                                                   316 
317         error = dlm_lowcomms_connect_node(node    317         error = dlm_lowcomms_connect_node(nodeid);
318         if (error < 0)                            318         if (error < 0)
319                 return error;                     319                 return error;
320                                                   320 
321         dlm_midcomms_add_member(nodeid);          321         dlm_midcomms_add_member(nodeid);
322         return 0;                                 322         return 0;
323 }                                                 323 }
324                                                   324 
325 static int dlm_add_member(struct dlm_ls *ls, s    325 static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node)
326 {                                                 326 {
327         struct dlm_member *memb;                  327         struct dlm_member *memb;
328         int error;                                328         int error;
329                                                   329 
330         memb = kzalloc(sizeof(*memb), GFP_NOFS    330         memb = kzalloc(sizeof(*memb), GFP_NOFS);
331         if (!memb)                                331         if (!memb)
332                 return -ENOMEM;                   332                 return -ENOMEM;
333                                                   333 
334         memb->nodeid = node->nodeid;              334         memb->nodeid = node->nodeid;
335         memb->weight = node->weight;              335         memb->weight = node->weight;
336         memb->comm_seq = node->comm_seq;          336         memb->comm_seq = node->comm_seq;
337                                                   337 
338         error = add_remote_member(node->nodeid    338         error = add_remote_member(node->nodeid);
339         if (error < 0) {                          339         if (error < 0) {
340                 kfree(memb);                      340                 kfree(memb);
341                 return error;                     341                 return error;
342         }                                         342         }
343                                                   343 
344         add_ordered_member(ls, memb);             344         add_ordered_member(ls, memb);
345         ls->ls_num_nodes++;                       345         ls->ls_num_nodes++;
346         return 0;                                 346         return 0;
347 }                                                 347 }
348                                                   348 
349 static struct dlm_member *find_memb(struct lis    349 static struct dlm_member *find_memb(struct list_head *head, int nodeid)
350 {                                                 350 {
351         struct dlm_member *memb;                  351         struct dlm_member *memb;
352                                                   352 
353         list_for_each_entry(memb, head, list)     353         list_for_each_entry(memb, head, list) {
354                 if (memb->nodeid == nodeid)       354                 if (memb->nodeid == nodeid)
355                         return memb;              355                         return memb;
356         }                                         356         }
357         return NULL;                              357         return NULL;
358 }                                                 358 }
359                                                   359 
360 int dlm_is_member(struct dlm_ls *ls, int nodei    360 int dlm_is_member(struct dlm_ls *ls, int nodeid)
361 {                                                 361 {
362         if (find_memb(&ls->ls_nodes, nodeid))     362         if (find_memb(&ls->ls_nodes, nodeid))
363                 return 1;                         363                 return 1;
364         return 0;                                 364         return 0;
365 }                                                 365 }
366                                                   366 
367 int dlm_is_removed(struct dlm_ls *ls, int node    367 int dlm_is_removed(struct dlm_ls *ls, int nodeid)
368 {                                                 368 {
369         WARN_ON_ONCE(!nodeid || nodeid == -1); << 
370                                                << 
371         if (find_memb(&ls->ls_nodes_gone, node    369         if (find_memb(&ls->ls_nodes_gone, nodeid))
372                 return 1;                         370                 return 1;
373         return 0;                                 371         return 0;
374 }                                                 372 }
375                                                   373 
376 static void clear_memb_list(struct list_head *    374 static void clear_memb_list(struct list_head *head,
377                             void (*after_del)(    375                             void (*after_del)(int nodeid))
378 {                                                 376 {
379         struct dlm_member *memb;                  377         struct dlm_member *memb;
380                                                   378 
381         while (!list_empty(head)) {               379         while (!list_empty(head)) {
382                 memb = list_entry(head->next,     380                 memb = list_entry(head->next, struct dlm_member, list);
383                 list_del(&memb->list);            381                 list_del(&memb->list);
384                 if (after_del)                    382                 if (after_del)
385                         after_del(memb->nodeid    383                         after_del(memb->nodeid);
386                 kfree(memb);                      384                 kfree(memb);
387         }                                         385         }
388 }                                                 386 }
389                                                   387 
390 static void remove_remote_member(int nodeid)      388 static void remove_remote_member(int nodeid)
391 {                                                 389 {
392         if (nodeid == dlm_our_nodeid())           390         if (nodeid == dlm_our_nodeid())
393                 return;                           391                 return;
394                                                   392 
395         dlm_midcomms_remove_member(nodeid);       393         dlm_midcomms_remove_member(nodeid);
396 }                                                 394 }
397                                                   395 
398 void dlm_clear_members(struct dlm_ls *ls)         396 void dlm_clear_members(struct dlm_ls *ls)
399 {                                                 397 {
400         clear_memb_list(&ls->ls_nodes, remove_    398         clear_memb_list(&ls->ls_nodes, remove_remote_member);
401         ls->ls_num_nodes = 0;                     399         ls->ls_num_nodes = 0;
402 }                                                 400 }
403                                                   401 
404 void dlm_clear_members_gone(struct dlm_ls *ls)    402 void dlm_clear_members_gone(struct dlm_ls *ls)
405 {                                                 403 {
406         clear_memb_list(&ls->ls_nodes_gone, NU    404         clear_memb_list(&ls->ls_nodes_gone, NULL);
407 }                                                 405 }
408                                                   406 
409 static void make_member_array(struct dlm_ls *l    407 static void make_member_array(struct dlm_ls *ls)
410 {                                                 408 {
411         struct dlm_member *memb;                  409         struct dlm_member *memb;
412         int i, w, x = 0, total = 0, all_zero =    410         int i, w, x = 0, total = 0, all_zero = 0, *array;
413                                                   411 
414         kfree(ls->ls_node_array);                 412         kfree(ls->ls_node_array);
415         ls->ls_node_array = NULL;                 413         ls->ls_node_array = NULL;
416                                                   414 
417         list_for_each_entry(memb, &ls->ls_node    415         list_for_each_entry(memb, &ls->ls_nodes, list) {
418                 if (memb->weight)                 416                 if (memb->weight)
419                         total += memb->weight;    417                         total += memb->weight;
420         }                                         418         }
421                                                   419 
422         /* all nodes revert to weight of 1 if     420         /* all nodes revert to weight of 1 if all have weight 0 */
423                                                   421 
424         if (!total) {                             422         if (!total) {
425                 total = ls->ls_num_nodes;         423                 total = ls->ls_num_nodes;
426                 all_zero = 1;                     424                 all_zero = 1;
427         }                                         425         }
428                                                   426 
429         ls->ls_total_weight = total;              427         ls->ls_total_weight = total;
430         array = kmalloc_array(total, sizeof(*a    428         array = kmalloc_array(total, sizeof(*array), GFP_NOFS);
431         if (!array)                               429         if (!array)
432                 return;                           430                 return;
433                                                   431 
434         list_for_each_entry(memb, &ls->ls_node    432         list_for_each_entry(memb, &ls->ls_nodes, list) {
435                 if (!all_zero && !memb->weight    433                 if (!all_zero && !memb->weight)
436                         continue;                 434                         continue;
437                                                   435 
438                 if (all_zero)                     436                 if (all_zero)
439                         w = 1;                    437                         w = 1;
440                 else                              438                 else
441                         w = memb->weight;         439                         w = memb->weight;
442                                                   440 
443                 DLM_ASSERT(x < total, printk("    441                 DLM_ASSERT(x < total, printk("total %d x %d\n", total, x););
444                                                   442 
445                 for (i = 0; i < w; i++)           443                 for (i = 0; i < w; i++)
446                         array[x++] = memb->nod    444                         array[x++] = memb->nodeid;
447         }                                         445         }
448                                                   446 
449         ls->ls_node_array = array;                447         ls->ls_node_array = array;
450 }                                                 448 }
451                                                   449 
452 /* send a status request to all members just t    450 /* send a status request to all members just to establish comms connections */
453                                                   451 
454 static int ping_members(struct dlm_ls *ls, uin    452 static int ping_members(struct dlm_ls *ls, uint64_t seq)
455 {                                                 453 {
456         struct dlm_member *memb;                  454         struct dlm_member *memb;
457         int error = 0;                            455         int error = 0;
458                                                   456 
459         list_for_each_entry(memb, &ls->ls_node    457         list_for_each_entry(memb, &ls->ls_nodes, list) {
460                 if (dlm_recovery_stopped(ls))     458                 if (dlm_recovery_stopped(ls)) {
461                         error = -EINTR;           459                         error = -EINTR;
462                         break;                    460                         break;
463                 }                                 461                 }
464                 error = dlm_rcom_status(ls, me    462                 error = dlm_rcom_status(ls, memb->nodeid, 0, seq);
465                 if (error)                        463                 if (error)
466                         break;                    464                         break;
467         }                                         465         }
468         if (error)                                466         if (error)
469                 log_rinfo(ls, "ping_members ab    467                 log_rinfo(ls, "ping_members aborted %d last nodeid %d",
470                           error, ls->ls_recove    468                           error, ls->ls_recover_nodeid);
471         return error;                             469         return error;
472 }                                                 470 }
473                                                   471 
474 static void dlm_lsop_recover_prep(struct dlm_l    472 static void dlm_lsop_recover_prep(struct dlm_ls *ls)
475 {                                                 473 {
476         if (!ls->ls_ops || !ls->ls_ops->recove    474         if (!ls->ls_ops || !ls->ls_ops->recover_prep)
477                 return;                           475                 return;
478         ls->ls_ops->recover_prep(ls->ls_ops_ar    476         ls->ls_ops->recover_prep(ls->ls_ops_arg);
479 }                                                 477 }
480                                                   478 
481 static void dlm_lsop_recover_slot(struct dlm_l    479 static void dlm_lsop_recover_slot(struct dlm_ls *ls, struct dlm_member *memb)
482 {                                                 480 {
483         struct dlm_slot slot;                     481         struct dlm_slot slot;
484         uint32_t seq;                             482         uint32_t seq;
485         int error;                                483         int error;
486                                                   484 
487         if (!ls->ls_ops || !ls->ls_ops->recove    485         if (!ls->ls_ops || !ls->ls_ops->recover_slot)
488                 return;                           486                 return;
489                                                   487 
490         /* if there is no comms connection wit    488         /* if there is no comms connection with this node
491            or the present comms connection is     489            or the present comms connection is newer
492            than the one when this member was a    490            than the one when this member was added, then
493            we consider the node to have failed    491            we consider the node to have failed (versus
494            being removed due to dlm_release_lo    492            being removed due to dlm_release_lockspace) */
495                                                   493 
496         error = dlm_comm_seq(memb->nodeid, &se    494         error = dlm_comm_seq(memb->nodeid, &seq);
497                                                   495 
498         if (!error && seq == memb->comm_seq)      496         if (!error && seq == memb->comm_seq)
499                 return;                           497                 return;
500                                                   498 
501         slot.nodeid = memb->nodeid;               499         slot.nodeid = memb->nodeid;
502         slot.slot = memb->slot;                   500         slot.slot = memb->slot;
503                                                   501 
504         ls->ls_ops->recover_slot(ls->ls_ops_ar    502         ls->ls_ops->recover_slot(ls->ls_ops_arg, &slot);
505 }                                                 503 }
506                                                   504 
507 void dlm_lsop_recover_done(struct dlm_ls *ls)     505 void dlm_lsop_recover_done(struct dlm_ls *ls)
508 {                                                 506 {
509         struct dlm_member *memb;                  507         struct dlm_member *memb;
510         struct dlm_slot *slots;                   508         struct dlm_slot *slots;
511         int i, num;                               509         int i, num;
512                                                   510 
513         if (!ls->ls_ops || !ls->ls_ops->recove    511         if (!ls->ls_ops || !ls->ls_ops->recover_done)
514                 return;                           512                 return;
515                                                   513 
516         num = ls->ls_num_nodes;                   514         num = ls->ls_num_nodes;
517         slots = kcalloc(num, sizeof(*slots), G    515         slots = kcalloc(num, sizeof(*slots), GFP_KERNEL);
518         if (!slots)                               516         if (!slots)
519                 return;                           517                 return;
520                                                   518 
521         i = 0;                                    519         i = 0;
522         list_for_each_entry(memb, &ls->ls_node    520         list_for_each_entry(memb, &ls->ls_nodes, list) {
523                 if (i == num) {                   521                 if (i == num) {
524                         log_error(ls, "dlm_lso    522                         log_error(ls, "dlm_lsop_recover_done bad num %d", num);
525                         goto out;                 523                         goto out;
526                 }                                 524                 }
527                 slots[i].nodeid = memb->nodeid    525                 slots[i].nodeid = memb->nodeid;
528                 slots[i].slot = memb->slot;       526                 slots[i].slot = memb->slot;
529                 i++;                              527                 i++;
530         }                                         528         }
531                                                   529 
532         ls->ls_ops->recover_done(ls->ls_ops_ar    530         ls->ls_ops->recover_done(ls->ls_ops_arg, slots, num,
533                                  ls->ls_slot,     531                                  ls->ls_slot, ls->ls_generation);
534  out:                                             532  out:
535         kfree(slots);                             533         kfree(slots);
536 }                                                 534 }
537                                                   535 
538 static struct dlm_config_node *find_config_nod    536 static struct dlm_config_node *find_config_node(struct dlm_recover *rv,
539                                                   537                                                 int nodeid)
540 {                                                 538 {
541         int i;                                    539         int i;
542                                                   540 
543         for (i = 0; i < rv->nodes_count; i++)     541         for (i = 0; i < rv->nodes_count; i++) {
544                 if (rv->nodes[i].nodeid == nod    542                 if (rv->nodes[i].nodeid == nodeid)
545                         return &rv->nodes[i];     543                         return &rv->nodes[i];
546         }                                         544         }
547         return NULL;                              545         return NULL;
548 }                                                 546 }
549                                                   547 
550 int dlm_recover_members(struct dlm_ls *ls, str    548 int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
551 {                                                 549 {
552         struct dlm_member *memb, *safe;           550         struct dlm_member *memb, *safe;
553         struct dlm_config_node *node;             551         struct dlm_config_node *node;
554         int i, error, neg = 0, low = -1;          552         int i, error, neg = 0, low = -1;
555                                                   553 
556         /* previously removed members that we'    554         /* previously removed members that we've not finished removing need to
557          * count as a negative change so the "    555          * count as a negative change so the "neg" recovery steps will happen
558          *                                        556          *
559          * This functionality must report all     557          * This functionality must report all member changes to lsops or
560          * midcomms layer and must never retur    558          * midcomms layer and must never return before.
561          */                                       559          */
562                                                   560 
563         list_for_each_entry(memb, &ls->ls_node    561         list_for_each_entry(memb, &ls->ls_nodes_gone, list) {
564                 log_rinfo(ls, "prev removed me    562                 log_rinfo(ls, "prev removed member %d", memb->nodeid);
565                 neg++;                            563                 neg++;
566         }                                         564         }
567                                                   565 
568         /* move departed members from ls_nodes    566         /* move departed members from ls_nodes to ls_nodes_gone */
569                                                   567 
570         list_for_each_entry_safe(memb, safe, &    568         list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) {
571                 node = find_config_node(rv, me    569                 node = find_config_node(rv, memb->nodeid);
572                 if (node && !node->new)           570                 if (node && !node->new)
573                         continue;                 571                         continue;
574                                                   572 
575                 if (!node) {                      573                 if (!node) {
576                         log_rinfo(ls, "remove     574                         log_rinfo(ls, "remove member %d", memb->nodeid);
577                 } else {                          575                 } else {
578                         /* removed and re-adde    576                         /* removed and re-added */
579                         log_rinfo(ls, "remove     577                         log_rinfo(ls, "remove member %d comm_seq %u %u",
580                                   memb->nodeid    578                                   memb->nodeid, memb->comm_seq, node->comm_seq);
581                 }                                 579                 }
582                                                   580 
583                 neg++;                            581                 neg++;
584                 list_move(&memb->list, &ls->ls    582                 list_move(&memb->list, &ls->ls_nodes_gone);
585                 remove_remote_member(memb->nod    583                 remove_remote_member(memb->nodeid);
586                 ls->ls_num_nodes--;               584                 ls->ls_num_nodes--;
587                 dlm_lsop_recover_slot(ls, memb    585                 dlm_lsop_recover_slot(ls, memb);
588         }                                         586         }
589                                                   587 
590         /* add new members to ls_nodes */         588         /* add new members to ls_nodes */
591                                                   589 
592         for (i = 0; i < rv->nodes_count; i++)     590         for (i = 0; i < rv->nodes_count; i++) {
593                 node = &rv->nodes[i];             591                 node = &rv->nodes[i];
594                 if (dlm_is_member(ls, node->no    592                 if (dlm_is_member(ls, node->nodeid))
595                         continue;                 593                         continue;
596                 error = dlm_add_member(ls, nod    594                 error = dlm_add_member(ls, node);
597                 if (error)                        595                 if (error)
598                         return error;             596                         return error;
599                                                   597 
600                 log_rinfo(ls, "add member %d",    598                 log_rinfo(ls, "add member %d", node->nodeid);
601         }                                         599         }
602                                                   600 
603         list_for_each_entry(memb, &ls->ls_node    601         list_for_each_entry(memb, &ls->ls_nodes, list) {
604                 if (low == -1 || memb->nodeid     602                 if (low == -1 || memb->nodeid < low)
605                         low = memb->nodeid;       603                         low = memb->nodeid;
606         }                                         604         }
607         ls->ls_low_nodeid = low;                  605         ls->ls_low_nodeid = low;
608                                                   606 
609         make_member_array(ls);                    607         make_member_array(ls);
610         *neg_out = neg;                           608         *neg_out = neg;
611                                                   609 
612         error = ping_members(ls, rv->seq);        610         error = ping_members(ls, rv->seq);
613         log_rinfo(ls, "dlm_recover_members %d     611         log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
614         return error;                             612         return error;
615 }                                                 613 }
616                                                   614 
617 /* Userspace guarantees that dlm_ls_stop() has    615 /* Userspace guarantees that dlm_ls_stop() has completed on all nodes before
618    dlm_ls_start() is called on any of them to     616    dlm_ls_start() is called on any of them to start the new recovery. */
619                                                   617 
620 int dlm_ls_stop(struct dlm_ls *ls)                618 int dlm_ls_stop(struct dlm_ls *ls)
621 {                                                 619 {
622         int new;                                  620         int new;
623                                                   621 
624         /*                                        622         /*
625          * Prevent dlm_recv from being in the     623          * Prevent dlm_recv from being in the middle of something when we do
626          * the stop.  This includes ensuring d    624          * the stop.  This includes ensuring dlm_recv isn't processing a
627          * recovery message (rcom), while dlm_    625          * recovery message (rcom), while dlm_recoverd is aborting and
628          * resetting things from an in-progres    626          * resetting things from an in-progress recovery.  i.e. we want
629          * dlm_recoverd to abort its recovery     627          * dlm_recoverd to abort its recovery without worrying about dlm_recv
630          * processing an rcom at the same time    628          * processing an rcom at the same time.  Stopping dlm_recv also makes
631          * it easy for dlm_receive_message() t    629          * it easy for dlm_receive_message() to check locking stopped and add a
632          * message to the requestqueue without    630          * message to the requestqueue without races.
633          */                                       631          */
634                                                   632 
635         write_lock_bh(&ls->ls_recv_active);    !! 633         down_write(&ls->ls_recv_active);
636                                                   634 
637         /*                                        635         /*
638          * Abort any recovery that's in progre    636          * Abort any recovery that's in progress (see RECOVER_STOP,
639          * dlm_recovery_stopped()) and tell an    637          * dlm_recovery_stopped()) and tell any other threads running in the
640          * dlm to quit any processing (see RUN    638          * dlm to quit any processing (see RUNNING, dlm_locking_stopped()).
641          */                                       639          */
642                                                   640 
643         spin_lock_bh(&ls->ls_recover_lock);    !! 641         spin_lock(&ls->ls_recover_lock);
644         set_bit(LSFL_RECOVER_STOP, &ls->ls_fla    642         set_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
645         new = test_and_clear_bit(LSFL_RUNNING,    643         new = test_and_clear_bit(LSFL_RUNNING, &ls->ls_flags);
646         if (new)                               << 
647                 timer_delete_sync(&ls->ls_scan << 
648         ls->ls_recover_seq++;                     644         ls->ls_recover_seq++;
649                                                !! 645         spin_unlock(&ls->ls_recover_lock);
650         /* activate requestqueue and stop proc << 
651         write_lock_bh(&ls->ls_requestqueue_loc << 
652         set_bit(LSFL_RECV_MSG_BLOCKED, &ls->ls << 
653         write_unlock_bh(&ls->ls_requestqueue_l << 
654         spin_unlock_bh(&ls->ls_recover_lock);  << 
655                                                   646 
656         /*                                        647         /*
657          * Let dlm_recv run again, now any nor    648          * Let dlm_recv run again, now any normal messages will be saved on the
658          * requestqueue for later.                649          * requestqueue for later.
659          */                                       650          */
660                                                   651 
661         write_unlock_bh(&ls->ls_recv_active);  !! 652         up_write(&ls->ls_recv_active);
662                                                   653 
663         /*                                        654         /*
664          * This in_recovery lock does two thin    655          * This in_recovery lock does two things:
665          * 1) Keeps this function from returni    656          * 1) Keeps this function from returning until all threads are out
666          *    of locking routines and locking     657          *    of locking routines and locking is truly stopped.
667          * 2) Keeps any new requests from bein    658          * 2) Keeps any new requests from being processed until it's unlocked
668          *    when recovery is complete.          659          *    when recovery is complete.
669          */                                       660          */
670                                                   661 
671         if (new) {                                662         if (new) {
672                 set_bit(LSFL_RECOVER_DOWN, &ls    663                 set_bit(LSFL_RECOVER_DOWN, &ls->ls_flags);
673                 wake_up_process(ls->ls_recover    664                 wake_up_process(ls->ls_recoverd_task);
674                 wait_event(ls->ls_recover_lock    665                 wait_event(ls->ls_recover_lock_wait,
675                            test_bit(LSFL_RECOV    666                            test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
676         }                                         667         }
677                                                   668 
678         /*                                        669         /*
679          * The recoverd suspend/resume makes s    670          * The recoverd suspend/resume makes sure that dlm_recoverd (if
680          * running) has noticed RECOVER_STOP a    671          * running) has noticed RECOVER_STOP above and quit processing the
681          * previous recovery.                     672          * previous recovery.
682          */                                       673          */
683                                                   674 
684         dlm_recoverd_suspend(ls);                 675         dlm_recoverd_suspend(ls);
685                                                   676 
686         spin_lock_bh(&ls->ls_recover_lock);    !! 677         spin_lock(&ls->ls_recover_lock);
687         kfree(ls->ls_slots);                      678         kfree(ls->ls_slots);
688         ls->ls_slots = NULL;                      679         ls->ls_slots = NULL;
689         ls->ls_num_slots = 0;                     680         ls->ls_num_slots = 0;
690         ls->ls_slots_size = 0;                    681         ls->ls_slots_size = 0;
691         ls->ls_recover_status = 0;                682         ls->ls_recover_status = 0;
692         spin_unlock_bh(&ls->ls_recover_lock);  !! 683         spin_unlock(&ls->ls_recover_lock);
693                                                   684 
694         dlm_recoverd_resume(ls);                  685         dlm_recoverd_resume(ls);
695                                                   686 
696         if (!ls->ls_recover_begin)                687         if (!ls->ls_recover_begin)
697                 ls->ls_recover_begin = jiffies    688                 ls->ls_recover_begin = jiffies;
698                                                   689 
699         /* call recover_prep ops only once and    690         /* call recover_prep ops only once and not multiple times
700          * for each possible dlm_ls_stop() whe    691          * for each possible dlm_ls_stop() when recovery is already
701          * stopped.                               692          * stopped.
702          *                                        693          *
703          * If we successful was able to clear     694          * If we successful was able to clear LSFL_RUNNING bit and
704          * it was set we know it is the first     695          * it was set we know it is the first dlm_ls_stop() call.
705          */                                       696          */
706         if (new)                                  697         if (new)
707                 dlm_lsop_recover_prep(ls);        698                 dlm_lsop_recover_prep(ls);
708                                                   699 
709         return 0;                                 700         return 0;
710 }                                                 701 }
711                                                   702 
712 int dlm_ls_start(struct dlm_ls *ls)               703 int dlm_ls_start(struct dlm_ls *ls)
713 {                                                 704 {
714         struct dlm_recover *rv, *rv_old;          705         struct dlm_recover *rv, *rv_old;
715         struct dlm_config_node *nodes = NULL;     706         struct dlm_config_node *nodes = NULL;
716         int error, count;                         707         int error, count;
717                                                   708 
718         rv = kzalloc(sizeof(*rv), GFP_NOFS);      709         rv = kzalloc(sizeof(*rv), GFP_NOFS);
719         if (!rv)                                  710         if (!rv)
720                 return -ENOMEM;                   711                 return -ENOMEM;
721                                                   712 
722         error = dlm_config_nodes(ls->ls_name,     713         error = dlm_config_nodes(ls->ls_name, &nodes, &count);
723         if (error < 0)                            714         if (error < 0)
724                 goto fail_rv;                     715                 goto fail_rv;
725                                                   716 
726         spin_lock_bh(&ls->ls_recover_lock);    !! 717         spin_lock(&ls->ls_recover_lock);
727                                                   718 
728         /* the lockspace needs to be stopped b    719         /* the lockspace needs to be stopped before it can be started */
729                                                   720 
730         if (!dlm_locking_stopped(ls)) {           721         if (!dlm_locking_stopped(ls)) {
731                 spin_unlock_bh(&ls->ls_recover !! 722                 spin_unlock(&ls->ls_recover_lock);
732                 log_error(ls, "start ignored:     723                 log_error(ls, "start ignored: lockspace running");
733                 error = -EINVAL;                  724                 error = -EINVAL;
734                 goto fail;                        725                 goto fail;
735         }                                         726         }
736                                                   727 
737         rv->nodes = nodes;                        728         rv->nodes = nodes;
738         rv->nodes_count = count;                  729         rv->nodes_count = count;
739         rv->seq = ++ls->ls_recover_seq;           730         rv->seq = ++ls->ls_recover_seq;
740         rv_old = ls->ls_recover_args;             731         rv_old = ls->ls_recover_args;
741         ls->ls_recover_args = rv;                 732         ls->ls_recover_args = rv;
742         spin_unlock_bh(&ls->ls_recover_lock);  !! 733         spin_unlock(&ls->ls_recover_lock);
743                                                   734 
744         if (rv_old) {                             735         if (rv_old) {
745                 log_error(ls, "unused recovery    736                 log_error(ls, "unused recovery %llx %d",
746                           (unsigned long long)    737                           (unsigned long long)rv_old->seq, rv_old->nodes_count);
747                 kfree(rv_old->nodes);             738                 kfree(rv_old->nodes);
748                 kfree(rv_old);                    739                 kfree(rv_old);
749         }                                         740         }
750                                                   741 
751         set_bit(LSFL_RECOVER_WORK, &ls->ls_fla    742         set_bit(LSFL_RECOVER_WORK, &ls->ls_flags);
752         wake_up_process(ls->ls_recoverd_task);    743         wake_up_process(ls->ls_recoverd_task);
753         return 0;                                 744         return 0;
754                                                   745 
755  fail:                                            746  fail:
756         kfree(nodes);                             747         kfree(nodes);
757  fail_rv:                                         748  fail_rv:
758         kfree(rv);                                749         kfree(rv);
759         return error;                             750         return error;
760 }                                                 751 }
761                                                   752 
762                                                   753 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php