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