Whamcloud - gitweb
LU-1267 lfsck: framework (1) for MDT-OST consistency
[fs/lustre-release.git] / lustre / lfsck / lfsck_layout.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License version 2 for more details.  A copy is
14  * included in the COPYING file that accompanied this code.
15
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2013, Intel Corporation.
24  */
25 /*
26  * lustre/lfsck/lfsck_layout.c
27  *
28  * Author: Fan, Yong <fan.yong@intel.com>
29  */
30
31 #ifndef EXPORT_SYMTAB
32 # define EXPORT_SYMTAB
33 #endif
34 #define DEBUG_SUBSYSTEM S_LFSCK
35
36 #include <linux/bitops.h>
37
38 #include <lustre/lustre_idl.h>
39 #include <lu_object.h>
40 #include <dt_object.h>
41 #include <lustre_linkea.h>
42 #include <lustre_fid.h>
43 #include <lustre_lib.h>
44 #include <lustre_net.h>
45 #include <lustre/lustre_user.h>
46
47 #include "lfsck_internal.h"
48
49 #define LFSCK_LAYOUT_MAGIC              0xB173AE14
50
51 static const char lfsck_layout_name[] = "lfsck_layout";
52
53 static void lfsck_layout_le_to_cpu(struct lfsck_layout *des,
54                                    const struct lfsck_layout *src)
55 {
56         int i;
57
58         des->ll_magic = le32_to_cpu(src->ll_magic);
59         des->ll_status = le32_to_cpu(src->ll_status);
60         des->ll_flags = le32_to_cpu(src->ll_flags);
61         des->ll_success_count = le32_to_cpu(src->ll_success_count);
62         des->ll_run_time_phase1 = le32_to_cpu(src->ll_run_time_phase1);
63         des->ll_run_time_phase2 = le32_to_cpu(src->ll_run_time_phase2);
64         des->ll_time_last_complete = le64_to_cpu(src->ll_time_last_complete);
65         des->ll_time_latest_start = le64_to_cpu(src->ll_time_latest_start);
66         des->ll_time_last_checkpoint =
67                                 le64_to_cpu(src->ll_time_last_checkpoint);
68         des->ll_pos_latest_start = le64_to_cpu(src->ll_pos_latest_start);
69         des->ll_pos_last_checkpoint = le64_to_cpu(src->ll_pos_last_checkpoint);
70         des->ll_pos_first_inconsistent =
71                         le64_to_cpu(src->ll_pos_first_inconsistent);
72         des->ll_objs_checked_phase1 = le64_to_cpu(src->ll_objs_checked_phase1);
73         des->ll_objs_failed_phase1 = le64_to_cpu(src->ll_objs_failed_phase1);
74         des->ll_objs_checked_phase2 = le64_to_cpu(src->ll_objs_checked_phase2);
75         des->ll_objs_failed_phase2 = le64_to_cpu(src->ll_objs_failed_phase2);
76         for (i = 0; i < LLIT_MAX; i++)
77                 des->ll_objs_repaired[i] =
78                                 le64_to_cpu(src->ll_objs_repaired[i]);
79         des->ll_objs_skipped = le64_to_cpu(src->ll_objs_skipped);
80 }
81
82 static void lfsck_layout_cpu_to_le(struct lfsck_layout *des,
83                                    const struct lfsck_layout *src)
84 {
85         int i;
86
87         des->ll_magic = cpu_to_le32(src->ll_magic);
88         des->ll_status = cpu_to_le32(src->ll_status);
89         des->ll_flags = cpu_to_le32(src->ll_flags);
90         des->ll_success_count = cpu_to_le32(src->ll_success_count);
91         des->ll_run_time_phase1 = cpu_to_le32(src->ll_run_time_phase1);
92         des->ll_run_time_phase2 = cpu_to_le32(src->ll_run_time_phase2);
93         des->ll_time_last_complete = cpu_to_le64(src->ll_time_last_complete);
94         des->ll_time_latest_start = cpu_to_le64(src->ll_time_latest_start);
95         des->ll_time_last_checkpoint =
96                                 cpu_to_le64(src->ll_time_last_checkpoint);
97         des->ll_pos_latest_start = cpu_to_le64(src->ll_pos_latest_start);
98         des->ll_pos_last_checkpoint = cpu_to_le64(src->ll_pos_last_checkpoint);
99         des->ll_pos_first_inconsistent =
100                         cpu_to_le64(src->ll_pos_first_inconsistent);
101         des->ll_objs_checked_phase1 = cpu_to_le64(src->ll_objs_checked_phase1);
102         des->ll_objs_failed_phase1 = cpu_to_le64(src->ll_objs_failed_phase1);
103         des->ll_objs_checked_phase2 = cpu_to_le64(src->ll_objs_checked_phase2);
104         des->ll_objs_failed_phase2 = cpu_to_le64(src->ll_objs_failed_phase2);
105         for (i = 0; i < LLIT_MAX; i++)
106                 des->ll_objs_repaired[i] =
107                                 cpu_to_le64(src->ll_objs_repaired[i]);
108         des->ll_objs_skipped = cpu_to_le64(src->ll_objs_skipped);
109 }
110
111 /**
112  * \retval +ve: the lfsck_layout is broken, the caller should reset it.
113  * \retval 0: succeed.
114  * \retval -ve: failed cases.
115  */
116 static int lfsck_layout_load(const struct lu_env *env,
117                              struct lfsck_component *com)
118 {
119         struct lfsck_layout             *lo     = com->lc_file_ram;
120         const struct dt_body_operations *dbo    = com->lc_obj->do_body_ops;
121         ssize_t                          size   = com->lc_file_size;
122         loff_t                           pos    = 0;
123         int                              rc;
124
125         rc = dbo->dbo_read(env, com->lc_obj,
126                            lfsck_buf_get(env, com->lc_file_disk, size), &pos,
127                            BYPASS_CAPA);
128         if (rc == 0) {
129                 return -ENOENT;
130         } else if (rc < 0) {
131                 CWARN("%s: failed to load lfsck_layout: rc = %d\n",
132                       lfsck_lfsck2name(com->lc_lfsck), rc);
133                 return rc;
134         } else if (rc != size) {
135                 CWARN("%s: crashed lfsck_layout, to be reset: rc = %d\n",
136                       lfsck_lfsck2name(com->lc_lfsck), rc);
137                 return 1;
138         }
139
140         lfsck_layout_le_to_cpu(lo, com->lc_file_disk);
141         if (lo->ll_magic != LFSCK_LAYOUT_MAGIC) {
142                 CWARN("%s: invalid lfsck_layout magic %#x != %#x, "
143                       "to be reset\n", lfsck_lfsck2name(com->lc_lfsck),
144                       lo->ll_magic, LFSCK_LAYOUT_MAGIC);
145                 return 1;
146         }
147
148         return 0;
149 }
150
151 static int lfsck_layout_store(const struct lu_env *env,
152                               struct lfsck_component *com)
153 {
154         struct dt_object         *obj           = com->lc_obj;
155         struct lfsck_instance    *lfsck         = com->lc_lfsck;
156         struct lfsck_layout      *lo            = com->lc_file_disk;
157         struct thandle           *handle;
158         ssize_t                   size          = com->lc_file_size;
159         loff_t                    pos           = 0;
160         int                       rc;
161         ENTRY;
162
163         lfsck_layout_cpu_to_le(lo, com->lc_file_ram);
164         handle = dt_trans_create(env, lfsck->li_bottom);
165         if (IS_ERR(handle)) {
166                 rc = PTR_ERR(handle);
167                 CERROR("%s: fail to create trans for storing lfsck_layout: "
168                        "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
169                 RETURN(rc);
170         }
171
172         rc = dt_declare_record_write(env, obj, size, pos, handle);
173         if (rc != 0) {
174                 CERROR("%s: fail to declare trans for storing lfsck_layout(1): "
175                        "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
176                 GOTO(out, rc);
177         }
178
179         rc = dt_trans_start_local(env, lfsck->li_bottom, handle);
180         if (rc != 0) {
181                 CERROR("%s: fail to start trans for storing lfsck_layout: "
182                        "rc = %d\n", lfsck_lfsck2name(lfsck), rc);
183                 GOTO(out, rc);
184         }
185
186         rc = dt_record_write(env, obj, lfsck_buf_get(env, lo, size), &pos,
187                              handle);
188         if (rc != 0)
189                 CERROR("%s: fail to store lfsck_layout(1): size = %d, "
190                        "rc = %d\n", lfsck_lfsck2name(lfsck), (int)size, rc);
191
192         GOTO(out, rc);
193
194 out:
195         dt_trans_stop(env, lfsck->li_bottom, handle);
196
197         return rc;
198 }
199
200 static int lfsck_layout_init(const struct lu_env *env,
201                              struct lfsck_component *com)
202 {
203         struct lfsck_layout *lo = com->lc_file_ram;
204         int rc;
205
206         memset(lo, 0, com->lc_file_size);
207         lo->ll_magic = LFSCK_LAYOUT_MAGIC;
208         lo->ll_status = LS_INIT;
209         down_write(&com->lc_sem);
210         rc = lfsck_layout_store(env, com);
211         up_write(&com->lc_sem);
212
213         return rc;
214 }
215
216 /* layout APIs */
217 /* XXX: Some to be implemented in other patch(es). */
218
219 static int lfsck_layout_reset(const struct lu_env *env,
220                               struct lfsck_component *com, bool init)
221 {
222         struct lfsck_layout     *lo    = com->lc_file_ram;
223         int                      rc;
224
225         down_write(&com->lc_sem);
226         if (init) {
227                 memset(lo, 0, com->lc_file_size);
228         } else {
229                 __u32 count = lo->ll_success_count;
230                 __u64 last_time = lo->ll_time_last_complete;
231
232                 memset(lo, 0, com->lc_file_size);
233                 lo->ll_success_count = count;
234                 lo->ll_time_last_complete = last_time;
235         }
236
237         lo->ll_magic = LFSCK_LAYOUT_MAGIC;
238         lo->ll_status = LS_INIT;
239
240         rc = lfsck_layout_store(env, com);
241         up_write(&com->lc_sem);
242
243         return rc;
244 }
245
246 static void lfsck_layout_fail(const struct lu_env *env,
247                               struct lfsck_component *com, bool new_checked)
248 {
249 }
250
251 static int lfsck_layout_checkpoint(const struct lu_env *env,
252                                    struct lfsck_component *com, bool init)
253 {
254         return 0;
255 }
256
257 static int lfsck_layout_master_prep(const struct lu_env *env,
258                                     struct lfsck_component *com)
259 {
260         return 0;
261 }
262
263 static int lfsck_layout_slave_prep(const struct lu_env *env,
264                                    struct lfsck_component *com)
265 {
266         return 0;
267 }
268
269 static int lfsck_layout_master_exec_oit(const struct lu_env *env,
270                                         struct lfsck_component *com,
271                                         struct dt_object *obj)
272 {
273         return 0;
274 }
275
276 static int lfsck_layout_slave_exec_oit(const struct lu_env *env,
277                                        struct lfsck_component *com,
278                                        struct dt_object *obj)
279 {
280         return 0;
281 }
282
283 static int lfsck_layout_exec_dir(const struct lu_env *env,
284                                  struct lfsck_component *com,
285                                  struct dt_object *obj,
286                                  struct lu_dirent *ent)
287 {
288         return 0;
289 }
290
291 static int lfsck_layout_master_post(const struct lu_env *env,
292                                     struct lfsck_component *com,
293                                     int result, bool init)
294 {
295         return 0;
296 }
297
298 static int lfsck_layout_slave_post(const struct lu_env *env,
299                                    struct lfsck_component *com,
300                                    int result, bool init)
301 {
302         return 0;
303 }
304
305 static int lfsck_layout_dump(const struct lu_env *env,
306                              struct lfsck_component *com, char *buf, int len)
307 {
308         return 0;
309 }
310
311 static int lfsck_layout_master_double_scan(const struct lu_env *env,
312                                            struct lfsck_component *com)
313 {
314         return 0;
315 }
316
317 static int lfsck_layout_slave_double_scan(const struct lu_env *env,
318                                           struct lfsck_component *com)
319 {
320         return 0;
321 }
322
323 static struct lfsck_operations lfsck_layout_master_ops = {
324         .lfsck_reset            = lfsck_layout_reset,
325         .lfsck_fail             = lfsck_layout_fail,
326         .lfsck_checkpoint       = lfsck_layout_checkpoint,
327         .lfsck_prep             = lfsck_layout_master_prep,
328         .lfsck_exec_oit         = lfsck_layout_master_exec_oit,
329         .lfsck_exec_dir         = lfsck_layout_exec_dir,
330         .lfsck_post             = lfsck_layout_master_post,
331         .lfsck_dump             = lfsck_layout_dump,
332         .lfsck_double_scan      = lfsck_layout_master_double_scan,
333 };
334
335 static struct lfsck_operations lfsck_layout_slave_ops = {
336         .lfsck_reset            = lfsck_layout_reset,
337         .lfsck_fail             = lfsck_layout_fail,
338         .lfsck_checkpoint       = lfsck_layout_checkpoint,
339         .lfsck_prep             = lfsck_layout_slave_prep,
340         .lfsck_exec_oit         = lfsck_layout_slave_exec_oit,
341         .lfsck_exec_dir         = lfsck_layout_exec_dir,
342         .lfsck_post             = lfsck_layout_slave_post,
343         .lfsck_dump             = lfsck_layout_dump,
344         .lfsck_double_scan      = lfsck_layout_slave_double_scan,
345 };
346
347 int lfsck_layout_setup(const struct lu_env *env, struct lfsck_instance *lfsck)
348 {
349         struct lfsck_component  *com;
350         struct lfsck_layout     *lo;
351         struct dt_object        *root = NULL;
352         struct dt_object        *obj;
353         int                      rc;
354         ENTRY;
355
356         OBD_ALLOC_PTR(com);
357         if (com == NULL)
358                 RETURN(-ENOMEM);
359
360         INIT_LIST_HEAD(&com->lc_link);
361         INIT_LIST_HEAD(&com->lc_link_dir);
362         init_rwsem(&com->lc_sem);
363         atomic_set(&com->lc_ref, 1);
364         com->lc_lfsck = lfsck;
365         com->lc_type = LT_LAYOUT;
366         if (lfsck->li_master)
367                 com->lc_ops = &lfsck_layout_master_ops;
368         else
369                 com->lc_ops = &lfsck_layout_slave_ops;
370         com->lc_file_size = sizeof(*lo);
371         OBD_ALLOC(com->lc_file_ram, com->lc_file_size);
372         if (com->lc_file_ram == NULL)
373                 GOTO(out, rc = -ENOMEM);
374
375         OBD_ALLOC(com->lc_file_disk, com->lc_file_size);
376         if (com->lc_file_disk == NULL)
377                 GOTO(out, rc = -ENOMEM);
378
379         root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
380         if (IS_ERR(root))
381                 GOTO(out, rc = PTR_ERR(root));
382
383         if (unlikely(!dt_try_as_dir(env, root)))
384                 GOTO(out, rc = -ENOTDIR);
385
386         obj = local_file_find_or_create(env, lfsck->li_los, root,
387                                         lfsck_layout_name,
388                                         S_IFREG | S_IRUGO | S_IWUSR);
389         if (IS_ERR(obj))
390                 GOTO(out, rc = PTR_ERR(obj));
391
392         com->lc_obj = obj;
393         rc = lfsck_layout_load(env, com);
394         if (rc > 0)
395                 rc = lfsck_layout_reset(env, com, true);
396         else if (rc == -ENOENT)
397                 rc = lfsck_layout_init(env, com);
398
399         if (rc != 0)
400                 GOTO(out, rc);
401
402         lo = com->lc_file_ram;
403         switch (lo->ll_status) {
404         case LS_INIT:
405         case LS_COMPLETED:
406         case LS_FAILED:
407         case LS_STOPPED:
408         case LS_PARTIAL:
409                 spin_lock(&lfsck->li_lock);
410                 list_add_tail(&com->lc_link, &lfsck->li_list_idle);
411                 spin_unlock(&lfsck->li_lock);
412                 break;
413         default:
414                 CERROR("%s: unknown lfsck_layout status: rc = %u\n",
415                        lfsck_lfsck2name(lfsck), lo->ll_status);
416                 /* fall through */
417         case LS_SCANNING_PHASE1:
418         case LS_SCANNING_PHASE2:
419                 /* No need to store the status to disk right now.
420                  * If the system crashed before the status stored,
421                  * it will be loaded back when next time. */
422                 lo->ll_status = LS_CRASHED;
423                 lo->ll_flags |= LF_INCOMPLETE;
424                 /* fall through */
425         case LS_PAUSED:
426         case LS_CRASHED:
427                 spin_lock(&lfsck->li_lock);
428                 list_add_tail(&com->lc_link, &lfsck->li_list_scan);
429                 spin_unlock(&lfsck->li_lock);
430                 break;
431         }
432
433         GOTO(out, rc = 0);
434
435 out:
436         if (root != NULL && !IS_ERR(root))
437                 lu_object_put(env, &root->do_lu);
438
439         if (rc != 0)
440                 lfsck_component_cleanup(env, com);
441
442         return rc;
443 }