]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/xfs_repair.c
xfs_repair: catch strtol() errors
[thirdparty/xfsprogs-dev.git] / repair / xfs_repair.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
2bd0ea18 2/*
da23017d
NS
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
2bd0ea18
NS
5 */
6
6b803e5a
CH
7#include "libxfs.h"
8#include "libxlog.h"
12be365e 9#include <sys/resource.h>
4a32b9e9 10#include "xfs_multidisk.h"
2bd0ea18 11#include "avl.h"
b4a09f89 12#include "libfrog/avl64.h"
2bd0ea18
NS
13#include "globals.h"
14#include "versions.h"
15#include "agheader.h"
16#include "protos.h"
17#include "incore.h"
18#include "err_protos.h"
cb5b3ef4 19#include "prefetch.h"
3b6ac903 20#include "threads.h"
06fbdda9 21#include "progress.h"
beed0dc8 22#include "dinode.h"
9e0f480e
DW
23#include "slab.h"
24#include "rmap.h"
fee68490 25#include "libfrog/fsgeom.h"
b658de93 26#include "libfrog/platform.h"
49031e66 27#include "bulkload.h"
0a8d74d6 28#include "quotacheck.h"
2bd0ea18 29
2bd0ea18
NS
30/*
31 * option tables for getsubopt calls
32 */
33
34/*
4af916f8 35 * -o: user-supplied override options
2bd0ea18 36 */
98884b66
DW
37enum o_opt_nums {
38 ASSUME_XFS = 0,
39 IHASH_SIZE,
40 BHASH_SIZE,
41 AG_STRIDE,
42 FORCE_GEO,
43 PHASE2_THREADS,
49031e66
DW
44 BLOAD_LEAF_SLACK,
45 BLOAD_NODE_SLACK,
0a8d74d6 46 NOQUOTA,
98884b66
DW
47 O_MAX_OPTS,
48};
49
8b8a6b02 50static char *o_opts[] = {
98884b66
DW
51 [ASSUME_XFS] = "assume_xfs",
52 [IHASH_SIZE] = "ihash",
53 [BHASH_SIZE] = "bhash",
54 [AG_STRIDE] = "ag_stride",
55 [FORCE_GEO] = "force_geometry",
56 [PHASE2_THREADS] = "phase2_threads",
49031e66
DW
57 [BLOAD_LEAF_SLACK] = "debug_bload_leaf_slack",
58 [BLOAD_NODE_SLACK] = "debug_bload_node_slack",
0a8d74d6 59 [NOQUOTA] = "noquota",
98884b66 60 [O_MAX_OPTS] = NULL,
2bd0ea18
NS
61};
62
4af916f8
BN
63/*
64 * -c: conversion options
65 */
98884b66
DW
66enum c_opt_nums {
67 CONVERT_LAZY_COUNT = 0,
49c226a5 68 CONVERT_INOBTCOUNT,
63bbaacf 69 CONVERT_BIGTIME,
1b3daa7d 70 CONVERT_NREXT64,
98884b66
DW
71 C_MAX_OPTS,
72};
73
8b8a6b02 74static char *c_opts[] = {
98884b66 75 [CONVERT_LAZY_COUNT] = "lazycount",
49c226a5 76 [CONVERT_INOBTCOUNT] = "inobtcount",
63bbaacf 77 [CONVERT_BIGTIME] = "bigtime",
1b3daa7d 78 [CONVERT_NREXT64] = "nrext64",
98884b66 79 [C_MAX_OPTS] = NULL,
4af916f8
BN
80};
81
82
2556c98b 83static int bhash_option_used;
12be365e 84static long max_mem_specified; /* in megabytes */
364a126c 85static int phase2_threads = 32;
7c3e94a3 86static bool report_corrected;
2556c98b 87
2bd0ea18
NS
88static void
89usage(void)
90{
4af916f8
BN
91 do_warn(_(
92"Usage: %s [options] device\n"
93"\n"
94"Options:\n"
95" -f The device is a file\n"
96" -L Force log zeroing. Do this as a last resort.\n"
97" -l logdev Specifies the device where the external log resides.\n"
98" -m maxmem Maximum amount of memory to be used in megabytes.\n"
99" -n No modify mode, just checks the filesystem for damage.\n"
7c3e94a3 100" (Cannot be used together with -e.)\n"
4af916f8
BN
101" -P Disables prefetching.\n"
102" -r rtdev Specifies the device where the realtime section resides.\n"
103" -v Verbose output.\n"
104" -c subopts Change filesystem parameters - use xfs_admin.\n"
105" -o subopts Override default behaviour, refer to man page.\n"
79e106f0 106" -t interval Reporting interval in seconds.\n"
4af916f8 107" -d Repair dangerously.\n"
7c3e94a3
JT
108" -e Exit with a non-zero code if any errors were repaired.\n"
109" (Cannot be used together with -n.)\n"
4af916f8 110" -V Reports version and exits.\n"), progname);
2bd0ea18
NS
111 exit(1);
112}
113
2bd0ea18
NS
114char *
115err_string(int err_code)
116{
507f4e33
NS
117 static char *err_message[XR_BAD_ERR_CODE];
118 static int done;
119
120 if (!done) {
121 err_message[XR_OK] = _("no error");
122 err_message[XR_BAD_MAGIC] = _("bad magic number");
123 err_message[XR_BAD_BLOCKSIZE] = _("bad blocksize field");
124 err_message[XR_BAD_BLOCKLOG] = _("bad blocksize log field");
4af916f8 125 err_message[XR_BAD_VERSION] = _("bad or unsupported version");
507f4e33
NS
126 err_message[XR_BAD_INPROGRESS] =
127 _("filesystem mkfs-in-progress bit set");
128 err_message[XR_BAD_FS_SIZE_DATA] =
129 _("inconsistent filesystem geometry information");
130 err_message[XR_BAD_INO_SIZE_DATA] =
131 _("bad inode size or inconsistent with number of inodes/block"),
132 err_message[XR_BAD_SECT_SIZE_DATA] = _("bad sector size");
133 err_message[XR_AGF_GEO_MISMATCH] =
134 _("AGF geometry info conflicts with filesystem geometry");
135 err_message[XR_AGI_GEO_MISMATCH] =
136 _("AGI geometry info conflicts with filesystem geometry");
137 err_message[XR_SB_GEO_MISMATCH] =
138 _("AG superblock geometry info conflicts with filesystem geometry");
139 err_message[XR_EOF] = _("attempted to perform I/O beyond EOF");
140 err_message[XR_BAD_RT_GEO_DATA] =
141 _("inconsistent filesystem geometry in realtime filesystem component");
142 err_message[XR_BAD_INO_MAX_PCT] =
143 _("maximum indicated percentage of inodes > 100%");
144 err_message[XR_BAD_INO_ALIGN] =
145 _("inconsistent inode alignment value");
146 err_message[XR_INSUFF_SEC_SB] =
147 _("not enough secondary superblocks with matching geometry");
148 err_message[XR_BAD_SB_UNIT] =
149 _("bad stripe unit in superblock");
150 err_message[XR_BAD_SB_WIDTH] =
151 _("bad stripe width in superblock");
152 err_message[XR_BAD_SVN] =
153 _("bad shared version number in superblock");
88f364a9
DC
154 err_message[XR_BAD_CRC] =
155 _("bad CRC in superblock");
02b56f87
DW
156 err_message[XR_BAD_DIR_SIZE_DATA] =
157 _("inconsistent directory geometry information");
eb9cee60
DW
158 err_message[XR_BAD_LOG_GEOMETRY] =
159 _("inconsistent log geometry information");
507f4e33
NS
160 done = 1;
161 }
162
2bd0ea18 163 if (err_code < XR_OK || err_code >= XR_BAD_ERR_CODE)
507f4e33 164 do_abort(_("bad error code - %d\n"), err_code);
2bd0ea18
NS
165
166 return(err_message[err_code]);
167}
168
169static void
170noval(char opt, char *tbl[], int idx)
171{
507f4e33 172 do_warn(_("-%c %s option cannot have a value\n"), opt, tbl[idx]);
2bd0ea18
NS
173 usage();
174}
175
176static void
177respec(char opt, char *tbl[], int idx)
178{
179 do_warn("-%c ", opt);
180 if (tbl)
181 do_warn("%s ", tbl[idx]);
507f4e33 182 do_warn(_("option respecified\n"));
2bd0ea18
NS
183 usage();
184}
185
186static void
187unknown(char opt, char *s)
188{
507f4e33 189 do_warn(_("unknown option -%c %s\n"), opt, s);
2bd0ea18
NS
190 usage();
191}
192
193/*
194 * sets only the global argument flags and variables
195 */
8b8a6b02 196static void
2bd0ea18
NS
197process_args(int argc, char **argv)
198{
199 char *p;
200 int c;
201
202 log_spec = 0;
203 fs_is_dirty = 0;
204 verbose = 0;
205 no_modify = 0;
c781939c 206 dangerously = 0;
2bd0ea18 207 isa_file = 0;
d321ceac 208 zap_log = 0;
2bd0ea18 209 dumpcore = 0;
0f012a4c 210 full_ino_ex_data = 0;
2bd0ea18
NS
211 force_geo = 0;
212 assume_xfs = 0;
6bf4721d 213 copied_sunit = 0;
2bd0ea18
NS
214 sb_inoalignmt = 0;
215 sb_unit = 0;
216 sb_width = 0;
add3cb90 217 ag_stride = 0;
2556c98b 218 thread_count = 1;
06fbdda9 219 report_interval = PROG_RPT_DEFAULT;
7c3e94a3 220 report_corrected = false;
2bd0ea18
NS
221
222 /*
223 * XXX have to add suboption processing here
224 * attributes, quotas, nlinks, aligned_inos, sb_fbits
225 */
7c3e94a3 226 while ((c = getopt(argc, argv, "c:o:fl:m:r:LnDvVdPet:")) != EOF) {
2bd0ea18
NS
227 switch (c) {
228 case 'D':
229 dumpcore = 1;
230 break;
231 case 'o':
232 p = optarg;
233 while (*p != '\0') {
234 char *val;
235
ab870d0e 236 switch (getsubopt(&p, o_opts, &val)) {
2bd0ea18
NS
237 case ASSUME_XFS:
238 if (val)
239 noval('o', o_opts, ASSUME_XFS);
240 if (assume_xfs)
241 respec('o', o_opts, ASSUME_XFS);
242 assume_xfs = 1;
243 break;
9f38f08d 244 case IHASH_SIZE:
3a19fb7d
CH
245 do_warn(
246 _("-o ihash option has been removed and will be ignored\n"));
9f38f08d
MV
247 break;
248 case BHASH_SIZE:
12be365e
BN
249 if (max_mem_specified)
250 do_abort(
3a19fb7d 251 _("-o bhash option cannot be used with -m option\n"));
1f8480b6
DW
252 if (!val)
253 do_abort(
254 _("-o bhash requires a parameter\n"));
d03b73d2 255 errno = 0;
5e656dbb 256 libxfs_bhash_size = (int)strtol(val, NULL, 0);
d03b73d2
AA
257 if (errno)
258 do_abort(
259 _("-o bhash invalid parameter: %s\n"), strerror(errno));
2556c98b 260 bhash_option_used = 1;
cb5b3ef4 261 break;
add3cb90 262 case AG_STRIDE:
1f8480b6
DW
263 if (!val)
264 do_abort(
265 _("-o ag_stride requires a parameter\n"));
d03b73d2 266 errno = 0;
5e656dbb 267 ag_stride = (int)strtol(val, NULL, 0);
d03b73d2
AA
268 if (errno)
269 do_abort(
270 _("-o ag_stride invalid parameter: %s\n"), strerror(errno));
3b6ac903 271 break;
d4dd6ab5
CH
272 case FORCE_GEO:
273 if (val)
274 noval('o', o_opts, FORCE_GEO);
275 if (force_geo)
276 respec('o', o_opts, FORCE_GEO);
277 force_geo = 1;
278 break;
364a126c 279 case PHASE2_THREADS:
1f8480b6
DW
280 if (!val)
281 do_abort(
282 _("-o phase2_threads requires a parameter\n"));
d03b73d2 283 errno = 0;
364a126c 284 phase2_threads = (int)strtol(val, NULL, 0);
d03b73d2
AA
285 if (errno)
286 do_abort(
287 _("-o phase2_threads invalid parameter: %s\n"), strerror(errno));
364a126c 288 break;
49031e66
DW
289 case BLOAD_LEAF_SLACK:
290 if (!val)
291 do_abort(
292 _("-o debug_bload_leaf_slack requires a parameter\n"));
d03b73d2 293 errno = 0;
49031e66 294 bload_leaf_slack = (int)strtol(val, NULL, 0);
d03b73d2
AA
295 if (errno)
296 do_abort(
297 _("-o debug_bload_leaf_slack invalid parameter: %s\n"), strerror(errno));
49031e66
DW
298 break;
299 case BLOAD_NODE_SLACK:
300 if (!val)
301 do_abort(
302 _("-o debug_bload_node_slack requires a parameter\n"));
d03b73d2 303 errno = 0;
49031e66 304 bload_node_slack = (int)strtol(val, NULL, 0);
d03b73d2
AA
305 if (errno)
306 do_abort(
307 _("-o debug_bload_node_slack invalid parameter: %s\n"), strerror(errno));
49031e66 308 break;
0a8d74d6
DW
309 case NOQUOTA:
310 quotacheck_skip();
311 break;
2bd0ea18
NS
312 default:
313 unknown('o', val);
314 break;
315 }
316 }
317 break;
4af916f8
BN
318 case 'c':
319 p = optarg;
320 while (*p) {
321 char *val;
322
ab870d0e 323 switch (getsubopt(&p, c_opts, &val)) {
4af916f8 324 case CONVERT_LAZY_COUNT:
1f8480b6
DW
325 if (!val)
326 do_abort(
327 _("-c lazycount requires a parameter\n"));
d03b73d2 328 errno = 0;
5e656dbb 329 lazy_count = (int)strtol(val, NULL, 0);
d03b73d2
AA
330 if (errno)
331 do_abort(
332 _("-o lazycount invalid parameter: %s\n"), strerror(errno));
4af916f8
BN
333 convert_lazy_count = 1;
334 break;
49c226a5
DW
335 case CONVERT_INOBTCOUNT:
336 if (!val)
337 do_abort(
338 _("-c inobtcount requires a parameter\n"));
339 if (strtol(val, NULL, 0) != 1)
340 do_abort(
341 _("-c inobtcount only supports upgrades\n"));
342 add_inobtcount = true;
343 break;
63bbaacf
DW
344 case CONVERT_BIGTIME:
345 if (!val)
346 do_abort(
347 _("-c bigtime requires a parameter\n"));
348 if (strtol(val, NULL, 0) != 1)
349 do_abort(
350 _("-c bigtime only supports upgrades\n"));
351 add_bigtime = true;
352 break;
1b3daa7d
CB
353 case CONVERT_NREXT64:
354 if (!val)
355 do_abort(
356 _("-c nrext64 requires a parameter\n"));
357 if (strtol(val, NULL, 0) != 1)
358 do_abort(
359 _("-c nrext64 only supports upgrades\n"));
360 add_nrext64 = true;
361 break;
4af916f8
BN
362 default:
363 unknown('c', val);
364 break;
365 }
366 }
367 break;
2bd0ea18
NS
368 case 'l':
369 log_name = optarg;
370 log_spec = 1;
371 break;
42a564ab
ES
372 case 'r':
373 rt_name = optarg;
374 rt_spec = 1;
375 break;
2bd0ea18
NS
376 case 'f':
377 isa_file = 1;
378 break;
12be365e
BN
379 case 'm':
380 if (bhash_option_used)
381 do_abort(_("-m option cannot be used with "
382 "-o bhash option\n"));
d03b73d2 383 errno = 0;
5e656dbb 384 max_mem_specified = strtol(optarg, NULL, 0);
d03b73d2
AA
385 if (errno)
386 do_abort(
387 _("%s: invalid memory amount: %s\n"), optarg, strerror(errno));
12be365e 388 break;
d321ceac
NS
389 case 'L':
390 zap_log = 1;
391 break;
2bd0ea18
NS
392 case 'n':
393 no_modify = 1;
394 break;
6089b6f0
NS
395 case 'd':
396 dangerously = 1;
397 break;
2bd0ea18 398 case 'v':
3b6ac903 399 verbose++;
2bd0ea18
NS
400 break;
401 case 'V':
507f4e33 402 printf(_("%s version %s\n"), progname, VERSION);
3d98fe63 403 exit(0);
cb5b3ef4 404 case 'P':
2556c98b 405 do_prefetch = 0;
3b6ac903 406 break;
06fbdda9 407 case 't':
d03b73d2 408 errno = 0;
fcac184c 409 report_interval = strtol(optarg, NULL, 0);
d03b73d2
AA
410 if (errno)
411 do_abort(
412 _("%s: invalid interval: %s\n"), optarg, strerror(errno));
06fbdda9 413 break;
7c3e94a3
JT
414 case 'e':
415 report_corrected = true;
416 break;
78aeaffd 417 default:
2bd0ea18
NS
418 usage();
419 }
420 }
421
422 if (argc - optind != 1)
423 usage();
424
425 if ((fs_name = argv[optind]) == NULL)
426 usage();
7c3e94a3
JT
427
428 if (report_corrected && no_modify)
429 usage();
7007b99f
DW
430
431 p = getenv("XFS_REPAIR_FAIL_AFTER_PHASE");
d03b73d2
AA
432 if (p) {
433 errno = 0;
7007b99f 434 fail_after_phase = (int)strtol(p, NULL, 0);
d03b73d2
AA
435 if (errno)
436 do_abort(
437 _("%s: invalid phase in XFS_REPAIR_FAIL_AFTER_PHASE: %s\n"),
438 p, strerror(errno));
439 }
2bd0ea18
NS
440}
441
b1559967 442void __attribute__((noreturn))
2bd0ea18
NS
443do_error(char const *msg, ...)
444{
445 va_list args;
446
507f4e33 447 fprintf(stderr, _("\nfatal error -- "));
2bd0ea18
NS
448
449 va_start(args, msg);
079afa09
CH
450 vfprintf(stderr, msg, args);
451 if (dumpcore)
452 abort();
453 exit(1);
2bd0ea18
NS
454}
455
456/*
457 * like do_error, only the error is internal, no system
458 * error so no oserror processing
459 */
b1559967 460void __attribute__((noreturn))
2bd0ea18
NS
461do_abort(char const *msg, ...)
462{
463 va_list args;
464
465 va_start(args, msg);
079afa09
CH
466 vfprintf(stderr, msg, args);
467 if (dumpcore)
468 abort();
469 exit(1);
2bd0ea18
NS
470}
471
472void
473do_warn(char const *msg, ...)
474{
475 va_list args;
476
477 fs_is_dirty = 1;
478
479 va_start(args, msg);
079afa09 480 vfprintf(stderr, msg, args);
2bd0ea18
NS
481 va_end(args);
482}
483
484/* no formatting */
485
486void
487do_log(char const *msg, ...)
488{
489 va_list args;
490
491 va_start(args, msg);
079afa09 492 vfprintf(stderr, msg, args);
2bd0ea18
NS
493 va_end(args);
494}
495
a3e126aa
DW
496/* Make sure a fixed-location inode is where it should be. */
497static void
498validate_sb_ino(
499 xfs_ino_t *ino,
500 xfs_ino_t expected_ino,
501 const char *tag)
502{
503 if (*ino == expected_ino)
504 return;
505
506 do_warn(
507_("sb %s inode value %" PRIu64 " %sinconsistent with calculated value %"PRIu64"\n"),
508 tag, *ino, *ino == NULLFSINO ? "(NULLFSINO) " : "",
509 expected_ino);
510
511 if (!no_modify)
512 do_warn(
513_("resetting superblock %s inode pointer to %"PRIu64"\n"),
514 tag, expected_ino);
515 else
516 do_warn(
517_("would reset superblock %s inode pointer to %"PRIu64"\n"),
518 tag, expected_ino);
519
520 /*
521 * Just set the value -- safe since the superblock doesn't get flushed
522 * out if no_modify is set.
523 */
524 *ino = expected_ino;
525}
526
ded6b558
DW
527/* Does the root directory inode look like a plausible root directory? */
528static bool
529has_plausible_rootdir(
530 struct xfs_mount *mp)
531{
532 struct xfs_inode *ip;
533 xfs_ino_t ino;
534 int error;
535 bool ret = false;
536
1fecabf9 537 error = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &ip);
ded6b558
DW
538 if (error)
539 goto out;
540 if (!S_ISDIR(VFS_I(ip)->i_mode))
541 goto out_rele;
542
543 error = -libxfs_dir_lookup(NULL, ip, &xfs_name_dotdot, &ino, NULL);
544 if (error)
545 goto out_rele;
546
547 /* The root directory '..' entry points to the directory. */
548 if (ino == mp->m_sb.sb_rootino)
549 ret = true;
550
551out_rele:
552 libxfs_irele(ip);
553out:
554 return ret;
555}
556
306b450b
DW
557/*
558 * If any of the secondary SBs contain a *correct* value for sunit, write that
559 * back to the primary superblock.
560 */
561static void
562guess_correct_sunit(
563 struct xfs_mount *mp)
564{
565 struct xfs_sb sb;
566 struct xfs_buf *bp;
567 xfs_ino_t calc_rootino = NULLFSINO;
568 xfs_agnumber_t agno;
569 unsigned int new_sunit;
570 unsigned int sunit_guess;
571 int error;
572
573 /* Try reading secondary supers to see if we find a good sb_unit. */
574 for (agno = 1; agno < mp->m_sb.sb_agcount; agno++) {
575 error = -libxfs_sb_read_secondary(mp, NULL, agno, &bp);
576 if (error)
577 continue;
d6522f1d 578 libxfs_sb_from_disk(&sb, bp->b_addr);
e02ba985 579 libxfs_buf_relse(bp);
306b450b
DW
580
581 calc_rootino = libxfs_ialloc_calc_rootino(mp, sb.sb_unit);
582 if (calc_rootino == mp->m_sb.sb_rootino)
583 break;
584 }
585
586 /* If we found a reasonable value, log where we found it. */
587 if (calc_rootino == mp->m_sb.sb_rootino) {
588 do_warn(_("AG %u superblock contains plausible sb_unit value\n"),
589 agno);
590 new_sunit = sb.sb_unit;
591 goto fix;
592 }
593
594 /* Try successive powers of two. */
595 for (sunit_guess = 1;
596 sunit_guess <= XFS_AG_MAX_BLOCKS(mp->m_sb.sb_blocklog);
597 sunit_guess *= 2) {
598 calc_rootino = libxfs_ialloc_calc_rootino(mp, sunit_guess);
599 if (calc_rootino == mp->m_sb.sb_rootino)
600 break;
601 }
602
603 /* If we found a reasonable value, log where we found it. */
604 if (calc_rootino == mp->m_sb.sb_rootino) {
605 do_warn(_("Found an sb_unit value that looks plausible\n"));
606 new_sunit = sunit_guess;
607 goto fix;
608 }
609
610 do_warn(_("Could not estimate a plausible sb_unit value\n"));
611 return;
612
613fix:
614 if (!no_modify)
615 do_warn(_("Resetting sb_unit to %u\n"), new_sunit);
616 else
617 do_warn(_("Would reset sb_unit to %u\n"), new_sunit);
618
619 /*
620 * Just set the value -- safe since the superblock doesn't get flushed
621 * out if no_modify is set.
622 */
623 mp->m_sb.sb_unit = new_sunit;
624
625 /* Make sure that swidth is still a multiple of sunit. */
626 if (mp->m_sb.sb_width % mp->m_sb.sb_unit == 0)
627 return;
628
629 if (!no_modify)
630 do_warn(_("Resetting sb_width to %u\n"), new_sunit);
631 else
632 do_warn(_("Would reset sb_width to %u\n"), new_sunit);
633}
634
90b2397e
DW
635/*
636 * Make sure that the first 3 inodes in the filesystem are the root directory,
637 * the realtime bitmap, and the realtime summary, in that order.
638 */
8b8a6b02 639static void
90b2397e
DW
640calc_mkfs(
641 struct xfs_mount *mp)
2bd0ea18 642{
90b2397e 643 xfs_ino_t rootino;
649bfa9a 644
90b2397e 645 rootino = libxfs_ialloc_calc_rootino(mp, mp->m_sb.sb_unit);
d4dd6ab5 646
ded6b558
DW
647 /*
648 * If the root inode isn't where we think it is, check its plausibility
649 * as a root directory. It's possible that somebody changed sunit
650 * since the filesystem was created, which can change the value of the
651 * above computation. Don't blow up the root directory if this is the
652 * case.
653 */
654 if (mp->m_sb.sb_rootino != rootino && has_plausible_rootdir(mp)) {
655 do_warn(
656_("sb root inode value %" PRIu64 " valid but in unaligned location (expected %"PRIu64") possibly due to sunit change\n"),
657 mp->m_sb.sb_rootino, rootino);
306b450b 658 guess_correct_sunit(mp);
ded6b558
DW
659 rootino = mp->m_sb.sb_rootino;
660 }
661
90b2397e 662 validate_sb_ino(&mp->m_sb.sb_rootino, rootino,
a3e126aa 663 _("root"));
90b2397e 664 validate_sb_ino(&mp->m_sb.sb_rbmino, rootino + 1,
a3e126aa 665 _("realtime bitmap"));
90b2397e 666 validate_sb_ino(&mp->m_sb.sb_rsumino, rootino + 2,
a3e126aa 667 _("realtime summary"));
2bd0ea18
NS
668}
669
1926558d
BF
670/*
671 * v5 superblock metadata track the LSN of last modification and thus require
672 * that the current LSN is always moving forward. The current LSN is reset if
673 * the log has been cleared, which puts the log behind parts of the filesystem
674 * on-disk and can disrupt log recovery.
675 *
676 * We have tracked the maximum LSN of every piece of metadata that has been read
677 * in via the read verifiers. Compare the max LSN with the log and if the log is
678 * behind, bump the cycle number and reformat the log.
679 */
680static void
681format_log_max_lsn(
682 struct xfs_mount *mp)
683{
684 struct xlog *log = mp->m_log;
685 int max_cycle;
686 int max_block;
687 int new_cycle;
688 xfs_daddr_t logstart;
689 xfs_daddr_t logblocks;
690 int logversion;
691
2660e653 692 if (!xfs_has_crc(mp))
1926558d
BF
693 return;
694
695 /*
696 * If the log is ahead of the highest metadata LSN we've seen, we're
697 * safe and there's nothing to do.
698 */
699 max_cycle = CYCLE_LSN(libxfs_max_lsn);
700 max_block = BLOCK_LSN(libxfs_max_lsn);
701 if (max_cycle < log->l_curr_cycle ||
702 (max_cycle == log->l_curr_cycle && max_block < log->l_curr_block))
703 return;
704
705 /*
706 * Going to the next cycle should be sufficient but we bump by a few
707 * counts to help cover any metadata LSNs we could have missed.
708 */
709 new_cycle = max_cycle + 3;
710 logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart);
711 logblocks = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
2660e653 712 logversion = xfs_has_logv2(mp) ? 2 : 1;
1926558d
BF
713
714 do_warn(_("Maximum metadata LSN (%d:%d) is ahead of log (%d:%d).\n"),
715 max_cycle, max_block, log->l_curr_cycle, log->l_curr_block);
716
717 if (no_modify) {
718 do_warn(_("Would format log to cycle %d.\n"), new_cycle);
719 return;
720 }
721
722 do_warn(_("Format log to cycle %d.\n"), new_cycle);
1c12a814
BF
723 libxfs_log_clear(log->l_dev, NULL, logstart, logblocks,
724 &mp->m_sb.sb_uuid, logversion, mp->m_sb.sb_logsunit,
571a78a7 725 XLOG_FMT, new_cycle, true);
1926558d
BF
726}
727
4a32b9e9
DC
728/*
729 * mkfs increases the AG count for "multidisk" configurations, we want
730 * to target these for an increase in thread count. Hence check the superlock
731 * geometry information to determine if mkfs considered this a multidisk
732 * configuration.
733 */
734static bool
735is_multidisk_filesystem(
736 struct xfs_mount *mp)
737{
738 struct xfs_sb *sbp = &mp->m_sb;
739
740 /* High agcount filesystems are always considered "multidisk" */
741 if (sbp->sb_agcount >= XFS_MULTIDISK_AGCOUNT)
742 return true;
743
744 /*
745 * If it doesn't have a sunit/swidth, mkfs didn't consider it a
746 * multi-disk array, so we don't either.
747 */
748 if (!sbp->sb_unit)
749 return false;
750
751 ASSERT(sbp->sb_width);
752 return true;
753}
754
28a0a30f
ZL
755/*
756 * if the sector size of the filesystem we are trying to repair is
757 * smaller than that of the underlying filesystem (i.e. we are repairing
758 * an image), the we have to turn off direct IO because we cannot do IO
759 * smaller than the host filesystem's sector size.
760 */
761static void
762check_fs_vs_host_sectsize(
763 struct xfs_sb *sb)
764{
28cd682b 765 int ret;
28a0a30f 766 long old_flags;
9612817d 767 struct xfs_fsop_geom geom = { 0 };
28a0a30f 768
fc83c757 769 ret = -xfrog_geometry(x.data.fd, &geom);
9612817d 770 if (ret) {
28a0a30f
ZL
771 do_log(_("Cannot get host filesystem geometry.\n"
772 "Repair may fail if there is a sector size mismatch between\n"
773 "the image and the host filesystem.\n"));
774 geom.sectsize = BBSIZE;
775 }
776
777 if (sb->sb_sectsize < geom.sectsize) {
fc83c757
CH
778 old_flags = fcntl(x.data.fd, F_GETFL, 0);
779 if (fcntl(x.data.fd, F_SETFL, old_flags & ~O_DIRECT) < 0) {
28a0a30f
ZL
780 do_warn(_(
781 "Sector size on host filesystem larger than image sector size.\n"
782 "Cannot turn off direct IO, so exiting.\n"));
783 exit(1);
784 }
785 }
786}
787
945c7341
DW
788/*
789 * If we set up a writeback function to set NEEDSREPAIR while the filesystem is
790 * dirty, there's a chance that calling libxfs_getsb could deadlock the buffer
791 * cache while trying to get the primary sb buffer if the first non-sb write to
792 * the filesystem is the result of a cache shake. Retain a reference to the
793 * primary sb buffer to avoid all that.
794 */
795static struct xfs_buf *primary_sb_bp; /* buffer for superblock */
796
797int
798retain_primary_sb(
799 struct xfs_mount *mp)
800{
801 int error;
802
803 error = -libxfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR,
804 XFS_FSS_TO_BB(mp, 1), 0, &primary_sb_bp,
805 &xfs_sb_buf_ops);
806 if (error)
807 return error;
808
809 libxfs_buf_unlock(primary_sb_bp);
810 return 0;
811}
812
813static void
814drop_primary_sb(void)
815{
816 if (!primary_sb_bp)
817 return;
818
819 libxfs_buf_lock(primary_sb_bp);
820 libxfs_buf_relse(primary_sb_bp);
821 primary_sb_bp = NULL;
822}
823
824static int
825get_primary_sb(
826 struct xfs_mount *mp,
827 struct xfs_buf **bpp)
828{
829 int error;
830
831 *bpp = NULL;
832
833 if (!primary_sb_bp) {
834 error = retain_primary_sb(mp);
835 if (error)
836 return error;
837 }
838
839 libxfs_buf_lock(primary_sb_bp);
840 xfs_buf_hold(primary_sb_bp);
841 *bpp = primary_sb_bp;
842 return 0;
843}
844
a7348c58 845/* Clear needsrepair after a successful repair run. */
b6fef47a 846static void
a7348c58
DW
847clear_needsrepair(
848 struct xfs_mount *mp)
849{
850 struct xfs_buf *bp;
851 int error;
852
853 /*
854 * If we're going to clear NEEDSREPAIR, we need to make absolutely sure
855 * that everything is ok with the ondisk filesystem. Make sure any
856 * dirty buffers are sent to disk and that the disks have persisted
857 * writes to stable storage. If that fails, leave NEEDSREPAIR in
858 * place.
859 */
860 error = -libxfs_flush_mount(mp);
861 if (error) {
862 do_warn(
863 _("Cannot clear needsrepair due to flush failure, err=%d.\n"),
864 error);
945c7341 865 goto drop;
a7348c58
DW
866 }
867
868 /* Clear needsrepair from the superblock. */
945c7341
DW
869 error = get_primary_sb(mp, &bp);
870 if (error) {
a7348c58 871 do_warn(
945c7341 872 _("Cannot clear needsrepair from primary super, err=%d.\n"), error);
a7348c58
DW
873 } else {
874 mp->m_sb.sb_features_incompat &=
875 ~XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
876 libxfs_sb_to_disk(bp->b_addr, &mp->m_sb);
877 libxfs_buf_mark_dirty(bp);
878 }
879 if (bp)
880 libxfs_buf_relse(bp);
945c7341
DW
881drop:
882 drop_primary_sb();
a7348c58
DW
883}
884
3b7667cb
DW
885static void
886update_sb_crc_only(
887 struct xfs_buf *bp)
888{
889 xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF);
890}
891
892/* Forcibly write the primary superblock with the NEEDSREPAIR flag set. */
893static void
894force_needsrepair(
895 struct xfs_mount *mp)
896{
897 struct xfs_buf_ops fake_ops;
898 struct xfs_buf *bp;
899 int error;
900
2660e653 901 if (!xfs_has_crc(mp) ||
3b7667cb
DW
902 xfs_sb_version_needsrepair(&mp->m_sb))
903 return;
904
945c7341
DW
905 error = get_primary_sb(mp, &bp);
906 if (error) {
3b7667cb 907 do_log(
945c7341 908 _("couldn't get superblock to set needsrepair, err=%d\n"), error);
3b7667cb
DW
909 } else {
910 /*
911 * It's possible that we need to set NEEDSREPAIR before we've
912 * had a chance to fix the summary counters in the primary sb.
913 * With the exception of those counters, phase 1 already
914 * ensured that the geometry makes sense.
915 *
916 * Bad summary counters in the primary super can cause the
917 * write verifier to fail, so substitute a dummy that only sets
918 * the CRC. In the event of a crash, NEEDSREPAIR will prevent
919 * the kernel from mounting our potentially damaged filesystem
920 * until repair is run again, so it's ok to bypass the usual
921 * verification in this one case.
922 */
923 fake_ops = xfs_sb_buf_ops; /* struct copy */
924 fake_ops.verify_write = update_sb_crc_only;
925
926 mp->m_sb.sb_features_incompat |=
927 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
928 libxfs_sb_to_disk(bp->b_addr, &mp->m_sb);
929
930 /* Force the primary super to disk immediately. */
931 bp->b_ops = &fake_ops;
932 error = -libxfs_bwrite(bp);
933 bp->b_ops = &xfs_sb_buf_ops;
934 if (error)
935 do_log(_("couldn't force needsrepair, err=%d\n"), error);
936 }
937 if (bp)
938 libxfs_buf_relse(bp);
939}
940
941/*
942 * Intercept the first non-super write to the filesystem so we can set
943 * NEEDSREPAIR to protect the filesystem from mount in case of a crash.
944 */
945static void
946repair_capture_writeback(
947 struct xfs_buf *bp)
948{
949 struct xfs_mount *mp = bp->b_mount;
950 static pthread_mutex_t wb_mutex = PTHREAD_MUTEX_INITIALIZER;
951
952 /*
953 * This write hook ignores any buffer that looks like a superblock to
954 * avoid hook recursion when setting NEEDSREPAIR. Higher level code
955 * modifying an sb must control the flag manually.
956 */
f1208396 957 if (bp->b_ops == &xfs_sb_buf_ops || xfs_buf_daddr(bp) == XFS_SB_DADDR)
3b7667cb
DW
958 return;
959
960 pthread_mutex_lock(&wb_mutex);
961
962 /*
963 * If someone else already dropped the hook, then needsrepair has
964 * already been set on the filesystem and we can unlock.
965 */
966 if (mp->m_buf_writeback_fn != repair_capture_writeback)
967 goto unlock;
968
969 /*
970 * If we get here, the buffer being written is not a superblock, and
971 * needsrepair needs to be set. The hook is kept in place to plug all
972 * other writes until the sb write finishes.
973 */
974 force_needsrepair(mp);
975
976 /* We only set needsrepair once, so clear the hook now. */
977 mp->m_buf_writeback_fn = NULL;
978unlock:
979 pthread_mutex_unlock(&wb_mutex);
980}
981
8e9f22d6
DW
982static inline void
983phase_end(int phase)
984{
985 timestamp(PHASE_END, phase, NULL);
7007b99f
DW
986
987 /* Fail if someone injected an post-phase error. */
988 if (fail_after_phase && phase == fail_after_phase)
989 platform_crash();
8e9f22d6
DW
990}
991
2bd0ea18
NS
992int
993main(int argc, char **argv)
994{
2bd0ea18
NS
995 xfs_mount_t *temp_mp;
996 xfs_mount_t *mp;
167137fe 997 struct xfs_buf *sbp;
2bd0ea18 998 xfs_mount_t xfs_m;
1d6cb115 999 struct xlog log = {0};
06fbdda9 1000 char *msgbuf;
88f364a9
DC
1001 struct xfs_sb psb;
1002 int rval;
e7fd2b6f 1003 struct xfs_ino_geometry *igeo;
14fb3613 1004 int error;
2bd0ea18
NS
1005
1006 progname = basename(argv[0]);
507f4e33
NS
1007 setlocale(LC_ALL, "");
1008 bindtextdomain(PACKAGE, LOCALEDIR);
1009 textdomain(PACKAGE);
beed0dc8 1010 dinode_bmbt_translation_init();
2bd0ea18
NS
1011
1012 temp_mp = &xfs_m;
1013 setbuf(stdout, NULL);
1014
1015 process_args(argc, argv);
d321ceac 1016 xfs_init(&x);
2bd0ea18 1017
2556c98b
BN
1018 msgbuf = malloc(DURATION_BUF_SIZE);
1019
06fbdda9 1020 timestamp(PHASE_START, 0, NULL);
8e9f22d6 1021 phase_end(0);
06fbdda9 1022
28a0a30f
ZL
1023 /* -f forces this, but let's be nice and autodetect it, as well. */
1024 if (!isa_file) {
28a0a30f
ZL
1025 struct stat statbuf;
1026
fc83c757 1027 if (fstat(x.data.fd, &statbuf) < 0)
28a0a30f
ZL
1028 do_warn(_("%s: couldn't stat \"%s\"\n"),
1029 progname, fs_name);
1030 else if (S_ISREG(statbuf.st_mode))
1031 isa_file = 1;
1032 }
1033
1034 if (isa_file) {
1035 /* Best effort attempt to validate fs vs host sector size */
1036 rval = get_sb(&psb, 0, XFS_MAX_SECTORSIZE, 0);
1037 if (rval == XR_OK)
1038 check_fs_vs_host_sectsize(&psb);
1039 }
1040
2bd0ea18
NS
1041 /* do phase1 to make sure we have a superblock */
1042 phase1(temp_mp);
8e9f22d6 1043 phase_end(1);
2bd0ea18
NS
1044
1045 if (no_modify && primary_sb_modified) {
507f4e33
NS
1046 do_warn(_("Primary superblock would have been modified.\n"
1047 "Cannot proceed further in no_modify mode.\n"
1048 "Exiting now.\n"));
2bd0ea18
NS
1049 exit(1);
1050 }
1051
88f364a9
DC
1052 rval = get_sb(&psb, 0, XFS_MAX_SECTORSIZE, 0);
1053 if (rval != XR_OK) {
1054 do_warn(_("Primary superblock bad after phase 1!\n"
1055 "Exiting now.\n"));
1056 exit(1);
1057 }
2bd0ea18 1058
f63fd268 1059 /*
28a0a30f
ZL
1060 * Now that we have completely validated the superblock, geometry may
1061 * have changed; re-check geometry vs the host filesystem geometry
f63fd268 1062 */
28a0a30f
ZL
1063 if (isa_file)
1064 check_fs_vs_host_sectsize(&psb);
88f364a9 1065
1d6cb115
BF
1066 /*
1067 * Prepare the mount structure. Point the log reference to our local
1068 * copy so it's available to the various phases. The log bits are
1069 * initialized in phase 2.
1070 */
88f364a9 1071 memset(&xfs_m, 0, sizeof(xfs_mount_t));
ddd9942b 1072 mp = libxfs_mount(&xfs_m, &psb, &x, 0);
2bd0ea18
NS
1073
1074 if (!mp) {
507f4e33
NS
1075 fprintf(stderr,
1076 _("%s: cannot repair this filesystem. Sorry.\n"),
2bd0ea18
NS
1077 progname);
1078 exit(1);
1079 }
1d6cb115 1080 mp->m_log = &log;
e7fd2b6f 1081 igeo = M_IGEO(mp);
2bd0ea18 1082
23639f77
ES
1083 /* Spit out function & line on these corruption macros */
1084 if (verbose > 2)
2420d095 1085 xfs_set_reporting_corruption(mp);
23639f77 1086
3b7667cb 1087 /* Capture the first writeback so that we can set needsrepair. */
2660e653 1088 if (xfs_has_crc(mp))
3b7667cb
DW
1089 mp->m_buf_writeback_fn = repair_capture_writeback;
1090
2bd0ea18
NS
1091 /*
1092 * set XFS-independent status vars from the mount/sb structure
1093 */
1094 glob_agcount = mp->m_sb.sb_agcount;
1095
1096 chunks_pblock = mp->m_sb.sb_inopblock / XFS_INODES_PER_CHUNK;
5a707ca1 1097 max_symlink_blocks = libxfs_symlink_blocks(mp, XFS_SYMLINK_MAXLEN);
2bd0ea18 1098
0cce4aa1
DC
1099 /*
1100 * Automatic striding for high agcount filesystems.
1101 *
1102 * More AGs indicates that the filesystem is either large or can handle
1103 * more IO parallelism. Either way, we should try to process multiple
1104 * AGs at a time in such a configuration to try to saturate the
1105 * underlying storage and speed the repair process. Only do this if
1106 * prefetching is enabled.
1107 *
1108 * Given mkfs defaults for 16AGs for "multidisk" configurations, we want
1109 * to target these for an increase in thread count. Hence a stride value
1110 * of 15 is chosen to ensure we get at least 2 AGs being scanned at once
1111 * on such filesystems.
12b55baf
DC
1112 *
1113 * Limit the maximum thread count based on the available CPU power that
1114 * is available. If we use too many threads, we might run out of memory
1115 * and CPU power before we run out of IO concurrency. We limit to 8
1116 * threads/CPU as this is enough threads to saturate a CPU on fast
1117 * devices, yet few enough that it will saturate but won't overload slow
1118 * devices.
4a32b9e9
DC
1119 *
1120 * Multidisk filesystems can handle more IO parallelism so we should try
1121 * to process multiple AGs at a time in such a configuration to try to
1122 * saturate the underlying storage and speed the repair process. Only do
1123 * this if prefetching is enabled.
0cce4aa1 1124 */
4a32b9e9
DC
1125 if (!ag_stride && do_prefetch && is_multidisk_filesystem(mp)) {
1126 /*
1127 * For small agcount multidisk systems, just double the
1128 * parallelism. For larger AG count filesystems (32 and above)
1129 * use more parallelism, and linearly increase the parallelism
1130 * with the number of AGs.
1131 */
1132 ag_stride = min(glob_agcount, XFS_MULTIDISK_AGCOUNT / 2) - 1;
1133 }
0cce4aa1 1134
add3cb90 1135 if (ag_stride) {
12b55baf
DC
1136 int max_threads = platform_nproc() * 8;
1137
2556c98b 1138 thread_count = (glob_agcount + ag_stride - 1) / ag_stride;
12b55baf
DC
1139 while (thread_count > max_threads) {
1140 ag_stride *= 2;
1141 thread_count = (glob_agcount + ag_stride - 1) /
1142 ag_stride;
1143 }
1144 if (thread_count > 0)
1145 thread_init();
1146 else {
1147 thread_count = 1;
1148 ag_stride = 0;
1149 }
add3cb90
BN
1150 }
1151
2556c98b 1152 if (ag_stride && report_interval) {
06fbdda9 1153 init_progress_rpt();
06fbdda9
MV
1154 if (msgbuf) {
1155 do_log(_(" - reporting progress in intervals of %s\n"),
1156 duration(report_interval, msgbuf));
06fbdda9
MV
1157 }
1158 }
1159
2556c98b
BN
1160 /*
1161 * Adjust libxfs cache sizes based on system memory,
1162 * filesystem size and inode count.
1163 *
1164 * We'll set the cache size based on 3/4s the memory minus
1165 * space used by the inode AVL tree and block usage map.
1166 *
1167 * Inode AVL tree space is approximately 4 bytes per inode,
1168 * block usage map is currently 1 byte for 2 blocks.
1169 *
1170 * We assume most blocks will be inode clusters.
1171 *
1172 * Calculations are done in kilobyte units.
1173 */
1174
12be365e 1175 if (!bhash_option_used || max_mem_specified) {
2556c98b 1176 unsigned long mem_used;
12be365e
BN
1177 unsigned long max_mem;
1178 struct rlimit rlim;
2556c98b 1179
2556c98b 1180 libxfs_bcache_purge();
2556c98b
BN
1181 cache_destroy(libxfs_bcache);
1182
1183 mem_used = (mp->m_sb.sb_icount >> (10 - 2)) +
12be365e
BN
1184 (mp->m_sb.sb_dblocks >> (10 + 1)) +
1185 50000; /* rough estimate of 50MB overhead */
1186 max_mem = max_mem_specified ? max_mem_specified * 1024 :
4e5fe123 1187 platform_physmem() * 3 / 4;
12be365e
BN
1188
1189 if (getrlimit(RLIMIT_AS, &rlim) != -1 &&
1190 rlim.rlim_cur != RLIM_INFINITY) {
1191 rlim.rlim_cur = rlim.rlim_max;
1192 setrlimit(RLIMIT_AS, &rlim);
1193 /* use approximately 80% of rlimit to avoid overrun */
68d16907 1194 max_mem = min(max_mem, rlim.rlim_cur / 1280);
12be365e 1195 } else
68d16907 1196 max_mem = min(max_mem, (LONG_MAX >> 10) + 1);
2556c98b
BN
1197
1198 if (verbose > 1)
5d1b7f0f
CH
1199 do_log(
1200 _(" - max_mem = %lu, icount = %" PRIu64 ", imem = %" PRIu64 ", dblock = %" PRIu64 ", dmem = %" PRIu64 "\n"),
12be365e
BN
1201 max_mem, mp->m_sb.sb_icount,
1202 mp->m_sb.sb_icount >> (10 - 2),
1203 mp->m_sb.sb_dblocks,
1204 mp->m_sb.sb_dblocks >> (10 + 1));
1205
1206 if (max_mem <= mem_used) {
0335a835
DC
1207 if (max_mem_specified) {
1208 do_abort(
1209 _("Required memory for repair is greater that the maximum specified\n"
1210 "with the -m option. Please increase it to at least %lu.\n"),
12be365e 1211 mem_used / 1024);
0335a835 1212 }
70a4820f 1213 do_log(
61510437
DC
1214 _("Memory available for repair (%luMB) may not be sufficient.\n"
1215 "At least %luMB is needed to repair this filesystem efficiently\n"
1216 "If repair fails due to lack of memory, please\n"),
1217 max_mem / 1024, mem_used / 1024);
1218 if (do_prefetch)
70a4820f 1219 do_log(
61510437
DC
1220 _("turn prefetching off (-P) to reduce the memory footprint.\n"));
1221 else
70a4820f 1222 do_log(
61510437
DC
1223 _("increase system RAM and/or swap space to at least %luMB.\n"),
1224 mem_used * 2 / 1024);
1225
1226 max_mem = mem_used;
2556c98b
BN
1227 }
1228
61510437
DC
1229 max_mem -= mem_used;
1230 if (max_mem >= (1 << 30))
1231 max_mem = 1 << 30;
1232 libxfs_bhash_size = max_mem / (HASH_CACHE_RATIO *
e7fd2b6f 1233 (igeo->inode_cluster_size >> 10));
61510437
DC
1234 if (libxfs_bhash_size < 512)
1235 libxfs_bhash_size = 512;
1236
2556c98b
BN
1237 if (verbose)
1238 do_log(_(" - block cache size set to %d entries\n"),
1239 libxfs_bhash_size * HASH_CACHE_RATIO);
1240
ba9ecd40 1241 libxfs_bcache = cache_init(0, libxfs_bhash_size,
2556c98b
BN
1242 &libxfs_bcache_operations);
1243 }
1244
2bd0ea18
NS
1245 /*
1246 * calculate what mkfs would do to this filesystem
1247 */
1248 calc_mkfs(mp);
1249
1250 /*
c1f7a46c 1251 * initialize block alloc map
2bd0ea18 1252 */
c1f7a46c
BN
1253 init_bmaps(mp);
1254 incore_ino_init(mp);
1255 incore_ext_init(mp);
2d273771 1256 rmaps_init(mp);
c1f7a46c
BN
1257
1258 /* initialize random globals now that we know the fs geometry */
1259 inodes_per_block = mp->m_sb.sb_inopblock;
2bd0ea18 1260
575f24e5 1261 if (parse_sb_version(mp)) {
2bd0ea18 1262 do_warn(
507f4e33 1263 _("Found unsupported filesystem features. Exiting now.\n"));
2bd0ea18
NS
1264 return(1);
1265 }
1266
1267 /* make sure the per-ag freespace maps are ok so we can mount the fs */
364a126c 1268 phase2(mp, phase2_threads);
8e9f22d6 1269 phase_end(2);
2bd0ea18 1270
2556c98b
BN
1271 if (do_prefetch)
1272 init_prefetch(mp);
1273
8100dd79 1274 phase3(mp, phase2_threads);
8e9f22d6 1275 phase_end(3);
2bd0ea18
NS
1276
1277 phase4(mp);
8e9f22d6 1278 phase_end(4);
2bd0ea18 1279
f2e38861 1280 if (no_modify) {
507f4e33 1281 printf(_("No modify flag set, skipping phase 5\n"));
f2e38861
DW
1282
1283 if (mp->m_sb.sb_rblocks > 0)
1284 check_rtmetadata(mp);
1285 } else {
2bd0ea18 1286 phase5(mp);
3b6ac903 1287 }
8e9f22d6 1288 phase_end(5);
2bd0ea18 1289
c1f7a46c
BN
1290 /*
1291 * Done with the block usage maps, toss them...
1292 */
2d273771 1293 rmaps_free(mp);
c1f7a46c
BN
1294 free_bmaps(mp);
1295
2bd0ea18
NS
1296 if (!bad_ino_btree) {
1297 phase6(mp);
8e9f22d6 1298 phase_end(6);
2bd0ea18 1299
e161d4a8 1300 phase7(mp, phase2_threads);
8e9f22d6 1301 phase_end(7);
2bd0ea18
NS
1302 } else {
1303 do_warn(
507f4e33 1304_("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
2bd0ea18
NS
1305 }
1306
0340d706 1307 if (lost_quotas && !have_uquotino && !have_gquotino && !have_pquotino) {
2bd0ea18
NS
1308 if (!no_modify) {
1309 do_warn(
507f4e33 1310_("Warning: no quota inodes were found. Quotas disabled.\n"));
2bd0ea18
NS
1311 } else {
1312 do_warn(
507f4e33 1313_("Warning: no quota inodes were found. Quotas would be disabled.\n"));
2bd0ea18
NS
1314 }
1315 } else if (lost_quotas) {
1316 if (!no_modify) {
1317 do_warn(
507f4e33 1318_("Warning: quota inodes were cleared. Quotas disabled.\n"));
2bd0ea18
NS
1319 } else {
1320 do_warn(
507f4e33 1321_("Warning: quota inodes would be cleared. Quotas would be disabled.\n"));
2bd0ea18
NS
1322 }
1323 } else {
1324 if (lost_uquotino) {
1325 if (!no_modify) {
1326 do_warn(
507f4e33
NS
1327_("Warning: user quota information was cleared.\n"
1328 "User quotas can not be enforced until limit information is recreated.\n"));
2bd0ea18
NS
1329 } else {
1330 do_warn(
507f4e33
NS
1331_("Warning: user quota information would be cleared.\n"
1332 "User quotas could not be enforced until limit information was recreated.\n"));
2bd0ea18
NS
1333 }
1334 }
1335
b36eef04 1336 if (lost_gquotino) {
2bd0ea18
NS
1337 if (!no_modify) {
1338 do_warn(
507f4e33
NS
1339_("Warning: group quota information was cleared.\n"
1340 "Group quotas can not be enforced until limit information is recreated.\n"));
2bd0ea18
NS
1341 } else {
1342 do_warn(
507f4e33
NS
1343_("Warning: group quota information would be cleared.\n"
1344 "Group quotas could not be enforced until limit information was recreated.\n"));
9b27bdbb
NS
1345 }
1346 }
1347
1348 if (lost_pquotino) {
1349 if (!no_modify) {
1350 do_warn(
1351_("Warning: project quota information was cleared.\n"
1352 "Project quotas can not be enforced until limit information is recreated.\n"));
1353 } else {
1354 do_warn(
1355_("Warning: project quota information would be cleared.\n"
1356 "Project quotas could not be enforced until limit information was recreated.\n"));
2bd0ea18
NS
1357 }
1358 }
1359 }
1360
2556c98b 1361 if (ag_stride && report_interval)
06fbdda9 1362 stop_progress_rpt();
9f38f08d 1363
2bd0ea18 1364 if (no_modify) {
1926558d
BF
1365 /*
1366 * Warn if the current LSN is problematic and the log requires a
1367 * reformat.
1368 */
1369 format_log_max_lsn(mp);
1370
2bd0ea18 1371 do_log(
507f4e33 1372 _("No modify flag set, skipping filesystem flush and exiting.\n"));
3b6ac903 1373 if (verbose)
06fbdda9 1374 summary_report();
2bd0ea18
NS
1375 if (fs_is_dirty)
1376 return(1);
1377
1378 return(0);
1379 }
1380
1381 /*
1382 * Clear the quota flags if they're on.
1383 */
67c4a324 1384 sbp = libxfs_getsb(mp);
2bd0ea18 1385 if (!sbp)
507f4e33 1386 do_error(_("couldn't get superblock\n"));
2bd0ea18 1387
91a52fbc 1388 if ((mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD) != quotacheck_results()) {
5e656dbb
BN
1389 do_warn(_("Note - quota info will be regenerated on next "
1390 "quota mount.\n"));
bbe6680f
DW
1391 mp->m_sb.sb_qflags &= ~(XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD |
1392 XFS_PQUOTA_CHKD | XFS_OQUOTA_CHKD);
1393 libxfs_sb_to_disk(sbp->b_addr, &mp->m_sb);
2bd0ea18
NS
1394 }
1395
6bf4721d 1396 if (copied_sunit) {
2bd0ea18 1397 do_warn(
6bf4721d
ES
1398_("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\n"
1399 "Please reset with mount -o sunit=<value>,swidth=<value> if necessary\n"),
bbe6680f 1400 mp->m_sb.sb_unit, mp->m_sb.sb_width);
dfc130f3 1401 }
2bd0ea18 1402
f524ae04 1403 libxfs_buf_mark_dirty(sbp);
18b4f688 1404 libxfs_buf_relse(sbp);
2bd0ea18 1405
68fb1399
DW
1406 /*
1407 * If we upgraded V5 filesystem features, we need to update the
1408 * secondary superblocks to include the new feature bits. Don't set
1409 * NEEDSREPAIR on the secondaries.
1410 */
1411 if (features_changed) {
1412 mp->m_sb.sb_features_incompat &=
1413 ~XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
1414 error = -libxfs_update_secondary_sbs(mp);
1415 if (error)
1416 do_error(_("upgrading features of secondary supers"));
1417 mp->m_sb.sb_features_incompat |=
1418 XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR;
1419 }
1420
2556c98b 1421 /*
1926558d
BF
1422 * Done. Flush all cached buffers and inodes first to ensure all
1423 * verifiers are run (where we discover the max metadata LSN), reformat
1424 * the log if necessary and unmount.
2556c98b
BN
1425 */
1426 libxfs_bcache_flush();
1926558d 1427 format_log_max_lsn(mp);
14fb3613 1428
a7348c58
DW
1429 if (xfs_sb_version_needsrepair(&mp->m_sb))
1430 clear_needsrepair(mp);
1431
14fb3613
DW
1432 /* Report failure if anything failed to get written to our fs. */
1433 error = -libxfs_umount(mp);
1434 if (error)
1435 do_error(
1acabf90 1436 _("File system metadata writeout failed, err=%d. Re-run xfs_repair.\n"),
14fb3613 1437 error);
1926558d 1438
a9468486 1439 libxfs_destroy(&x);
2bd0ea18 1440
06fbdda9
MV
1441 if (verbose)
1442 summary_report();
507f4e33 1443 do_log(_("done\n"));
3ae81520
ES
1444
1445 if (dangerously && !no_modify)
1446 do_warn(
1447_("Repair of readonly mount complete. Immediate reboot encouraged.\n"));
1448
4c0a98ae
BN
1449 pftrace_done();
1450
0a223eb8
ES
1451 free(msgbuf);
1452
7c3e94a3
JT
1453 if (fs_is_dirty && report_corrected)
1454 return (4);
3b6ac903
MV
1455 return (0);
1456}