Line data Source code
1 : #include "clusterautoconfig.h"
2 :
3 : #include <stdio.h>
4 : #include <stdint.h>
5 : #include <inttypes.h>
6 : #include <stdlib.h>
7 : #include <sys/types.h>
8 : #include <sys/stat.h>
9 : #include <fcntl.h>
10 : #include <string.h>
11 : #include <unistd.h>
12 : #include <libintl.h>
13 : #include <errno.h>
14 :
15 : #define _(String) gettext(String)
16 :
17 : #include <logging.h>
18 : #include "libgfs2.h"
19 : #include "fsck.h"
20 : #include "util.h"
21 : #include "fs_recovery.h"
22 : #include "metawalk.h"
23 : #include "inode_hash.h"
24 :
25 : #define CLEAR_POINTER(x) \
26 : if (x) { \
27 : free(x); \
28 : x = NULL; \
29 : }
30 : #define HIGHEST_BLOCK 0xffffffffffffffff
31 :
32 : static int was_mounted_ro = 0;
33 : static uint64_t possible_root = HIGHEST_BLOCK;
34 : static struct lgfs2_meta_dir fix_md;
35 : static uint64_t blks_2free = 0;
36 :
37 : /**
38 : * block_mounters
39 : *
40 : * Change the lock protocol so nobody can mount the fs
41 : *
42 : */
43 28 : static int block_mounters(struct lgfs2_sbd *sdp, int block_em)
44 : {
45 28 : if (block_em) {
46 : /* verify it starts with lock_ */
47 14 : if (!strncmp(sdp->sd_lockproto, "lock_", 5)) {
48 : /* Change lock_ to fsck_ */
49 13 : memcpy(sdp->sd_lockproto, "fsck_", 5);
50 : }
51 : /* FIXME: Need to do other verification in the else
52 : * case */
53 : } else {
54 : /* verify it starts with fsck_ */
55 : /* verify it starts with lock_ */
56 14 : if (!strncmp(sdp->sd_lockproto, "fsck_", 5)) {
57 : /* Change fsck_ to lock_ */
58 13 : memcpy(sdp->sd_lockproto, "lock_", 5);
59 : }
60 : }
61 :
62 28 : if (lgfs2_sb_write(sdp, sdp->device_fd)) {
63 0 : stack;
64 0 : return -1;
65 : }
66 28 : return 0;
67 : }
68 :
69 56 : static void dup_free(struct fsck_cx *cx)
70 : {
71 : struct osi_node *n;
72 : struct duptree *dt;
73 :
74 56 : while ((n = osi_first(&cx->dup_blocks))) {
75 0 : dt = (struct duptree *)n;
76 0 : dup_delete(cx, dt);
77 : }
78 56 : }
79 :
80 56 : static void dirtree_free(struct fsck_cx *cx)
81 : {
82 : struct osi_node *n;
83 : struct dir_info *dt;
84 :
85 280 : while ((n = osi_first(&cx->dirtree))) {
86 224 : dt = (struct dir_info *)n;
87 224 : dirtree_delete(cx, dt);
88 : }
89 56 : }
90 :
91 56 : static void inodetree_free(struct fsck_cx *cx)
92 : {
93 : struct osi_node *n;
94 : struct inode_info *dt;
95 :
96 56 : while ((n = osi_first(&cx->inodetree))) {
97 0 : dt = (struct inode_info *)n;
98 0 : inodetree_delete(cx, dt);
99 : }
100 56 : }
101 :
102 : /*
103 : * empty_super_block - free all structures in the super block
104 : * sdp: the in-core super block
105 : *
106 : * This function frees all allocated structures within the
107 : * super block. It does not free the super block itself.
108 : *
109 : * Returns: Nothing
110 : */
111 56 : static void empty_super_block(struct fsck_cx *cx)
112 : {
113 56 : log_info( _("Freeing buffers.\n"));
114 56 : lgfs2_rgrp_free(cx->sdp, &cx->sdp->rgtree);
115 :
116 56 : inodetree_free(cx);
117 56 : dirtree_free(cx);
118 56 : dup_free(cx);
119 56 : }
120 :
121 :
122 : /**
123 : * set_block_ranges
124 : * @sdp: superblock
125 : *
126 : * Uses info in rgrps and jindex to determine boundaries of the
127 : * file system.
128 : *
129 : * Returns: 0 on success, -1 on failure
130 : */
131 56 : static int set_block_ranges(struct lgfs2_sbd *sdp)
132 : {
133 56 : struct osi_node *n, *next = NULL;
134 : struct lgfs2_rgrp_tree *rgd;
135 56 : uint64_t rmax = 0;
136 56 : uint64_t rmin = 0;
137 : ssize_t count;
138 : char *buf;
139 :
140 56 : log_info( _("Setting block ranges..."));
141 :
142 4415 : for (n = osi_first(&sdp->rgtree); n; n = next) {
143 4359 : next = osi_next(n);
144 4359 : rgd = (struct lgfs2_rgrp_tree *)n;
145 4359 : if (rgd->rt_data0 + rgd->rt_data &&
146 4359 : rgd->rt_data0 + rgd->rt_data - 1 > rmax)
147 4359 : rmax = rgd->rt_data0 + rgd->rt_data - 1;
148 4359 : if (!rmin || rgd->rt_data0 < rmin)
149 56 : rmin = rgd->rt_data0;
150 : }
151 :
152 56 : last_fs_block = rmax;
153 : if (last_fs_block > 0xffffffff && sizeof(unsigned long) <= 4) {
154 : log_crit(_("This file system is too big for this computer to handle.\n"));
155 : log_crit(_("Last fs block = 0x%"PRIx64", but sizeof(unsigned long) is %zu bytes.\n"),
156 : last_fs_block, sizeof(unsigned long));
157 : goto fail;
158 : }
159 :
160 56 : last_data_block = rmax;
161 56 : first_data_block = rmin;
162 :
163 56 : buf = calloc(1, sdp->sd_bsize);
164 56 : if (buf == NULL) {
165 0 : log_crit(_("Failed to determine file system boundaries: %s\n"), strerror(errno));
166 0 : return -1;
167 : }
168 56 : count = pread(sdp->device_fd, buf, sdp->sd_bsize, (last_fs_block * sdp->sd_bsize));
169 56 : free(buf);
170 56 : if (count != sdp->sd_bsize) {
171 0 : log_crit(_("Failed to read highest block number (%"PRIx64"): %s\n"),
172 : last_fs_block, strerror(errno));
173 0 : goto fail;
174 : }
175 :
176 56 : log_info(_("0x%"PRIx64" to 0x%"PRIx64"\n"), first_data_block, last_data_block);
177 56 : return 0;
178 :
179 0 : fail:
180 0 : log_info( _("Error\n"));
181 0 : return -1;
182 : }
183 :
184 : /**
185 : * check_rgrp_integrity - verify a rgrp free block count against the bitmap
186 : */
187 4359 : static void check_rgrp_integrity(struct fsck_cx *cx, struct lgfs2_rgrp_tree *rgd,
188 : int *fixit, int *this_rg_fixed,
189 : int *this_rg_bad, int *this_rg_cleaned)
190 : {
191 : uint32_t rg_free, rg_reclaimed, rg_unlinked, rg_usedmeta, rg_useddi;
192 4359 : int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0;
193 4359 : struct lgfs2_sbd *sdp = cx->sdp;
194 : unsigned int state;
195 : uint64_t diblock;
196 : struct lgfs2_buffer_head *bh;
197 :
198 4359 : rg_free = rg_reclaimed = rg_unlinked = rg_usedmeta = rg_useddi = 0;
199 4359 : total_bytes_to_check = rgd->rt_bitbytes;
200 :
201 4359 : *this_rg_fixed = *this_rg_bad = *this_rg_cleaned = 0;
202 :
203 4359 : diblock = rgd->rt_data0;
204 136822 : for (rgb = 0; rgb < rgd->rt_length; rgb++){
205 : /* Count up the free blocks in the bitmap */
206 132463 : off = (rgb) ? sizeof(struct gfs2_meta_header) :
207 : sizeof(struct gfs2_rgrp);
208 132463 : if (total_bytes_to_check <= sdp->sd_bsize - off)
209 4359 : bytes_to_check = total_bytes_to_check;
210 : else
211 128104 : bytes_to_check = sdp->sd_bsize - off;
212 132463 : total_bytes_to_check -= bytes_to_check;
213 119507774 : for (x = 0; x < bytes_to_check; x++) {
214 : unsigned char *byte;
215 :
216 119375311 : byte = (unsigned char *)&rgd->rt_bits[rgb].bi_data[off + x];
217 119375311 : if (*byte == 0x55) {
218 491106 : diblock += GFS2_NBBY;
219 491106 : continue;
220 : }
221 118884205 : if (*byte == 0x00) {
222 118883894 : diblock += GFS2_NBBY;
223 118883894 : rg_free += GFS2_NBBY;
224 118883894 : continue;
225 : }
226 1555 : for (y = 0; y < GFS2_NBBY; y++) {
227 1244 : state = (*byte >>
228 1244 : (GFS2_BIT_SIZE * y)) & GFS2_BIT_MASK;
229 1244 : if (state == GFS2_BLKST_USED) {
230 461 : diblock++;
231 461 : continue;
232 : }
233 783 : if (state == GFS2_BLKST_DINODE) {
234 700 : diblock++;
235 700 : continue;
236 : }
237 83 : if (state == GFS2_BLKST_FREE) {
238 83 : diblock++;
239 83 : rg_free++;
240 83 : continue;
241 : }
242 : /* GFS2_BLKST_UNLINKED */
243 0 : log_info(_("Unlinked dinode 0x%"PRIx64" found.\n"), diblock);
244 0 : if (!asked) {
245 : char msg[256];
246 :
247 0 : asked = 1;
248 0 : sprintf(msg,
249 0 : _("Okay to reclaim free "
250 : "metadata in resource group "
251 : "%"PRIu64" (0x%"PRIx64")? (y/n)"),
252 : rgd->rt_addr, rgd->rt_addr);
253 0 : if (query(cx, "%s", msg))
254 0 : *fixit = 1;
255 : }
256 0 : if (!(*fixit)) {
257 0 : rg_unlinked++;
258 0 : diblock++;
259 0 : continue;
260 : }
261 0 : *byte &= ~(GFS2_BIT_MASK <<
262 0 : (GFS2_BIT_SIZE * y));
263 0 : rgd->rt_bits[rgb].bi_modified = 1;
264 0 : rg_reclaimed++;
265 0 : rg_free++;
266 0 : rgd->rt_free++;
267 0 : log_info(_("Free metadata block %"PRIu64" (0x%"PRIx64") reclaimed.\n"),
268 : diblock, diblock);
269 0 : bh = lgfs2_bread(sdp, diblock);
270 0 : if (!lgfs2_check_meta(bh->b_data, GFS2_METATYPE_DI)) {
271 0 : struct lgfs2_inode *ip =
272 0 : fsck_inode_get(sdp, rgd, bh);
273 0 : if (ip->i_blocks > 1) {
274 0 : blks_2free += ip->i_blocks - 1;
275 0 : log_info(_("%"PRIu64" blocks "
276 : "(total) may need "
277 : "to be freed in "
278 : "pass 5.\n"),
279 : blks_2free);
280 : }
281 0 : fsck_inode_put(&ip);
282 : }
283 0 : lgfs2_brelse(bh);
284 0 : diblock++;
285 : }
286 : }
287 : }
288 : /* The unlinked blocks we reclaim shouldn't be considered errors,
289 : since we're just reclaiming them as a courtesy. If we already
290 : got permission to reclaim them, we adjust the rgrp counts
291 : accordingly. That way, only "real" rgrp count inconsistencies
292 : will be reported. */
293 4359 : if (rg_reclaimed && *fixit) {
294 0 : lgfs2_rgrp_out(rgd, rgd->rt_bits[0].bi_data);
295 0 : rgd->rt_bits[0].bi_modified = 1;
296 0 : *this_rg_cleaned = 1;
297 0 : log_info(_("The rgrp at %"PRIu64" (0x%"PRIx64") was cleaned of %d "
298 : "free metadata blocks.\n"),
299 : rgd->rt_addr, rgd->rt_addr, rg_reclaimed);
300 : }
301 4359 : if (rgd->rt_free != rg_free) {
302 4 : *this_rg_bad = 1;
303 4 : *this_rg_cleaned = 0;
304 4 : log_err( _("Error: resource group %"PRIu64" (0x%"PRIx64"): "
305 : "free space (%d) does not match bitmap (%d)\n"),
306 : rgd->rt_addr, rgd->rt_addr, rgd->rt_free, rg_free);
307 4 : if (query(cx, _("Fix the rgrp free blocks count? (y/n)"))) {
308 4 : rgd->rt_free = rg_free;
309 4 : lgfs2_rgrp_out(rgd, rgd->rt_bits[0].bi_data);
310 4 : rgd->rt_bits[0].bi_modified = 1;
311 4 : *this_rg_fixed = 1;
312 4 : log_err( _("The rgrp was fixed.\n"));
313 : } else
314 0 : log_err( _("The rgrp was not fixed.\n"));
315 : }
316 4359 : }
317 :
318 : /**
319 : * check_rgrps_integrity - verify rgrp consistency
320 : * Note: We consider an rgrp "cleaned" if the unlinked meta blocks are
321 : * cleaned, so not quite "bad" and not quite "good" but rewritten anyway.
322 : *
323 : * Returns: 0 on success, 1 if errors were detected
324 : */
325 56 : static void check_rgrps_integrity(struct fsck_cx *cx)
326 : {
327 56 : struct osi_node *n, *next = NULL;
328 56 : int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0, rgs_cleaned = 0;
329 56 : int was_bad = 0, was_fixed = 0, was_cleaned = 0;
330 : struct lgfs2_rgrp_tree *rgd;
331 56 : int reclaim_unlinked = 0;
332 :
333 56 : log_info( _("Checking the integrity of all resource groups.\n"));
334 4415 : for (n = osi_first(&cx->sdp->rgtree); n; n = next) {
335 4359 : next = osi_next(n);
336 4359 : rgd = (struct lgfs2_rgrp_tree *)n;
337 4359 : if (fsck_abort)
338 0 : return;
339 4359 : check_rgrp_integrity(cx, rgd, &reclaim_unlinked,
340 : &was_fixed, &was_bad, &was_cleaned);
341 4359 : if (was_fixed)
342 4 : rgs_fixed++;
343 4359 : if (was_cleaned)
344 0 : rgs_cleaned++;
345 4359 : else if (was_bad)
346 4 : rgs_bad++;
347 : else
348 4355 : rgs_good++;
349 : }
350 56 : if (rgs_bad || rgs_cleaned) {
351 4 : log_err( _("RGs: Consistent: %d Cleaned: %d Inconsistent: "
352 : "%d Fixed: %d Total: %d\n"),
353 : rgs_good, rgs_cleaned, rgs_bad, rgs_fixed,
354 : rgs_good + rgs_bad + rgs_cleaned);
355 4 : if (rgs_cleaned && blks_2free)
356 0 : log_err(_("%"PRIu64" blocks may need to be freed in pass 5 "
357 : "due to the cleaned resource groups.\n"),
358 : blks_2free);
359 : }
360 : }
361 :
362 0 : static int rebuild_sysdir(struct fsck_cx *cx)
363 : {
364 0 : struct lgfs2_sbd *sdp = cx->sdp;
365 : struct lgfs2_inum inum;
366 0 : struct lgfs2_buffer_head *bh = NULL;
367 0 : int err = 0;
368 :
369 0 : log_err(_("The system directory seems to be destroyed.\n"));
370 0 : if (!query(cx, _("Okay to rebuild it? (y/n)"))) {
371 0 : log_err(_("System directory not rebuilt; aborting.\n"));
372 0 : return -1;
373 : }
374 0 : log_err(_("Trying to rebuild the master directory.\n"));
375 0 : inum.in_formal_ino = sdp->md.next_inum++;
376 0 : inum.in_addr = sdp->sd_meta_dir.in_addr;
377 0 : err = lgfs2_init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, GFS2_DIF_SYSTEM, &inum);
378 0 : if (err != 0)
379 0 : return -1;
380 0 : sdp->master_dir = lgfs2_inode_get(sdp, bh);
381 0 : if (sdp->master_dir == NULL) {
382 0 : log_crit(_("Error reading master: %s\n"), strerror(errno));
383 0 : return -1;
384 : }
385 0 : sdp->master_dir->bh_owned = 1;
386 :
387 0 : if (fix_md.jiinode) {
388 0 : inum.in_formal_ino = sdp->md.next_inum++;
389 0 : inum.in_addr = fix_md.jiinode->i_num.in_addr;
390 0 : err = lgfs2_dir_add(sdp->master_dir, "jindex", 6, &inum,
391 : IF2DT(S_IFDIR | 0700));
392 0 : if (err) {
393 0 : log_crit(_("Error %d adding jindex directory\n"), errno);
394 0 : exit(FSCK_ERROR);
395 : }
396 0 : sdp->master_dir->i_nlink++;
397 : } else {
398 0 : err = build_jindex(cx);
399 0 : if (err) {
400 0 : log_crit(_("Error %d building jindex\n"), err);
401 0 : exit(FSCK_ERROR);
402 : }
403 : }
404 :
405 0 : if (fix_md.pinode) {
406 0 : inum.in_formal_ino = sdp->md.next_inum++;
407 0 : inum.in_addr = fix_md.pinode->i_num.in_addr;
408 : /* coverity[deref_arg:SUPPRESS] */
409 0 : err = lgfs2_dir_add(sdp->master_dir, "per_node", 8, &inum,
410 : IF2DT(S_IFDIR | 0700));
411 0 : if (err) {
412 0 : log_crit(_("Error %d adding per_node directory\n"),
413 : errno);
414 0 : exit(FSCK_ERROR);
415 : }
416 0 : sdp->master_dir->i_nlink++;
417 : } else {
418 : /* coverity[double_free:SUPPRESS] */
419 0 : err = build_per_node(cx);
420 0 : if (err) {
421 0 : log_crit(_("Error %d building per_node directory\n"),
422 : err);
423 0 : exit(FSCK_ERROR);
424 : }
425 : }
426 :
427 0 : if (fix_md.inum) {
428 0 : inum.in_formal_ino = sdp->md.next_inum++;
429 0 : inum.in_addr = fix_md.inum->i_num.in_addr;
430 : /* coverity[deref_arg:SUPPRESS] */
431 0 : err = lgfs2_dir_add(sdp->master_dir, "inum", 4, &inum,
432 : IF2DT(S_IFREG | 0600));
433 0 : if (err) {
434 0 : log_crit(_("Error %d adding inum inode\n"), errno);
435 0 : exit(FSCK_ERROR);
436 : }
437 : } else {
438 0 : sdp->md.inum = lgfs2_build_inum(sdp);
439 0 : if (sdp->md.inum == NULL) {
440 0 : log_crit(_("Error building inum inode: %s\n"), strerror(errno));
441 0 : exit(FSCK_ERROR);
442 : }
443 : /* Write the inode but don't free it, to avoid doing an extra lookup */
444 : /* coverity[deref_after_free:SUPPRESS] */
445 0 : lgfs2_dinode_out(sdp->md.inum, sdp->md.inum->i_bh->b_data);
446 0 : lgfs2_bwrite(sdp->md.inum->i_bh);
447 : }
448 :
449 0 : if (fix_md.statfs) {
450 0 : inum.in_formal_ino = sdp->md.next_inum++;
451 0 : inum.in_addr = fix_md.statfs->i_num.in_addr;
452 : /* coverity[deref_arg:SUPPRESS] */
453 0 : err = lgfs2_dir_add(sdp->master_dir, "statfs", 6, &inum,
454 : IF2DT(S_IFREG | 0600));
455 0 : if (err) {
456 0 : log_crit(_("Error %d adding statfs inode\n"), errno);
457 0 : exit(FSCK_ERROR);
458 : }
459 : } else {
460 0 : sdp->md.statfs = lgfs2_build_statfs(sdp);
461 0 : if (sdp->md.statfs == NULL) {
462 0 : log_crit(_("Error %d building statfs inode\n"), err);
463 0 : exit(FSCK_ERROR);
464 : }
465 : /* Write the inode but don't free it, to avoid doing an extra lookup */
466 : /* coverity[deref_after_free:SUPPRESS] */
467 0 : lgfs2_dinode_out(sdp->md.statfs, sdp->md.statfs->i_bh->b_data);
468 0 : lgfs2_bwrite(sdp->md.statfs->i_bh);
469 : }
470 :
471 0 : if (fix_md.riinode) {
472 0 : inum.in_formal_ino = sdp->md.next_inum++;
473 0 : inum.in_addr = fix_md.riinode->i_num.in_addr;
474 : /* coverity[deref_arg:SUPPRESS] */
475 0 : err = lgfs2_dir_add(sdp->master_dir, "rindex", 6, &inum,
476 : IF2DT(S_IFREG | 0600));
477 0 : if (err) {
478 0 : log_crit(_("Error %d adding rindex inode\n"), errno);
479 0 : exit(FSCK_ERROR);
480 : }
481 : } else {
482 : /* coverity[double_free:SUPPRESS] */
483 0 : struct lgfs2_inode *rip = lgfs2_build_rindex(sdp);
484 0 : if (rip == NULL) {
485 0 : log_crit(_("Error building rindex inode: %s\n"), strerror(errno));
486 0 : exit(FSCK_ERROR);
487 : }
488 0 : lgfs2_inode_put(&rip);
489 : }
490 :
491 0 : if (fix_md.qinode) {
492 0 : inum.in_formal_ino = sdp->md.next_inum++;
493 0 : inum.in_addr = fix_md.qinode->i_num.in_addr;
494 0 : err = lgfs2_dir_add(sdp->master_dir, "quota", 5, &inum,
495 : IF2DT(S_IFREG | 0600));
496 0 : if (err) {
497 0 : log_crit(_("Error %d adding quota inode\n"), errno);
498 0 : exit(FSCK_ERROR);
499 : }
500 : } else {
501 0 : struct lgfs2_inode *qip = lgfs2_build_quota(sdp);
502 0 : if (qip == NULL) {
503 0 : log_crit(_("Error building quota inode: %s\n"), strerror(errno));
504 0 : exit(FSCK_ERROR);
505 : }
506 0 : lgfs2_inode_put(&qip);
507 : }
508 :
509 0 : log_err(_("Master directory rebuilt.\n"));
510 0 : lgfs2_inode_put(&sdp->md.inum);
511 0 : lgfs2_inode_put(&sdp->md.statfs);
512 0 : lgfs2_inode_put(&sdp->master_dir);
513 0 : return 0;
514 : }
515 :
516 : /**
517 : * lookup_per_node - Make sure the per_node directory is read in
518 : *
519 : * This function is used to read in the per_node directory. It is called
520 : * twice. The first call tries to read in the dinode early on. That ensures
521 : * that if any journals are missing, we can figure out the number of journals
522 : * from per_node. However, we unfortunately can't rebuild per_node at that
523 : * point in time because our resource groups aren't read in yet.
524 : * The second time it's called is much later when we can rebuild it.
525 : *
526 : * allow_rebuild: 0 if rebuilds are not allowed
527 : * 1 if rebuilds are allowed
528 : */
529 112 : static void lookup_per_node(struct fsck_cx *cx, int allow_rebuild)
530 : {
531 112 : struct lgfs2_sbd *sdp = cx->sdp;
532 :
533 112 : if (sdp->md.pinode)
534 56 : return;
535 :
536 56 : sdp->md.pinode = lgfs2_lookupi(sdp->master_dir, "per_node", 8);
537 56 : if (sdp->md.pinode)
538 56 : return;
539 0 : if (!allow_rebuild) {
540 0 : log_err( _("The gfs2 system per_node directory "
541 : "inode is missing, so we might not be \nable to "
542 : "rebuild missing journals this run.\n"));
543 0 : return;
544 : }
545 :
546 0 : if (query(cx, _("The gfs2 system per_node directory "
547 : "inode is missing. Okay to rebuild it? (y/n) "))) {
548 : int err;
549 :
550 : /* coverity[freed_arg:SUPPRESS] False positive */
551 0 : err = build_per_node(cx);
552 0 : if (err) {
553 0 : log_crit(_("Error %d rebuilding per_node directory\n"),
554 : err);
555 0 : exit(FSCK_ERROR);
556 : }
557 : }
558 : /* coverity[identity_transfer:SUPPRESS] False positive */
559 0 : sdp->md.pinode = lgfs2_lookupi(sdp->master_dir, "per_node", 8);
560 0 : if (!sdp->md.pinode) {
561 0 : log_err( _("Unable to rebuild per_node; aborting.\n"));
562 0 : exit(FSCK_ERROR);
563 : }
564 : }
565 :
566 : #define RA_WINDOW 32
567 :
568 1003 : static unsigned rgrp_reada(struct lgfs2_sbd *sdp, unsigned cur_window,
569 : struct osi_node *n)
570 : {
571 : struct lgfs2_rgrp_tree *rgd;
572 : unsigned i;
573 : off_t start, len;
574 :
575 14015 : for (i = 0; i < RA_WINDOW; i++, n = osi_next(n)) {
576 13841 : if (n == NULL)
577 829 : return i;
578 13012 : if (i < cur_window)
579 8567 : continue;
580 4445 : rgd = (struct lgfs2_rgrp_tree *)n;
581 4445 : start = rgd->rt_addr * sdp->sd_bsize;
582 4445 : len = rgd->rt_length * sdp->sd_bsize;
583 4445 : (void)posix_fadvise(sdp->device_fd, start, len, POSIX_FADV_WILLNEED);
584 : }
585 :
586 174 : return i;
587 : }
588 :
589 : /**
590 : * read_rgrps - attach rgrps to the super block
591 : * @sdp: incore superblock data
592 : * @expected: number of resource groups expected (rindex entries)
593 : *
594 : * Given the rgrp index inode, link in all rgrps into the super block
595 : * and be sure that they can be read.
596 : *
597 : * Returns: 0 on success, -1 on failure.
598 : */
599 60 : static int read_rgrps(struct lgfs2_sbd *sdp, uint64_t expected)
600 : {
601 : struct lgfs2_rgrp_tree *rgd;
602 60 : uint64_t count = 0;
603 60 : uint64_t errblock = 0;
604 60 : uint64_t rmax = 0;
605 60 : struct osi_node *n, *next = NULL;
606 60 : unsigned ra_window = 0;
607 :
608 : /* Turn off generic readhead */
609 60 : (void)posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_RANDOM);
610 :
611 4421 : for (n = osi_first(&sdp->rgtree); n; n = next) {
612 4365 : next = osi_next(n);
613 4365 : rgd = (struct lgfs2_rgrp_tree *)n;
614 : /* Readahead resource group headers */
615 4365 : if (ra_window < RA_WINDOW/2)
616 1003 : ra_window = rgrp_reada(sdp, ra_window, n);
617 : /* Read resource group header */
618 4365 : errblock = lgfs2_rgrp_read(sdp, rgd);
619 4365 : if (errblock)
620 4 : return errblock;
621 4361 : ra_window--;
622 4361 : count++;
623 4361 : if (rgd->rt_data0 + rgd->rt_data - 1 > rmax)
624 4361 : rmax = rgd->rt_data0 + rgd->rt_data - 1;
625 : }
626 :
627 56 : sdp->fssize = rmax;
628 56 : if (count != expected)
629 0 : goto fail;
630 :
631 56 : (void)posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
632 56 : return 0;
633 :
634 0 : fail:
635 0 : (void)posix_fadvise(sdp->device_fd, 0, 0, POSIX_FADV_NORMAL);
636 0 : lgfs2_rgrp_free(sdp, &sdp->rgtree);
637 0 : return -1;
638 : }
639 :
640 68 : static int fetch_rgrps_level(struct fsck_cx *cx, enum rgindex_trust_level lvl, uint64_t *count, int *ok)
641 : {
642 68 : int ret = 1;
643 :
644 68 : const char *level_desc[] = {
645 68 : _("Checking if all rgrp and rindex values are good"),
646 68 : _("Checking if rindex values may be easily repaired"),
647 68 : _("Calculating where the rgrps should be if evenly spaced"),
648 68 : _("Trying to rebuild rindex assuming evenly spaced rgrps"),
649 68 : _("Trying to rebuild rindex assuming unevenly spaced rgrps"),
650 : };
651 68 : const char *fail_desc[] = {
652 68 : _("Some damage was found; we need to take remedial measures"),
653 68 : _("rindex is unevenly spaced: either gfs1-style or corrupt"),
654 68 : _("rindex calculations don't match: uneven rgrp boundaries"),
655 68 : _("Too many rgrp misses: rgrps must be unevenly spaced"),
656 68 : _("Too much damage found: we cannot rebuild this rindex"),
657 : };
658 :
659 68 : log_notice(_("Level %d resource group check: %s.\n"), lvl + 1, level_desc[lvl]);
660 :
661 68 : if (rindex_repair(cx, lvl, ok) != 0)
662 6 : goto fail;
663 :
664 62 : if (lgfs2_rindex_read(cx->sdp, count, ok) != 0 || !*ok)
665 2 : goto fail;
666 :
667 60 : ret = read_rgrps(cx->sdp, *count);
668 60 : if (ret != 0)
669 4 : goto fail;
670 :
671 56 : log_notice(_("(level %d passed)\n"), lvl + 1);
672 56 : return 0;
673 12 : fail:
674 12 : if (ret == -1)
675 0 : log_err(_("(level %d failed: %s)\n"), lvl + 1, fail_desc[lvl]);
676 : else
677 12 : log_err(_("(level %d failed at block %d (0x%x): %s)\n"), lvl + 1,
678 : ret, ret, fail_desc[lvl]);
679 12 : return ret;
680 : }
681 :
682 : /**
683 : * fetch_rgrps - fetch the resource groups from disk, and check their integrity
684 : */
685 56 : static int fetch_rgrps(struct fsck_cx *cx)
686 : {
687 : enum rgindex_trust_level trust_lvl;
688 : uint64_t rgcount;
689 56 : int ok = 1;
690 :
691 56 : log_notice(_("Validating resource group index.\n"));
692 68 : for (trust_lvl = BLIND_FAITH; trust_lvl <= INDIGNATION; trust_lvl++) {
693 68 : int ret = 0;
694 :
695 68 : ret = fetch_rgrps_level(cx, trust_lvl, &rgcount, &ok);
696 68 : if (ret == 0)
697 56 : break;
698 12 : if (fsck_abort)
699 0 : break;
700 : }
701 56 : if (trust_lvl > INDIGNATION) {
702 0 : log_err( _("Resource group recovery impossible; I can't fix "
703 : "this file system.\n"));
704 0 : return -1;
705 : }
706 56 : log_info( _("%"PRIu64" resource groups found.\n"), rgcount);
707 :
708 56 : check_rgrps_integrity(cx);
709 56 : return 0;
710 : }
711 :
712 : /**
713 : * init_system_inodes
714 : *
715 : * Returns: 0 on success, -1 on failure
716 : */
717 56 : static int init_system_inodes(struct fsck_cx *cx)
718 : {
719 56 : struct lgfs2_sbd *sdp = cx->sdp;
720 56 : __be64 inumbuf = 0;
721 : char *buf;
722 : int err;
723 :
724 56 : log_info( _("Initializing special inodes...\n"));
725 :
726 : /* Get root dinode */
727 56 : sdp->md.rooti = lgfs2_inode_read(sdp, sdp->sd_root_dir.in_addr);
728 56 : if (sdp->md.rooti == NULL)
729 0 : return -1;
730 :
731 : /* Look for "inum" entry in master dinode */
732 56 : sdp->md.inum = lgfs2_lookupi(sdp->master_dir, "inum", 4);
733 56 : if (!sdp->md.inum) {
734 0 : if (!query(cx, _("The gfs2 system inum inode is missing. "
735 : "Okay to rebuild it? (y/n) "))) {
736 0 : log_err( _("fsck.gfs2 cannot continue without "
737 : "a valid inum file; aborting.\n"));
738 0 : goto fail;
739 : }
740 0 : sdp->md.inum = lgfs2_build_inum(sdp);
741 0 : if (sdp->md.inum == NULL) {
742 0 : log_crit(_("Error rebuilding inum inode: %s\n"), strerror(errno));
743 0 : exit(FSCK_ERROR);
744 : }
745 0 : lgfs2_dinode_out(sdp->md.inum, sdp->md.inum->i_bh->b_data);
746 0 : if (lgfs2_bwrite(sdp->md.inum->i_bh) != 0) {
747 0 : log_crit(_("System inum inode was not rebuilt. Aborting.\n"));
748 0 : goto fail;
749 : }
750 : }
751 : /* Read inum entry into buffer */
752 56 : err = lgfs2_readi(sdp->md.inum, &inumbuf, 0,
753 56 : sdp->md.inum->i_size);
754 56 : if (err != sdp->md.inum->i_size) {
755 0 : log_crit(_("Error %d reading system inum inode. "
756 : "Aborting.\n"), err);
757 0 : goto fail;
758 : }
759 : /* call gfs2_inum_range_in() to retrieve range */
760 56 : sdp->md.next_inum = be64_to_cpu(inumbuf);
761 :
762 56 : sdp->md.statfs = lgfs2_lookupi(sdp->master_dir, "statfs", 6);
763 56 : if (!sdp->md.statfs) {
764 0 : if (!query(cx, _("The gfs2 system statfs inode is missing. "
765 : "Okay to rebuild it? (y/n) "))) {
766 0 : log_err( _("fsck.gfs2 cannot continue without a valid "
767 : "statfs file; aborting.\n"));
768 0 : goto fail;
769 : }
770 0 : sdp->md.statfs = lgfs2_build_statfs(sdp);
771 0 : if (sdp->md.statfs == NULL) {
772 0 : log_crit(_("Error %d rebuilding statfs inode\n"), err);
773 0 : exit(FSCK_ERROR);
774 : }
775 0 : lgfs2_dinode_out(sdp->md.statfs, sdp->md.statfs->i_bh->b_data);
776 0 : if (lgfs2_bwrite(sdp->md.statfs->i_bh) != 0) {
777 0 : log_err( _("Rebuild of statfs system file failed."));
778 0 : log_err( _("fsck.gfs2 cannot continue without "
779 : "a valid statfs file; aborting.\n"));
780 0 : goto fail;
781 : }
782 0 : lgfs2_init_statfs(sdp, NULL);
783 : }
784 56 : if (sdp->md.statfs->i_size) {
785 56 : buf = malloc(sdp->md.statfs->i_size);
786 56 : if (buf) {
787 56 : err = lgfs2_readi(sdp->md.statfs, buf, 0,
788 56 : sdp->md.statfs->i_size);
789 56 : if (err != sdp->md.statfs->i_size) {
790 0 : log_crit(_("Error %d reading statfs file. "
791 : "Aborting.\n"), err);
792 0 : free(buf);
793 0 : goto fail;
794 : }
795 56 : free(buf);
796 : }
797 : }
798 :
799 56 : sdp->md.qinode = lgfs2_lookupi(sdp->master_dir, "quota", 5);
800 56 : if (!sdp->md.qinode) {
801 0 : if (!query(cx, _("The gfs2 system quota inode is missing. "
802 : "Okay to rebuild it? (y/n) "))) {
803 0 : log_crit(_("System quota inode was not "
804 : "rebuilt. Aborting.\n"));
805 0 : goto fail;
806 : }
807 0 : sdp->md.qinode = lgfs2_build_quota(sdp);
808 0 : if (sdp->md.qinode == NULL) {
809 0 : log_crit(_("Error rebuilding quota inode: %s\n"), strerror(errno));
810 0 : exit(FSCK_ERROR);
811 : }
812 0 : lgfs2_dinode_out(sdp->md.qinode, sdp->md.qinode->i_bh->b_data);
813 0 : if (lgfs2_bwrite(sdp->md.qinode->i_bh) != 0) {
814 0 : log_crit(_("Unable to rebuild system quota file "
815 : "inode. Aborting.\n"));
816 0 : goto fail;
817 : }
818 : }
819 :
820 : /* Try to lookup the per_node inode. If it was missing, it is now
821 : safe to rebuild it. */
822 56 : lookup_per_node(cx, 1);
823 :
824 : /*******************************************************************
825 : ******* Now, set boundary fields in the super block *************
826 : *******************************************************************/
827 56 : if (set_block_ranges(sdp)){
828 0 : log_err( _("Unable to determine the boundaries of the"
829 : " file system.\n"));
830 0 : goto fail;
831 : }
832 :
833 56 : return 0;
834 0 : fail:
835 0 : empty_super_block(cx);
836 :
837 0 : return -1;
838 : }
839 :
840 : /**
841 : * is_journal_copy - Is this a "real" dinode or a copy inside a journal?
842 : * A real dinode will be located at the block number in its no_addr.
843 : * A journal-copy will be at a different block (inside the journal).
844 : */
845 30 : static int is_journal_copy(struct lgfs2_inode *ip)
846 : {
847 30 : if (ip->i_num.in_addr == ip->i_bh->b_blocknr)
848 30 : return 0;
849 0 : return 1; /* journal copy */
850 : }
851 :
852 : /**
853 : * peruse_system_dinode - process a system dinode
854 : *
855 : * This function looks at a system dinode and tries to figure out which
856 : * dinode it is: statfs, inum, per_node, master, etc. Some of them we
857 : * can deduce from the contents. For example, di_size will be a multiple
858 : * of 96 for the rindex. di_size will be 8 for inum, 24 for statfs, etc.
859 : * the per_node directory will have a ".." entry that will lead us to
860 : * the master dinode if it's been destroyed.
861 : */
862 66 : static void peruse_system_dinode(struct fsck_cx *cx, struct lgfs2_inode *ip)
863 : {
864 66 : struct lgfs2_sbd *sdp = cx->sdp;
865 : struct lgfs2_inode *child_ip;
866 : struct lgfs2_inum inum;
867 : int error;
868 :
869 66 : if (ip->i_num.in_formal_ino == 2) {
870 6 : if (sdp->sd_meta_dir.in_addr)
871 12 : return;
872 1 : log_warn(_("Found system master directory at: 0x%"PRIx64".\n"),
873 : ip->i_num.in_addr);
874 1 : sdp->sd_meta_dir.in_addr = ip->i_num.in_addr;
875 1 : return;
876 : }
877 60 : if (ip->i_num.in_formal_ino == 3) {
878 6 : if (fix_md.jiinode || is_journal_copy(ip))
879 0 : goto out_discard_ip;
880 6 : log_warn(_("Found system jindex file at: 0x%"PRIx64"\n"), ip->i_num.in_addr);
881 6 : fix_md.jiinode = ip;
882 54 : } else if (is_dir(ip)) {
883 : /* Check for a jindex dir entry. Only one system dir has a
884 : jindex: master */
885 : /* coverity[identity_transfer:SUPPRESS] */
886 6 : child_ip = lgfs2_lookupi(ip, "jindex", 6);
887 6 : if (child_ip) {
888 0 : if (fix_md.jiinode || is_journal_copy(ip)) {
889 0 : lgfs2_inode_put(&child_ip);
890 0 : goto out_discard_ip;
891 : }
892 0 : fix_md.jiinode = child_ip;
893 0 : sdp->sd_meta_dir.in_addr = ip->i_num.in_addr;
894 0 : log_warn(_("Found system master directory at: 0x%"PRIx64"\n"),
895 : ip->i_num.in_addr);
896 0 : return;
897 : }
898 :
899 : /* Check for a statfs_change0 dir entry. Only one system dir
900 : has a statfs_change: per_node, and its .. will be master. */
901 : /* coverity[identity_transfer:SUPPRESS] */
902 6 : child_ip = lgfs2_lookupi(ip, "statfs_change0", 14);
903 6 : if (child_ip) {
904 6 : lgfs2_inode_put(&child_ip);
905 6 : if (fix_md.pinode || is_journal_copy(ip))
906 0 : goto out_discard_ip;
907 6 : log_warn(_("Found system per_node directory at: 0x%"PRIx64"\n"),
908 : ip->i_num.in_addr);
909 6 : fix_md.pinode = ip;
910 6 : error = lgfs2_dir_search(ip, "..", 2, NULL, &inum);
911 6 : if (!error && inum.in_addr) {
912 6 : sdp->sd_meta_dir.in_addr = inum.in_addr;
913 6 : log_warn(_("From per_node's '..' master directory backtracked to: "
914 : "0x%"PRIx64"\n"), inum.in_addr);
915 : }
916 6 : return;
917 : }
918 0 : log_debug(_("Unknown system directory at block 0x%"PRIx64"\n"), ip->i_num.in_addr);
919 0 : goto out_discard_ip;
920 48 : } else if (ip->i_size == 8) {
921 6 : if (fix_md.inum || is_journal_copy(ip))
922 0 : goto out_discard_ip;
923 6 : fix_md.inum = ip;
924 6 : log_warn(_("Found system inum file at: 0x%"PRIx64"\n"), ip->i_num.in_addr);
925 42 : } else if (ip->i_size == 24) {
926 12 : if (fix_md.statfs || is_journal_copy(ip))
927 6 : goto out_discard_ip;
928 6 : fix_md.statfs = ip;
929 6 : log_warn(_("Found system statfs file at: 0x%"PRIx64"\n"), ip->i_num.in_addr);
930 30 : } else if ((ip->i_size % 96) == 0) {
931 6 : if (fix_md.riinode || is_journal_copy(ip))
932 0 : goto out_discard_ip;
933 6 : fix_md.riinode = ip;
934 6 : log_warn(_("Found system rindex file at: 0x%"PRIx64"\n"), ip->i_num.in_addr);
935 24 : } else if (!fix_md.qinode && ip->i_size >= 176 &&
936 18 : ip->i_num.in_formal_ino >= 12 &&
937 0 : ip->i_num.in_formal_ino <= 100) {
938 0 : if (is_journal_copy(ip))
939 0 : goto out_discard_ip;
940 0 : fix_md.qinode = ip;
941 0 : log_warn(_("Found system quota file at: 0x%"PRIx64"\n"), ip->i_num.in_addr);
942 : } else {
943 24 : out_discard_ip:
944 30 : lgfs2_inode_put(&ip);
945 : }
946 : }
947 :
948 : /**
949 : * peruse_user_dinode - process a user dinode trying to find the root directory
950 : *
951 : */
952 6 : static void peruse_user_dinode(struct fsck_cx *cx, struct lgfs2_inode *ip)
953 : {
954 6 : struct lgfs2_sbd *sdp = cx->sdp;
955 : struct lgfs2_inode *parent_ip;
956 : struct lgfs2_inum inum;
957 : int error;
958 :
959 6 : if (sdp->sd_root_dir.in_addr) /* if we know the root dinode */
960 6 : return; /* we don't need to find the root */
961 1 : if (!is_dir(ip)) /* if this isn't a directory */
962 0 : return; /* it can't lead us to the root anyway */
963 :
964 1 : if (ip->i_num.in_formal_ino == 1) {
965 : struct lgfs2_buffer_head *root_bh;
966 :
967 0 : if (ip->i_num.in_addr == ip->i_bh->b_blocknr) {
968 0 : log_warn(_("Found the root directory at: 0x%"PRIx64".\n"),
969 : ip->i_num.in_addr);
970 0 : sdp->sd_root_dir.in_addr = ip->i_num.in_addr;
971 0 : return;
972 : }
973 0 : log_warn(_("The root dinode should be at block 0x%"PRIx64" but it "
974 : "seems to be destroyed.\n"),
975 : ip->i_num.in_addr);
976 0 : log_warn(_("Found a copy of the root directory in a journal "
977 : "at block: 0x%"PRIx64".\n"),
978 : ip->i_bh->b_blocknr);
979 0 : if (!query(cx, _("Do you want to replace the root dinode from the copy? (y/n)"))) {
980 0 : log_err(_("Damaged root dinode not fixed.\n"));
981 0 : return;
982 : }
983 0 : root_bh = lgfs2_bread(sdp, ip->i_num.in_addr);
984 0 : memcpy(root_bh->b_data, ip->i_bh->b_data, sdp->sd_bsize);
985 0 : lgfs2_bmodified(root_bh);
986 0 : lgfs2_brelse(root_bh);
987 0 : log_warn(_("Root directory copied from the journal.\n"));
988 0 : return;
989 : }
990 : /* coverity[check_after_deref:SUPPRESS] */
991 1 : while (ip) {
992 : /* coverity[identity_transfer:SUPPRESS] */
993 1 : parent_ip = lgfs2_lookupi(ip, "..", 2);
994 1 : if (parent_ip && parent_ip->i_num.in_addr == ip->i_num.in_addr) {
995 1 : log_warn(_("Found the root directory at: 0x%"PRIx64"\n"),
996 : ip->i_num.in_addr);
997 1 : sdp->sd_root_dir.in_addr = ip->i_num.in_addr;
998 1 : lgfs2_inode_put(&parent_ip);
999 1 : lgfs2_inode_put(&ip);
1000 1 : return;
1001 : }
1002 0 : if (!parent_ip)
1003 0 : break;
1004 0 : lgfs2_inode_put(&ip);
1005 0 : ip = parent_ip;
1006 : }
1007 0 : error = lgfs2_dir_search(ip, "..", 2, NULL, &inum);
1008 0 : if (!error && inum.in_addr && inum.in_addr < possible_root) {
1009 0 : possible_root = inum.in_addr;
1010 0 : log_debug(_("Found a possible root at: 0x%"PRIx64"\n"),
1011 : possible_root);
1012 : }
1013 0 : lgfs2_inode_put(&ip);
1014 : }
1015 :
1016 : /**
1017 : * find_rgs_for_bsize - check a range of blocks for rgrps to determine bsize.
1018 : * Assumes: device is open.
1019 : */
1020 6 : static int find_rgs_for_bsize(struct lgfs2_sbd *sdp, uint64_t startblock,
1021 : uint32_t *known_bsize)
1022 : {
1023 : uint64_t blk, max_rg_size, rb_addr;
1024 : uint32_t bsize, bsize2;
1025 : int found_rg;
1026 :
1027 6 : sdp->sd_bsize = LGFS2_DEFAULT_BSIZE;
1028 6 : max_rg_size = 524288;
1029 : /* Max RG size is 2GB. Max block size is 4K. 2G / 4K blks = 524288,
1030 : So this is traversing 2GB in 4K block increments. */
1031 12 : for (blk = startblock; blk < startblock + max_rg_size; blk++) {
1032 12 : struct lgfs2_buffer_head *bh = lgfs2_bread(sdp, blk);
1033 :
1034 12 : found_rg = 0;
1035 60 : for (bsize = 0; bsize < LGFS2_DEFAULT_BSIZE; bsize += GFS2_BASIC_BLOCK) {
1036 : struct gfs2_meta_header mhp;
1037 :
1038 54 : memcpy(&mhp, bh->b_data + bsize, sizeof(mhp));
1039 54 : if (be32_to_cpu(mhp.mh_magic) != GFS2_MAGIC)
1040 42 : continue;
1041 12 : if (be32_to_cpu(mhp.mh_type) == GFS2_METATYPE_RG) {
1042 6 : found_rg = 1;
1043 6 : break;
1044 : }
1045 : }
1046 12 : lgfs2_bfree(&bh);
1047 12 : if (!found_rg)
1048 6 : continue;
1049 : /* Try all the block sizes in 512 byte multiples */
1050 48 : for (bsize2 = GFS2_BASIC_BLOCK; bsize2 <= LGFS2_DEFAULT_BSIZE;
1051 42 : bsize2 += GFS2_BASIC_BLOCK) {
1052 : struct lgfs2_buffer_head *rb_bh;
1053 : struct gfs2_meta_header *mh;
1054 : int is_rb;
1055 :
1056 48 : rb_addr = (blk * (LGFS2_DEFAULT_BSIZE / bsize2)) +
1057 48 : (bsize / bsize2) + 1;
1058 48 : sdp->sd_bsize = bsize2; /* temporarily */
1059 48 : rb_bh = lgfs2_bread(sdp, rb_addr);
1060 48 : mh = (struct gfs2_meta_header *)rb_bh->b_data;
1061 54 : is_rb = (be32_to_cpu(mh->mh_magic) == GFS2_MAGIC &&
1062 6 : be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RB);
1063 48 : lgfs2_brelse(rb_bh);
1064 48 : if (is_rb) {
1065 6 : log_debug(_("boff:%d bsize2:%d rg:0x%"PRIx64", "
1066 : "rb:0x%"PRIx64"\n"), bsize, bsize2,
1067 : blk, rb_addr);
1068 6 : *known_bsize = bsize2;
1069 6 : break;
1070 : }
1071 : }
1072 6 : if (!(*known_bsize)) {
1073 0 : sdp->sd_bsize = LGFS2_DEFAULT_BSIZE;
1074 0 : continue;
1075 : }
1076 :
1077 6 : sdp->sd_bsize = *known_bsize;
1078 6 : log_warn(_("Block size determined to be: %d\n"), *known_bsize);
1079 6 : return 0;
1080 : }
1081 0 : return 0;
1082 : }
1083 :
1084 : /**
1085 : * peruse_metadata - check a range of blocks for metadata
1086 : * Assumes: device is open.
1087 : */
1088 6 : static int peruse_metadata(struct fsck_cx *cx, uint64_t startblock)
1089 : {
1090 6 : struct lgfs2_sbd *sdp = cx->sdp;
1091 : uint64_t blk, max_rg_size;
1092 : struct lgfs2_buffer_head *bh;
1093 : struct lgfs2_inode *ip;
1094 :
1095 6 : max_rg_size = 2147483648ull / sdp->sd_bsize;
1096 : /* Max RG size is 2GB. 2G / bsize. */
1097 3145734 : for (blk = startblock; blk < startblock + max_rg_size; blk++) {
1098 3145728 : bh = lgfs2_bread(sdp, blk);
1099 3145728 : if (lgfs2_check_meta(bh->b_data, GFS2_METATYPE_DI)) {
1100 3145656 : lgfs2_brelse(bh);
1101 3145656 : continue;
1102 : }
1103 72 : ip = lgfs2_inode_get(sdp, bh);
1104 72 : if (ip == NULL)
1105 0 : return -1;
1106 72 : ip->bh_owned = 1; /* lgfs2_inode_put() will free the bh */
1107 72 : if (ip->i_flags & GFS2_DIF_SYSTEM)
1108 66 : peruse_system_dinode(cx, ip);
1109 : else
1110 6 : peruse_user_dinode(cx, ip);
1111 : }
1112 6 : return 0;
1113 : }
1114 :
1115 : /**
1116 : * sb_repair - repair a damaged superblock
1117 : * Assumes: device is open.
1118 : * The biggest RG size is 2GB
1119 : */
1120 6 : static int sb_repair(struct fsck_cx *cx)
1121 : {
1122 6 : struct lgfs2_sbd *sdp = cx->sdp;
1123 : uint64_t half;
1124 6 : uint32_t known_bsize = 0;
1125 6 : int error = 0;
1126 :
1127 6 : memset(&fix_md, 0, sizeof(fix_md));
1128 : /* Step 1 - First we need to determine the correct block size. */
1129 6 : sdp->sd_bsize = LGFS2_DEFAULT_BSIZE;
1130 6 : log_warn(_("Gathering information to repair the gfs2 superblock. "
1131 : "This may take some time.\n"));
1132 6 : error = find_rgs_for_bsize(sdp, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
1133 : LGFS2_DEFAULT_BSIZE, &known_bsize);
1134 6 : if (error)
1135 0 : return error;
1136 6 : if (!known_bsize) {
1137 0 : log_warn(_("Block size not apparent; checking elsewhere.\n"));
1138 : /* First, figure out the device size. We need that so we can
1139 : find a suitable start point to determine what's what. */
1140 0 : half = sdp->dinfo.size / 2; /* in bytes */
1141 0 : half /= sdp->sd_bsize;
1142 : /* Start looking halfway through the device for gfs2
1143 : structures. If there aren't any at all, forget it. */
1144 0 : error = find_rgs_for_bsize(sdp, half, &known_bsize);
1145 0 : if (error)
1146 0 : return error;
1147 : }
1148 6 : if (!known_bsize) {
1149 0 : log_err(_("Unable to determine the block size; this "
1150 : "does not look like a gfs2 file system.\n"));
1151 0 : return -1;
1152 : }
1153 : /* Step 2 - look for the sytem dinodes */
1154 6 : error = peruse_metadata(cx, (GFS2_SB_ADDR * GFS2_BASIC_BLOCK) /
1155 : LGFS2_DEFAULT_BSIZE);
1156 6 : if (error)
1157 0 : return error;
1158 6 : if (!sdp->sd_meta_dir.in_addr) {
1159 0 : log_err(_("Unable to locate the system master directory.\n"));
1160 0 : return -1;
1161 : }
1162 6 : if (!sdp->sd_root_dir.in_addr) {
1163 0 : log_err(_("Unable to locate the root directory.\n"));
1164 0 : if (possible_root == HIGHEST_BLOCK) {
1165 : /* Take advantage of the fact that mkfs.gfs2
1166 : creates master immediately after root. */
1167 0 : log_err(_("Can't find any dinodes that might "
1168 : "be the root; using master - 1.\n"));
1169 0 : possible_root = sdp->sd_meta_dir.in_addr - 1;
1170 : }
1171 0 : log_err(_("Found a possible root at: 0x%"PRIx64"\n"), possible_root);
1172 0 : sdp->sd_root_dir.in_addr = possible_root;
1173 0 : sdp->md.rooti = lgfs2_inode_read(sdp, possible_root);
1174 0 : if (!sdp->md.rooti || sdp->md.rooti->i_magic != GFS2_MAGIC) {
1175 0 : struct lgfs2_buffer_head *bh = NULL;
1176 : struct lgfs2_inum inum;
1177 :
1178 0 : log_err(_("The root dinode block is destroyed.\n"));
1179 0 : log_err(_("At this point I recommend "
1180 : "reinitializing it.\n"
1181 : "Hopefully everything will later "
1182 : "be put into lost+found.\n"));
1183 0 : if (!query(cx, _("Okay to reinitialize the root "
1184 : "dinode? (y/n)"))) {
1185 0 : log_err(_("The root dinode was not "
1186 : "reinitialized; aborting.\n"));
1187 0 : return -1;
1188 : }
1189 0 : inum.in_formal_ino = 1;
1190 0 : inum.in_addr = possible_root;
1191 0 : error = lgfs2_init_dinode(sdp, &bh, &inum, S_IFDIR | 0755, 0, &inum);
1192 0 : if (error != 0)
1193 0 : return -1;
1194 0 : lgfs2_brelse(bh);
1195 : }
1196 : }
1197 : /* Step 3 - Rebuild the lock protocol and file system table name */
1198 6 : if (query(cx, _("Okay to fix the GFS2 superblock? (y/n)"))) {
1199 6 : log_info(_("Found system master directory at: 0x%"PRIx64"\n"),
1200 : sdp->sd_meta_dir.in_addr);
1201 6 : sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_meta_dir.in_addr);
1202 6 : if (sdp->master_dir == NULL) {
1203 0 : log_crit(_("Error reading master inode: %s\n"), strerror(errno));
1204 0 : return -1;
1205 : }
1206 6 : sdp->master_dir->i_num.in_addr = sdp->sd_meta_dir.in_addr;
1207 6 : log_info(_("Found the root directory at: 0x%"PRIx64"\n"),
1208 : sdp->sd_root_dir.in_addr);
1209 6 : sdp->md.rooti = lgfs2_inode_read(sdp, sdp->sd_root_dir.in_addr);
1210 6 : if (sdp->md.rooti == NULL) {
1211 0 : log_crit(_("Error reading root inode: %s\n"), strerror(errno));
1212 0 : return -1;
1213 : }
1214 6 : sdp->sd_fs_format = GFS2_FORMAT_FS;
1215 6 : lgfs2_sb_write(sdp, sdp->device_fd);
1216 6 : lgfs2_inode_put(&sdp->md.rooti);
1217 6 : lgfs2_inode_put(&sdp->master_dir);
1218 6 : sb_fixed = 1;
1219 : } else {
1220 0 : log_crit(_("GFS2 superblock not fixed; fsck cannot proceed "
1221 : "without a valid superblock.\n"));
1222 0 : return -1;
1223 : }
1224 6 : return 0;
1225 : }
1226 :
1227 : /**
1228 : * fill_super_block
1229 : * @sdp:
1230 : *
1231 : * Returns: 0 on success, -1 on failure
1232 : */
1233 57 : static int fill_super_block(struct fsck_cx *cx)
1234 : {
1235 57 : struct lgfs2_sbd *sdp = cx->sdp;
1236 : int ret;
1237 :
1238 57 : sync();
1239 :
1240 57 : log_info( _("Initializing lists...\n"));
1241 57 : sdp->rgtree.osi_node = NULL;
1242 :
1243 57 : sdp->sd_bsize = LGFS2_DEFAULT_BSIZE;
1244 57 : if (lgfs2_compute_constants(sdp)) {
1245 0 : log_crit("%s\n", _("Failed to compute file system constants"));
1246 0 : return FSCK_ERROR;
1247 : }
1248 57 : ret = lgfs2_read_sb(sdp);
1249 57 : if (ret < 0) {
1250 6 : if (sb_repair(cx) != 0)
1251 0 : return -1; /* unrepairable, so exit */
1252 : /* Now that we've tried to repair it, re-read it. */
1253 6 : ret = lgfs2_read_sb(sdp);
1254 6 : if (ret < 0)
1255 0 : return FSCK_ERROR;
1256 : }
1257 57 : if (sdp->sd_fs_format > FSCK_MAX_FORMAT) {
1258 1 : log_crit(_("Unsupported gfs2 format found: %"PRIu32"\n"), sdp->sd_fs_format);
1259 1 : log_crit(_("A newer fsck.gfs2 is required to check this file system.\n"));
1260 1 : return FSCK_USAGE;
1261 : }
1262 56 : return 0;
1263 : }
1264 :
1265 : /**
1266 : * init_rindex - read in the rindex file
1267 : */
1268 56 : static int init_rindex(struct fsck_cx *cx)
1269 : {
1270 56 : struct lgfs2_sbd *sdp = cx->sdp;
1271 : struct lgfs2_inode *ip;
1272 :
1273 56 : sdp->md.riinode = lgfs2_lookupi(sdp->master_dir, "rindex", 6);
1274 56 : if (sdp->md.riinode)
1275 56 : return 0;
1276 :
1277 0 : if (!query(cx, _("The gfs2 system rindex inode is missing. "
1278 : "Okay to rebuild it? (y/n) "))) {
1279 0 : log_crit(_("Error: Cannot proceed without a valid rindex.\n"));
1280 0 : return -1;
1281 : }
1282 0 : ip = lgfs2_build_rindex(sdp);
1283 0 : if (ip == NULL) {
1284 0 : log_crit(_("Error rebuilding rindex: %s\n"), strerror(errno));
1285 0 : return -1;
1286 : }
1287 0 : lgfs2_inode_put(&ip);
1288 0 : return 0;
1289 : }
1290 :
1291 : /**
1292 : * initialize - initialize superblock pointer
1293 : *
1294 : */
1295 57 : int initialize(struct fsck_cx *cx, int *all_clean)
1296 : {
1297 57 : struct lgfs2_sbd *sdp = cx->sdp;
1298 57 : int clean_journals = 0, open_flag;
1299 : int err;
1300 :
1301 57 : *all_clean = 0;
1302 :
1303 57 : if (cx->opts->no)
1304 42 : open_flag = O_RDONLY;
1305 : else
1306 15 : open_flag = O_RDWR | O_EXCL;
1307 :
1308 57 : sdp->device_fd = open(cx->opts->device, open_flag);
1309 57 : if (sdp->device_fd < 0) {
1310 : struct mntent *mnt;
1311 0 : if (open_flag == O_RDONLY || errno != EBUSY) {
1312 0 : log_crit( _("Unable to open device: %s\n"),
1313 : cx->opts->device);
1314 0 : return FSCK_USAGE;
1315 : }
1316 : /* We can't open it EXCL. It may be already open rw (in which
1317 : case we want to deny them access) or it may be mounted as
1318 : the root file system at boot time (in which case we need to
1319 : allow it.)
1320 : If the device is busy, but not because it's mounted, fail.
1321 : This protects against cases where the file system is LVM
1322 : and perhaps mounted on a different node.
1323 : Try opening without O_EXCL. */
1324 0 : sdp->device_fd = lgfs2_open_mnt_dev(cx->opts->device, O_RDWR, &mnt);
1325 0 : if (sdp->device_fd < 0)
1326 0 : goto mount_fail;
1327 : /* If the device is mounted, but not mounted RO, fail. This
1328 : protects them against cases where the file system is
1329 : mounted RW, but still allows us to check our own root
1330 : file system. */
1331 0 : if (!hasmntopt(mnt, MNTOPT_RO))
1332 0 : goto close_fail;
1333 : /* The device is mounted RO, so it's likely our own root
1334 : file system. We can only do so much to protect the users
1335 : from themselves. */
1336 0 : was_mounted_ro = 1;
1337 : }
1338 :
1339 57 : if (lgfs2_get_dev_info(sdp->device_fd, &sdp->dinfo)) {
1340 0 : perror(cx->opts->device);
1341 0 : return FSCK_ERROR;
1342 : }
1343 :
1344 : /* read in sb from disk */
1345 57 : err = fill_super_block(cx);
1346 57 : if (err != FSCK_OK)
1347 1 : return err;
1348 :
1349 : /* Change lock protocol to be fsck_* instead of lock_* */
1350 56 : if (!cx->opts->no && preen_is_safe(sdp, cx->opts)) {
1351 14 : if (block_mounters(sdp, 1)) {
1352 0 : log_err( _("Unable to block other mounters\n"));
1353 0 : return FSCK_USAGE;
1354 : }
1355 : }
1356 :
1357 56 : sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_meta_dir.in_addr);
1358 56 : if (sdp->master_dir->i_magic != GFS2_MAGIC ||
1359 56 : sdp->master_dir->i_mh_type != GFS2_METATYPE_DI ||
1360 56 : !sdp->master_dir->i_size) {
1361 0 : lgfs2_inode_put(&sdp->master_dir);
1362 0 : rebuild_sysdir(cx);
1363 0 : sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_meta_dir.in_addr);
1364 0 : if (sdp->master_dir == NULL) {
1365 0 : log_crit(_("Error reading master directory: %s\n"), strerror(errno));
1366 0 : return FSCK_ERROR;
1367 : }
1368 : }
1369 :
1370 : /* Look up the "per_node" inode. If there are journals missing, we
1371 : need to figure out what's missing from per_node. And we need all
1372 : our journals to be there before we can replay them. */
1373 56 : lookup_per_node(cx, 0);
1374 :
1375 : /* We need rindex first in case jindex is missing and needs to read
1376 : in the rgrps before rebuilding it. However, note that if the rindex
1377 : is damaged, we need the journals to repair it. That's because the
1378 : journals likely contain rgrps and bitmaps, which we need to ignore
1379 : when we're trying to find the rgrps. */
1380 56 : if (init_rindex(cx))
1381 0 : return FSCK_ERROR;
1382 :
1383 56 : if (fetch_rgrps(cx))
1384 0 : return FSCK_ERROR;
1385 :
1386 : /* We need to read in jindex in order to replay the journals. If
1387 : there's an error, we may proceed and let init_system_inodes
1388 : try to rebuild it. */
1389 56 : if (init_jindex(cx, 1) == 0) {
1390 56 : if (replay_journals(cx, &clean_journals)) {
1391 0 : if (!cx->opts->no && preen_is_safe(sdp, cx->opts))
1392 0 : block_mounters(sdp, 0);
1393 0 : stack;
1394 0 : return FSCK_ERROR;
1395 : }
1396 56 : if (sdp->md.journals == clean_journals)
1397 55 : *all_clean = 1;
1398 1 : else if (cx->opts->force || !cx->opts->preen)
1399 1 : log_notice( _("\nJournal recovery complete.\n"));
1400 :
1401 56 : if (!cx->opts->force && *all_clean && cx->opts->preen)
1402 0 : return FSCK_OK;
1403 : }
1404 :
1405 56 : if (init_system_inodes(cx))
1406 0 : return FSCK_ERROR;
1407 :
1408 56 : return FSCK_OK;
1409 :
1410 0 : close_fail:
1411 0 : close(sdp->device_fd);
1412 0 : mount_fail:
1413 0 : log_crit( _("Device %s is busy.\n"), cx->opts->device);
1414 0 : return FSCK_USAGE;
1415 : }
1416 :
1417 56 : void destroy(struct fsck_cx *cx)
1418 : {
1419 56 : struct lgfs2_sbd *sdp = cx->sdp;
1420 :
1421 56 : if (!cx->opts->no) {
1422 14 : if (block_mounters(sdp, 0)) {
1423 0 : log_warn( _("Unable to unblock other mounters - manual intervention required\n"));
1424 0 : log_warn( _("Use 'gfs2_tool sb <device> proto' to fix\n"));
1425 : }
1426 14 : log_info( _("Syncing the device.\n"));
1427 14 : fsync(sdp->device_fd);
1428 : }
1429 56 : empty_super_block(cx);
1430 56 : close(sdp->device_fd);
1431 56 : if (was_mounted_ro && errors_corrected) {
1432 0 : sdp->device_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
1433 0 : if (sdp->device_fd >= 0) {
1434 0 : if (write(sdp->device_fd, "2", 1) == 2) {
1435 0 : close(sdp->device_fd);
1436 0 : return;
1437 : }
1438 0 : close(sdp->device_fd);
1439 : }
1440 0 : log_warn(_("fsck.gfs2: Could not flush caches (non-fatal).\n"));
1441 : }
1442 : }
|