~ [ 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.0.19)


  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(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)       << 
311 {                                              << 
312         int error;                             << 
313                                                << 
314         if (nodeid == dlm_our_nodeid())        << 
315                 return 0;                      << 
316                                                << 
317         error = dlm_lowcomms_connect_node(node << 
318         if (error < 0)                         << 
319                 return error;                  << 
320                                                << 
321         dlm_midcomms_add_member(nodeid);       << 
322         return 0;                              << 
323 }                                              << 
324                                                << 
325 static int dlm_add_member(struct dlm_ls *ls, s    310 static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node)
326 {                                                 311 {
327         struct dlm_member *memb;                  312         struct dlm_member *memb;
328         int error;                                313         int error;
329                                                   314 
330         memb = kzalloc(sizeof(*memb), GFP_NOFS    315         memb = kzalloc(sizeof(*memb), GFP_NOFS);
331         if (!memb)                                316         if (!memb)
332                 return -ENOMEM;                   317                 return -ENOMEM;
333                                                   318 
334         memb->nodeid = node->nodeid;           !! 319         error = dlm_lowcomms_connect_node(node->nodeid);
335         memb->weight = node->weight;           << 
336         memb->comm_seq = node->comm_seq;       << 
337                                                << 
338         error = add_remote_member(node->nodeid << 
339         if (error < 0) {                          320         if (error < 0) {
340                 kfree(memb);                      321                 kfree(memb);
341                 return error;                     322                 return error;
342         }                                         323         }
343                                                   324 
                                                   >> 325         memb->nodeid = node->nodeid;
                                                   >> 326         memb->weight = node->weight;
                                                   >> 327         memb->comm_seq = node->comm_seq;
                                                   >> 328         dlm_midcomms_add_member(node->nodeid);
344         add_ordered_member(ls, memb);             329         add_ordered_member(ls, memb);
345         ls->ls_num_nodes++;                       330         ls->ls_num_nodes++;
346         return 0;                                 331         return 0;
347 }                                                 332 }
348                                                   333 
349 static struct dlm_member *find_memb(struct lis    334 static struct dlm_member *find_memb(struct list_head *head, int nodeid)
350 {                                                 335 {
351         struct dlm_member *memb;                  336         struct dlm_member *memb;
352                                                   337 
353         list_for_each_entry(memb, head, list)     338         list_for_each_entry(memb, head, list) {
354                 if (memb->nodeid == nodeid)       339                 if (memb->nodeid == nodeid)
355                         return memb;              340                         return memb;
356         }                                         341         }
357         return NULL;                              342         return NULL;
358 }                                                 343 }
359                                                   344 
360 int dlm_is_member(struct dlm_ls *ls, int nodei    345 int dlm_is_member(struct dlm_ls *ls, int nodeid)
361 {                                                 346 {
362         if (find_memb(&ls->ls_nodes, nodeid))     347         if (find_memb(&ls->ls_nodes, nodeid))
363                 return 1;                         348                 return 1;
364         return 0;                                 349         return 0;
365 }                                                 350 }
366                                                   351 
367 int dlm_is_removed(struct dlm_ls *ls, int node    352 int dlm_is_removed(struct dlm_ls *ls, int nodeid)
368 {                                                 353 {
369         WARN_ON_ONCE(!nodeid || nodeid == -1); << 
370                                                << 
371         if (find_memb(&ls->ls_nodes_gone, node    354         if (find_memb(&ls->ls_nodes_gone, nodeid))
372                 return 1;                         355                 return 1;
373         return 0;                                 356         return 0;
374 }                                                 357 }
375                                                   358 
376 static void clear_memb_list(struct list_head *    359 static void clear_memb_list(struct list_head *head,
377                             void (*after_del)(    360                             void (*after_del)(int nodeid))
378 {                                                 361 {
379         struct dlm_member *memb;                  362         struct dlm_member *memb;
380                                                   363 
381         while (!list_empty(head)) {               364         while (!list_empty(head)) {
382                 memb = list_entry(head->next,     365                 memb = list_entry(head->next, struct dlm_member, list);
383                 list_del(&memb->list);            366                 list_del(&memb->list);
384                 if (after_del)                    367                 if (after_del)
385                         after_del(memb->nodeid    368                         after_del(memb->nodeid);
386                 kfree(memb);                      369                 kfree(memb);
387         }                                         370         }
388 }                                                 371 }
389                                                   372 
390 static void remove_remote_member(int nodeid)   !! 373 static void clear_members_cb(int nodeid)
391 {                                                 374 {
392         if (nodeid == dlm_our_nodeid())        << 
393                 return;                        << 
394                                                << 
395         dlm_midcomms_remove_member(nodeid);       375         dlm_midcomms_remove_member(nodeid);
396 }                                                 376 }
397                                                   377 
398 void dlm_clear_members(struct dlm_ls *ls)         378 void dlm_clear_members(struct dlm_ls *ls)
399 {                                                 379 {
400         clear_memb_list(&ls->ls_nodes, remove_ !! 380         clear_memb_list(&ls->ls_nodes, clear_members_cb);
401         ls->ls_num_nodes = 0;                     381         ls->ls_num_nodes = 0;
402 }                                                 382 }
403                                                   383 
404 void dlm_clear_members_gone(struct dlm_ls *ls)    384 void dlm_clear_members_gone(struct dlm_ls *ls)
405 {                                                 385 {
406         clear_memb_list(&ls->ls_nodes_gone, NU    386         clear_memb_list(&ls->ls_nodes_gone, NULL);
407 }                                                 387 }
408                                                   388 
409 static void make_member_array(struct dlm_ls *l    389 static void make_member_array(struct dlm_ls *ls)
410 {                                                 390 {
411         struct dlm_member *memb;                  391         struct dlm_member *memb;
412         int i, w, x = 0, total = 0, all_zero =    392         int i, w, x = 0, total = 0, all_zero = 0, *array;
413                                                   393 
414         kfree(ls->ls_node_array);                 394         kfree(ls->ls_node_array);
415         ls->ls_node_array = NULL;                 395         ls->ls_node_array = NULL;
416                                                   396 
417         list_for_each_entry(memb, &ls->ls_node    397         list_for_each_entry(memb, &ls->ls_nodes, list) {
418                 if (memb->weight)                 398                 if (memb->weight)
419                         total += memb->weight;    399                         total += memb->weight;
420         }                                         400         }
421                                                   401 
422         /* all nodes revert to weight of 1 if     402         /* all nodes revert to weight of 1 if all have weight 0 */
423                                                   403 
424         if (!total) {                             404         if (!total) {
425                 total = ls->ls_num_nodes;         405                 total = ls->ls_num_nodes;
426                 all_zero = 1;                     406                 all_zero = 1;
427         }                                         407         }
428                                                   408 
429         ls->ls_total_weight = total;              409         ls->ls_total_weight = total;
430         array = kmalloc_array(total, sizeof(*a    410         array = kmalloc_array(total, sizeof(*array), GFP_NOFS);
431         if (!array)                               411         if (!array)
432                 return;                           412                 return;
433                                                   413 
434         list_for_each_entry(memb, &ls->ls_node    414         list_for_each_entry(memb, &ls->ls_nodes, list) {
435                 if (!all_zero && !memb->weight    415                 if (!all_zero && !memb->weight)
436                         continue;                 416                         continue;
437                                                   417 
438                 if (all_zero)                     418                 if (all_zero)
439                         w = 1;                    419                         w = 1;
440                 else                              420                 else
441                         w = memb->weight;         421                         w = memb->weight;
442                                                   422 
443                 DLM_ASSERT(x < total, printk("    423                 DLM_ASSERT(x < total, printk("total %d x %d\n", total, x););
444                                                   424 
445                 for (i = 0; i < w; i++)           425                 for (i = 0; i < w; i++)
446                         array[x++] = memb->nod    426                         array[x++] = memb->nodeid;
447         }                                         427         }
448                                                   428 
449         ls->ls_node_array = array;                429         ls->ls_node_array = array;
450 }                                                 430 }
451                                                   431 
452 /* send a status request to all members just t    432 /* send a status request to all members just to establish comms connections */
453                                                   433 
454 static int ping_members(struct dlm_ls *ls, uin !! 434 static int ping_members(struct dlm_ls *ls)
455 {                                                 435 {
456         struct dlm_member *memb;                  436         struct dlm_member *memb;
457         int error = 0;                            437         int error = 0;
458                                                   438 
459         list_for_each_entry(memb, &ls->ls_node    439         list_for_each_entry(memb, &ls->ls_nodes, list) {
460                 if (dlm_recovery_stopped(ls))     440                 if (dlm_recovery_stopped(ls)) {
461                         error = -EINTR;           441                         error = -EINTR;
462                         break;                    442                         break;
463                 }                                 443                 }
464                 error = dlm_rcom_status(ls, me !! 444                 error = dlm_rcom_status(ls, memb->nodeid, 0);
465                 if (error)                        445                 if (error)
466                         break;                    446                         break;
467         }                                         447         }
468         if (error)                                448         if (error)
469                 log_rinfo(ls, "ping_members ab    449                 log_rinfo(ls, "ping_members aborted %d last nodeid %d",
470                           error, ls->ls_recove    450                           error, ls->ls_recover_nodeid);
471         return error;                             451         return error;
472 }                                                 452 }
473                                                   453 
474 static void dlm_lsop_recover_prep(struct dlm_l    454 static void dlm_lsop_recover_prep(struct dlm_ls *ls)
475 {                                                 455 {
476         if (!ls->ls_ops || !ls->ls_ops->recove    456         if (!ls->ls_ops || !ls->ls_ops->recover_prep)
477                 return;                           457                 return;
478         ls->ls_ops->recover_prep(ls->ls_ops_ar    458         ls->ls_ops->recover_prep(ls->ls_ops_arg);
479 }                                                 459 }
480                                                   460 
481 static void dlm_lsop_recover_slot(struct dlm_l    461 static void dlm_lsop_recover_slot(struct dlm_ls *ls, struct dlm_member *memb)
482 {                                                 462 {
483         struct dlm_slot slot;                     463         struct dlm_slot slot;
484         uint32_t seq;                             464         uint32_t seq;
485         int error;                                465         int error;
486                                                   466 
487         if (!ls->ls_ops || !ls->ls_ops->recove    467         if (!ls->ls_ops || !ls->ls_ops->recover_slot)
488                 return;                           468                 return;
489                                                   469 
490         /* if there is no comms connection wit    470         /* if there is no comms connection with this node
491            or the present comms connection is     471            or the present comms connection is newer
492            than the one when this member was a    472            than the one when this member was added, then
493            we consider the node to have failed    473            we consider the node to have failed (versus
494            being removed due to dlm_release_lo    474            being removed due to dlm_release_lockspace) */
495                                                   475 
496         error = dlm_comm_seq(memb->nodeid, &se    476         error = dlm_comm_seq(memb->nodeid, &seq);
497                                                   477 
498         if (!error && seq == memb->comm_seq)      478         if (!error && seq == memb->comm_seq)
499                 return;                           479                 return;
500                                                   480 
501         slot.nodeid = memb->nodeid;               481         slot.nodeid = memb->nodeid;
502         slot.slot = memb->slot;                   482         slot.slot = memb->slot;
503                                                   483 
504         ls->ls_ops->recover_slot(ls->ls_ops_ar    484         ls->ls_ops->recover_slot(ls->ls_ops_arg, &slot);
505 }                                                 485 }
506                                                   486 
507 void dlm_lsop_recover_done(struct dlm_ls *ls)     487 void dlm_lsop_recover_done(struct dlm_ls *ls)
508 {                                                 488 {
509         struct dlm_member *memb;                  489         struct dlm_member *memb;
510         struct dlm_slot *slots;                   490         struct dlm_slot *slots;
511         int i, num;                               491         int i, num;
512                                                   492 
513         if (!ls->ls_ops || !ls->ls_ops->recove    493         if (!ls->ls_ops || !ls->ls_ops->recover_done)
514                 return;                           494                 return;
515                                                   495 
516         num = ls->ls_num_nodes;                   496         num = ls->ls_num_nodes;
517         slots = kcalloc(num, sizeof(*slots), G    497         slots = kcalloc(num, sizeof(*slots), GFP_KERNEL);
518         if (!slots)                               498         if (!slots)
519                 return;                           499                 return;
520                                                   500 
521         i = 0;                                    501         i = 0;
522         list_for_each_entry(memb, &ls->ls_node    502         list_for_each_entry(memb, &ls->ls_nodes, list) {
523                 if (i == num) {                   503                 if (i == num) {
524                         log_error(ls, "dlm_lso    504                         log_error(ls, "dlm_lsop_recover_done bad num %d", num);
525                         goto out;                 505                         goto out;
526                 }                                 506                 }
527                 slots[i].nodeid = memb->nodeid    507                 slots[i].nodeid = memb->nodeid;
528                 slots[i].slot = memb->slot;       508                 slots[i].slot = memb->slot;
529                 i++;                              509                 i++;
530         }                                         510         }
531                                                   511 
532         ls->ls_ops->recover_done(ls->ls_ops_ar    512         ls->ls_ops->recover_done(ls->ls_ops_arg, slots, num,
533                                  ls->ls_slot,     513                                  ls->ls_slot, ls->ls_generation);
534  out:                                             514  out:
535         kfree(slots);                             515         kfree(slots);
536 }                                                 516 }
537                                                   517 
538 static struct dlm_config_node *find_config_nod    518 static struct dlm_config_node *find_config_node(struct dlm_recover *rv,
539                                                   519                                                 int nodeid)
540 {                                                 520 {
541         int i;                                    521         int i;
542                                                   522 
543         for (i = 0; i < rv->nodes_count; i++)     523         for (i = 0; i < rv->nodes_count; i++) {
544                 if (rv->nodes[i].nodeid == nod    524                 if (rv->nodes[i].nodeid == nodeid)
545                         return &rv->nodes[i];     525                         return &rv->nodes[i];
546         }                                         526         }
547         return NULL;                              527         return NULL;
548 }                                                 528 }
549                                                   529 
550 int dlm_recover_members(struct dlm_ls *ls, str    530 int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
551 {                                                 531 {
552         struct dlm_member *memb, *safe;           532         struct dlm_member *memb, *safe;
553         struct dlm_config_node *node;             533         struct dlm_config_node *node;
554         int i, error, neg = 0, low = -1;          534         int i, error, neg = 0, low = -1;
555                                                   535 
556         /* previously removed members that we'    536         /* previously removed members that we've not finished removing need to
557          * count as a negative change so the "    537          * count as a negative change so the "neg" recovery steps will happen
558          *                                        538          *
559          * This functionality must report all     539          * This functionality must report all member changes to lsops or
560          * midcomms layer and must never retur    540          * midcomms layer and must never return before.
561          */                                       541          */
562                                                   542 
563         list_for_each_entry(memb, &ls->ls_node    543         list_for_each_entry(memb, &ls->ls_nodes_gone, list) {
564                 log_rinfo(ls, "prev removed me    544                 log_rinfo(ls, "prev removed member %d", memb->nodeid);
565                 neg++;                            545                 neg++;
566         }                                         546         }
567                                                   547 
568         /* move departed members from ls_nodes    548         /* move departed members from ls_nodes to ls_nodes_gone */
569                                                   549 
570         list_for_each_entry_safe(memb, safe, &    550         list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) {
571                 node = find_config_node(rv, me    551                 node = find_config_node(rv, memb->nodeid);
572                 if (node && !node->new)           552                 if (node && !node->new)
573                         continue;                 553                         continue;
574                                                   554 
575                 if (!node) {                      555                 if (!node) {
576                         log_rinfo(ls, "remove     556                         log_rinfo(ls, "remove member %d", memb->nodeid);
577                 } else {                          557                 } else {
578                         /* removed and re-adde    558                         /* removed and re-added */
579                         log_rinfo(ls, "remove     559                         log_rinfo(ls, "remove member %d comm_seq %u %u",
580                                   memb->nodeid    560                                   memb->nodeid, memb->comm_seq, node->comm_seq);
581                 }                                 561                 }
582                                                   562 
583                 neg++;                            563                 neg++;
584                 list_move(&memb->list, &ls->ls    564                 list_move(&memb->list, &ls->ls_nodes_gone);
585                 remove_remote_member(memb->nod !! 565                 dlm_midcomms_remove_member(memb->nodeid);
586                 ls->ls_num_nodes--;               566                 ls->ls_num_nodes--;
587                 dlm_lsop_recover_slot(ls, memb    567                 dlm_lsop_recover_slot(ls, memb);
588         }                                         568         }
589                                                   569 
590         /* add new members to ls_nodes */         570         /* add new members to ls_nodes */
591                                                   571 
592         for (i = 0; i < rv->nodes_count; i++)     572         for (i = 0; i < rv->nodes_count; i++) {
593                 node = &rv->nodes[i];             573                 node = &rv->nodes[i];
594                 if (dlm_is_member(ls, node->no    574                 if (dlm_is_member(ls, node->nodeid))
595                         continue;                 575                         continue;
596                 error = dlm_add_member(ls, nod !! 576                 dlm_add_member(ls, node);
597                 if (error)                     << 
598                         return error;          << 
599                                                << 
600                 log_rinfo(ls, "add member %d",    577                 log_rinfo(ls, "add member %d", node->nodeid);
601         }                                         578         }
602                                                   579 
603         list_for_each_entry(memb, &ls->ls_node    580         list_for_each_entry(memb, &ls->ls_nodes, list) {
604                 if (low == -1 || memb->nodeid     581                 if (low == -1 || memb->nodeid < low)
605                         low = memb->nodeid;       582                         low = memb->nodeid;
606         }                                         583         }
607         ls->ls_low_nodeid = low;                  584         ls->ls_low_nodeid = low;
608                                                   585 
609         make_member_array(ls);                    586         make_member_array(ls);
610         *neg_out = neg;                           587         *neg_out = neg;
611                                                   588 
612         error = ping_members(ls, rv->seq);     !! 589         error = ping_members(ls);
613         log_rinfo(ls, "dlm_recover_members %d     590         log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
614         return error;                             591         return error;
615 }                                                 592 }
616                                                   593 
617 /* Userspace guarantees that dlm_ls_stop() has    594 /* Userspace guarantees that dlm_ls_stop() has completed on all nodes before
618    dlm_ls_start() is called on any of them to     595    dlm_ls_start() is called on any of them to start the new recovery. */
619                                                   596 
620 int dlm_ls_stop(struct dlm_ls *ls)                597 int dlm_ls_stop(struct dlm_ls *ls)
621 {                                                 598 {
622         int new;                                  599         int new;
623                                                   600 
624         /*                                        601         /*
625          * Prevent dlm_recv from being in the     602          * Prevent dlm_recv from being in the middle of something when we do
626          * the stop.  This includes ensuring d    603          * the stop.  This includes ensuring dlm_recv isn't processing a
627          * recovery message (rcom), while dlm_    604          * recovery message (rcom), while dlm_recoverd is aborting and
628          * resetting things from an in-progres    605          * resetting things from an in-progress recovery.  i.e. we want
629          * dlm_recoverd to abort its recovery     606          * dlm_recoverd to abort its recovery without worrying about dlm_recv
630          * processing an rcom at the same time    607          * processing an rcom at the same time.  Stopping dlm_recv also makes
631          * it easy for dlm_receive_message() t    608          * it easy for dlm_receive_message() to check locking stopped and add a
632          * message to the requestqueue without    609          * message to the requestqueue without races.
633          */                                       610          */
634                                                   611 
635         write_lock_bh(&ls->ls_recv_active);    !! 612         down_write(&ls->ls_recv_active);
636                                                   613 
637         /*                                        614         /*
638          * Abort any recovery that's in progre    615          * Abort any recovery that's in progress (see RECOVER_STOP,
639          * dlm_recovery_stopped()) and tell an    616          * dlm_recovery_stopped()) and tell any other threads running in the
640          * dlm to quit any processing (see RUN    617          * dlm to quit any processing (see RUNNING, dlm_locking_stopped()).
641          */                                       618          */
642                                                   619 
643         spin_lock_bh(&ls->ls_recover_lock);    !! 620         spin_lock(&ls->ls_recover_lock);
644         set_bit(LSFL_RECOVER_STOP, &ls->ls_fla    621         set_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
645         new = test_and_clear_bit(LSFL_RUNNING,    622         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++;                     623         ls->ls_recover_seq++;
649                                                !! 624         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                                                   625 
656         /*                                        626         /*
657          * Let dlm_recv run again, now any nor    627          * Let dlm_recv run again, now any normal messages will be saved on the
658          * requestqueue for later.                628          * requestqueue for later.
659          */                                       629          */
660                                                   630 
661         write_unlock_bh(&ls->ls_recv_active);  !! 631         up_write(&ls->ls_recv_active);
662                                                   632 
663         /*                                        633         /*
664          * This in_recovery lock does two thin    634          * This in_recovery lock does two things:
665          * 1) Keeps this function from returni    635          * 1) Keeps this function from returning until all threads are out
666          *    of locking routines and locking     636          *    of locking routines and locking is truly stopped.
667          * 2) Keeps any new requests from bein    637          * 2) Keeps any new requests from being processed until it's unlocked
668          *    when recovery is complete.          638          *    when recovery is complete.
669          */                                       639          */
670                                                   640 
671         if (new) {                                641         if (new) {
672                 set_bit(LSFL_RECOVER_DOWN, &ls    642                 set_bit(LSFL_RECOVER_DOWN, &ls->ls_flags);
673                 wake_up_process(ls->ls_recover    643                 wake_up_process(ls->ls_recoverd_task);
674                 wait_event(ls->ls_recover_lock    644                 wait_event(ls->ls_recover_lock_wait,
675                            test_bit(LSFL_RECOV    645                            test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
676         }                                         646         }
677                                                   647 
678         /*                                        648         /*
679          * The recoverd suspend/resume makes s    649          * The recoverd suspend/resume makes sure that dlm_recoverd (if
680          * running) has noticed RECOVER_STOP a    650          * running) has noticed RECOVER_STOP above and quit processing the
681          * previous recovery.                     651          * previous recovery.
682          */                                       652          */
683                                                   653 
684         dlm_recoverd_suspend(ls);                 654         dlm_recoverd_suspend(ls);
685                                                   655 
686         spin_lock_bh(&ls->ls_recover_lock);    !! 656         spin_lock(&ls->ls_recover_lock);
687         kfree(ls->ls_slots);                      657         kfree(ls->ls_slots);
688         ls->ls_slots = NULL;                      658         ls->ls_slots = NULL;
689         ls->ls_num_slots = 0;                     659         ls->ls_num_slots = 0;
690         ls->ls_slots_size = 0;                    660         ls->ls_slots_size = 0;
691         ls->ls_recover_status = 0;                661         ls->ls_recover_status = 0;
692         spin_unlock_bh(&ls->ls_recover_lock);  !! 662         spin_unlock(&ls->ls_recover_lock);
693                                                   663 
694         dlm_recoverd_resume(ls);                  664         dlm_recoverd_resume(ls);
695                                                   665 
696         if (!ls->ls_recover_begin)                666         if (!ls->ls_recover_begin)
697                 ls->ls_recover_begin = jiffies    667                 ls->ls_recover_begin = jiffies;
698                                                   668 
699         /* call recover_prep ops only once and    669         /* call recover_prep ops only once and not multiple times
700          * for each possible dlm_ls_stop() whe    670          * for each possible dlm_ls_stop() when recovery is already
701          * stopped.                               671          * stopped.
702          *                                        672          *
703          * If we successful was able to clear     673          * If we successful was able to clear LSFL_RUNNING bit and
704          * it was set we know it is the first     674          * it was set we know it is the first dlm_ls_stop() call.
705          */                                       675          */
706         if (new)                                  676         if (new)
707                 dlm_lsop_recover_prep(ls);        677                 dlm_lsop_recover_prep(ls);
708                                                   678 
709         return 0;                                 679         return 0;
710 }                                                 680 }
711                                                   681 
712 int dlm_ls_start(struct dlm_ls *ls)               682 int dlm_ls_start(struct dlm_ls *ls)
713 {                                                 683 {
714         struct dlm_recover *rv, *rv_old;          684         struct dlm_recover *rv, *rv_old;
715         struct dlm_config_node *nodes = NULL;     685         struct dlm_config_node *nodes = NULL;
716         int error, count;                         686         int error, count;
717                                                   687 
718         rv = kzalloc(sizeof(*rv), GFP_NOFS);      688         rv = kzalloc(sizeof(*rv), GFP_NOFS);
719         if (!rv)                                  689         if (!rv)
720                 return -ENOMEM;                   690                 return -ENOMEM;
721                                                   691 
722         error = dlm_config_nodes(ls->ls_name,     692         error = dlm_config_nodes(ls->ls_name, &nodes, &count);
723         if (error < 0)                            693         if (error < 0)
724                 goto fail_rv;                     694                 goto fail_rv;
725                                                   695 
726         spin_lock_bh(&ls->ls_recover_lock);    !! 696         spin_lock(&ls->ls_recover_lock);
727                                                   697 
728         /* the lockspace needs to be stopped b    698         /* the lockspace needs to be stopped before it can be started */
729                                                   699 
730         if (!dlm_locking_stopped(ls)) {           700         if (!dlm_locking_stopped(ls)) {
731                 spin_unlock_bh(&ls->ls_recover !! 701                 spin_unlock(&ls->ls_recover_lock);
732                 log_error(ls, "start ignored:     702                 log_error(ls, "start ignored: lockspace running");
733                 error = -EINVAL;                  703                 error = -EINVAL;
734                 goto fail;                        704                 goto fail;
735         }                                         705         }
736                                                   706 
737         rv->nodes = nodes;                        707         rv->nodes = nodes;
738         rv->nodes_count = count;                  708         rv->nodes_count = count;
739         rv->seq = ++ls->ls_recover_seq;           709         rv->seq = ++ls->ls_recover_seq;
740         rv_old = ls->ls_recover_args;             710         rv_old = ls->ls_recover_args;
741         ls->ls_recover_args = rv;                 711         ls->ls_recover_args = rv;
742         spin_unlock_bh(&ls->ls_recover_lock);  !! 712         spin_unlock(&ls->ls_recover_lock);
743                                                   713 
744         if (rv_old) {                             714         if (rv_old) {
745                 log_error(ls, "unused recovery    715                 log_error(ls, "unused recovery %llx %d",
746                           (unsigned long long)    716                           (unsigned long long)rv_old->seq, rv_old->nodes_count);
747                 kfree(rv_old->nodes);             717                 kfree(rv_old->nodes);
748                 kfree(rv_old);                    718                 kfree(rv_old);
749         }                                         719         }
750                                                   720 
751         set_bit(LSFL_RECOVER_WORK, &ls->ls_fla    721         set_bit(LSFL_RECOVER_WORK, &ls->ls_flags);
752         wake_up_process(ls->ls_recoverd_task);    722         wake_up_process(ls->ls_recoverd_task);
753         return 0;                                 723         return 0;
754                                                   724 
755  fail:                                            725  fail:
756         kfree(nodes);                             726         kfree(nodes);
757  fail_rv:                                         727  fail_rv:
758         kfree(rv);                                728         kfree(rv);
759         return error;                             729         return error;
760 }                                                 730 }
761                                                   731 
762                                                   732 

~ [ 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