]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - repair/xfs_repair.c
xfsprogs: use <>-style includes in installed headers
[thirdparty/xfsprogs-dev.git] / repair / xfs_repair.c
CommitLineData
2bd0ea18 1/*
da23017d
NS
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
dfc130f3 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
2bd0ea18 7 * published by the Free Software Foundation.
dfc130f3 8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
dfc130f3 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2bd0ea18
NS
17 */
18
b08338d7 19#include "xfs/libxfs.h"
e708d0fa 20#include "xfs/libxlog.h"
12be365e 21#include <sys/resource.h>
2bd0ea18
NS
22#include "avl.h"
23#include "avl64.h"
24#include "globals.h"
25#include "versions.h"
26#include "agheader.h"
27#include "protos.h"
28#include "incore.h"
29#include "err_protos.h"
cb5b3ef4 30#include "prefetch.h"
3b6ac903 31#include "threads.h"
06fbdda9 32#include "progress.h"
beed0dc8 33#include "dinode.h"
2bd0ea18
NS
34
35#define rounddown(x, y) (((x)/(y))*(y))
36
2bd0ea18
NS
37#define XR_MAX_SECT_SIZE (64 * 1024)
38
39/*
40 * option tables for getsubopt calls
41 */
42
43/*
4af916f8 44 * -o: user-supplied override options
2bd0ea18 45 */
8b8a6b02 46static char *o_opts[] = {
2bd0ea18
NS
47#define ASSUME_XFS 0
48 "assume_xfs",
49#define PRE_65_BETA 1
50 "fs_is_pre_65_beta",
9f38f08d
MV
51#define IHASH_SIZE 2
52 "ihash",
53#define BHASH_SIZE 3
54 "bhash",
2556c98b 55#define AG_STRIDE 4
add3cb90 56 "ag_stride",
d4dd6ab5
CH
57#define FORCE_GEO 5
58 "force_geometry",
364a126c
DC
59#define PHASE2_THREADS 6
60 "phase2_threads",
2bd0ea18
NS
61 NULL
62};
63
4af916f8
BN
64/*
65 * -c: conversion options
66 */
8b8a6b02 67static char *c_opts[] = {
4af916f8
BN
68#define CONVERT_LAZY_COUNT 0
69 "lazycount",
70 NULL
71};
72
73
2556c98b 74static int bhash_option_used;
12be365e 75static long max_mem_specified; /* in megabytes */
364a126c 76static int phase2_threads = 32;
2556c98b 77
2bd0ea18
NS
78static void
79usage(void)
80{
4af916f8
BN
81 do_warn(_(
82"Usage: %s [options] device\n"
83"\n"
84"Options:\n"
85" -f The device is a file\n"
86" -L Force log zeroing. Do this as a last resort.\n"
87" -l logdev Specifies the device where the external log resides.\n"
88" -m maxmem Maximum amount of memory to be used in megabytes.\n"
89" -n No modify mode, just checks the filesystem for damage.\n"
90" -P Disables prefetching.\n"
91" -r rtdev Specifies the device where the realtime section resides.\n"
92" -v Verbose output.\n"
93" -c subopts Change filesystem parameters - use xfs_admin.\n"
94" -o subopts Override default behaviour, refer to man page.\n"
79e106f0 95" -t interval Reporting interval in seconds.\n"
4af916f8
BN
96" -d Repair dangerously.\n"
97" -V Reports version and exits.\n"), progname);
2bd0ea18
NS
98 exit(1);
99}
100
2bd0ea18
NS
101char *
102err_string(int err_code)
103{
507f4e33
NS
104 static char *err_message[XR_BAD_ERR_CODE];
105 static int done;
106
107 if (!done) {
108 err_message[XR_OK] = _("no error");
109 err_message[XR_BAD_MAGIC] = _("bad magic number");
110 err_message[XR_BAD_BLOCKSIZE] = _("bad blocksize field");
111 err_message[XR_BAD_BLOCKLOG] = _("bad blocksize log field");
4af916f8 112 err_message[XR_BAD_VERSION] = _("bad or unsupported version");
507f4e33
NS
113 err_message[XR_BAD_INPROGRESS] =
114 _("filesystem mkfs-in-progress bit set");
115 err_message[XR_BAD_FS_SIZE_DATA] =
116 _("inconsistent filesystem geometry information");
117 err_message[XR_BAD_INO_SIZE_DATA] =
118 _("bad inode size or inconsistent with number of inodes/block"),
119 err_message[XR_BAD_SECT_SIZE_DATA] = _("bad sector size");
120 err_message[XR_AGF_GEO_MISMATCH] =
121 _("AGF geometry info conflicts with filesystem geometry");
122 err_message[XR_AGI_GEO_MISMATCH] =
123 _("AGI geometry info conflicts with filesystem geometry");
124 err_message[XR_SB_GEO_MISMATCH] =
125 _("AG superblock geometry info conflicts with filesystem geometry");
126 err_message[XR_EOF] = _("attempted to perform I/O beyond EOF");
127 err_message[XR_BAD_RT_GEO_DATA] =
128 _("inconsistent filesystem geometry in realtime filesystem component");
129 err_message[XR_BAD_INO_MAX_PCT] =
130 _("maximum indicated percentage of inodes > 100%");
131 err_message[XR_BAD_INO_ALIGN] =
132 _("inconsistent inode alignment value");
133 err_message[XR_INSUFF_SEC_SB] =
134 _("not enough secondary superblocks with matching geometry");
135 err_message[XR_BAD_SB_UNIT] =
136 _("bad stripe unit in superblock");
137 err_message[XR_BAD_SB_WIDTH] =
138 _("bad stripe width in superblock");
139 err_message[XR_BAD_SVN] =
140 _("bad shared version number in superblock");
88f364a9
DC
141 err_message[XR_BAD_CRC] =
142 _("bad CRC in superblock");
507f4e33
NS
143 done = 1;
144 }
145
2bd0ea18 146 if (err_code < XR_OK || err_code >= XR_BAD_ERR_CODE)
507f4e33 147 do_abort(_("bad error code - %d\n"), err_code);
2bd0ea18
NS
148
149 return(err_message[err_code]);
150}
151
152static void
153noval(char opt, char *tbl[], int idx)
154{
507f4e33 155 do_warn(_("-%c %s option cannot have a value\n"), opt, tbl[idx]);
2bd0ea18
NS
156 usage();
157}
158
159static void
160respec(char opt, char *tbl[], int idx)
161{
162 do_warn("-%c ", opt);
163 if (tbl)
164 do_warn("%s ", tbl[idx]);
507f4e33 165 do_warn(_("option respecified\n"));
2bd0ea18
NS
166 usage();
167}
168
169static void
170unknown(char opt, char *s)
171{
507f4e33 172 do_warn(_("unknown option -%c %s\n"), opt, s);
2bd0ea18
NS
173 usage();
174}
175
176/*
177 * sets only the global argument flags and variables
178 */
8b8a6b02 179static void
2bd0ea18
NS
180process_args(int argc, char **argv)
181{
182 char *p;
183 int c;
184
185 log_spec = 0;
186 fs_is_dirty = 0;
187 verbose = 0;
188 no_modify = 0;
c781939c 189 dangerously = 0;
2bd0ea18 190 isa_file = 0;
d321ceac 191 zap_log = 0;
2bd0ea18 192 dumpcore = 0;
0f012a4c 193 full_ino_ex_data = 0;
2bd0ea18
NS
194 delete_attr_ok = 1;
195 force_geo = 0;
196 assume_xfs = 0;
6bf4721d 197 copied_sunit = 0;
2bd0ea18
NS
198 sb_inoalignmt = 0;
199 sb_unit = 0;
200 sb_width = 0;
201 fs_attributes_allowed = 1;
9b1d68ec 202 fs_attributes2_allowed = 1;
2bd0ea18
NS
203 fs_quotas_allowed = 1;
204 fs_aligned_inodes_allowed = 1;
205 fs_sb_feature_bits_allowed = 1;
206 fs_has_extflgbit_allowed = 1;
207 pre_65_beta = 0;
208 fs_shared_allowed = 1;
add3cb90 209 ag_stride = 0;
2556c98b 210 thread_count = 1;
06fbdda9 211 report_interval = PROG_RPT_DEFAULT;
2bd0ea18
NS
212
213 /*
214 * XXX have to add suboption processing here
215 * attributes, quotas, nlinks, aligned_inos, sb_fbits
216 */
4af916f8 217 while ((c = getopt(argc, argv, "c:o:fl:m:r:LnDvVdPt:")) != EOF) {
2bd0ea18
NS
218 switch (c) {
219 case 'D':
220 dumpcore = 1;
221 break;
222 case 'o':
223 p = optarg;
224 while (*p != '\0') {
225 char *val;
226
227 switch (getsubopt(&p, (constpp)o_opts, &val)) {
228 case ASSUME_XFS:
229 if (val)
230 noval('o', o_opts, ASSUME_XFS);
231 if (assume_xfs)
232 respec('o', o_opts, ASSUME_XFS);
233 assume_xfs = 1;
234 break;
235 case PRE_65_BETA:
236 if (val)
237 noval('o', o_opts, PRE_65_BETA);
238 if (pre_65_beta)
239 respec('o', o_opts,
240 PRE_65_BETA);
241 pre_65_beta = 1;
242 break;
9f38f08d 243 case IHASH_SIZE:
3a19fb7d
CH
244 do_warn(
245 _("-o ihash option has been removed and will be ignored\n"));
9f38f08d
MV
246 break;
247 case BHASH_SIZE:
12be365e
BN
248 if (max_mem_specified)
249 do_abort(
3a19fb7d 250 _("-o bhash option cannot be used with -m option\n"));
5e656dbb 251 libxfs_bhash_size = (int)strtol(val, NULL, 0);
2556c98b 252 bhash_option_used = 1;
cb5b3ef4 253 break;
add3cb90 254 case AG_STRIDE:
5e656dbb 255 ag_stride = (int)strtol(val, NULL, 0);
3b6ac903 256 break;
d4dd6ab5
CH
257 case FORCE_GEO:
258 if (val)
259 noval('o', o_opts, FORCE_GEO);
260 if (force_geo)
261 respec('o', o_opts, FORCE_GEO);
262 force_geo = 1;
263 break;
364a126c
DC
264 case PHASE2_THREADS:
265 phase2_threads = (int)strtol(val, NULL, 0);
266 break;
2bd0ea18
NS
267 default:
268 unknown('o', val);
269 break;
270 }
271 }
272 break;
4af916f8
BN
273 case 'c':
274 p = optarg;
275 while (*p) {
276 char *val;
277
278 switch (getsubopt(&p, (constpp)c_opts, &val)) {
279 case CONVERT_LAZY_COUNT:
5e656dbb 280 lazy_count = (int)strtol(val, NULL, 0);
4af916f8
BN
281 convert_lazy_count = 1;
282 break;
283 default:
284 unknown('c', val);
285 break;
286 }
287 }
288 break;
2bd0ea18
NS
289 case 'l':
290 log_name = optarg;
291 log_spec = 1;
292 break;
42a564ab
ES
293 case 'r':
294 rt_name = optarg;
295 rt_spec = 1;
296 break;
2bd0ea18
NS
297 case 'f':
298 isa_file = 1;
299 break;
12be365e
BN
300 case 'm':
301 if (bhash_option_used)
302 do_abort(_("-m option cannot be used with "
303 "-o bhash option\n"));
5e656dbb 304 max_mem_specified = strtol(optarg, NULL, 0);
12be365e 305 break;
d321ceac
NS
306 case 'L':
307 zap_log = 1;
308 break;
2bd0ea18
NS
309 case 'n':
310 no_modify = 1;
311 break;
6089b6f0
NS
312 case 'd':
313 dangerously = 1;
314 break;
2bd0ea18 315 case 'v':
3b6ac903 316 verbose++;
2bd0ea18
NS
317 break;
318 case 'V':
507f4e33 319 printf(_("%s version %s\n"), progname, VERSION);
3d98fe63 320 exit(0);
cb5b3ef4 321 case 'P':
2556c98b 322 do_prefetch = 0;
3b6ac903 323 break;
06fbdda9 324 case 't':
5e656dbb 325 report_interval = (int)strtol(optarg, NULL, 0);
06fbdda9 326 break;
2bd0ea18
NS
327 case '?':
328 usage();
329 }
330 }
331
332 if (argc - optind != 1)
333 usage();
334
335 if ((fs_name = argv[optind]) == NULL)
336 usage();
337}
338
b1559967 339void __attribute__((noreturn))
2bd0ea18
NS
340do_error(char const *msg, ...)
341{
342 va_list args;
343
507f4e33 344 fprintf(stderr, _("\nfatal error -- "));
2bd0ea18
NS
345
346 va_start(args, msg);
079afa09
CH
347 vfprintf(stderr, msg, args);
348 if (dumpcore)
349 abort();
350 exit(1);
2bd0ea18
NS
351}
352
353/*
354 * like do_error, only the error is internal, no system
355 * error so no oserror processing
356 */
b1559967 357void __attribute__((noreturn))
2bd0ea18
NS
358do_abort(char const *msg, ...)
359{
360 va_list args;
361
362 va_start(args, msg);
079afa09
CH
363 vfprintf(stderr, msg, args);
364 if (dumpcore)
365 abort();
366 exit(1);
2bd0ea18
NS
367}
368
369void
370do_warn(char const *msg, ...)
371{
372 va_list args;
373
374 fs_is_dirty = 1;
375
376 va_start(args, msg);
079afa09 377 vfprintf(stderr, msg, args);
2bd0ea18
NS
378 va_end(args);
379}
380
381/* no formatting */
382
383void
384do_log(char const *msg, ...)
385{
386 va_list args;
387
388 va_start(args, msg);
079afa09 389 vfprintf(stderr, msg, args);
2bd0ea18
NS
390 va_end(args);
391}
392
8b8a6b02 393static void
2bd0ea18
NS
394calc_mkfs(xfs_mount_t *mp)
395{
396 xfs_agblock_t fino_bno;
397 int do_inoalign;
398
399 do_inoalign = mp->m_sinoalign;
400
401 /*
7b370905
BF
402 * Pre-calculate the geometry of ag 0. We know what it looks like
403 * because we know what mkfs does: 2 allocation btree roots (by block
404 * and by size), the inode allocation btree root, the free inode
405 * allocation btree root (if enabled) and some number of blocks to
406 * prefill the agfl.
de046644
DC
407 *
408 * Because the current shape of the btrees may differ from the current
409 * shape, we open code the mkfs freelist block count here. mkfs creates
410 * single level trees, so the calculation is pertty straight forward for
411 * the two trees that use the AGFL.
2bd0ea18
NS
412 */
413 bnobt_root = howmany(4 * mp->m_sb.sb_sectsize, mp->m_sb.sb_blocksize);
414 bcntbt_root = bnobt_root + 1;
415 inobt_root = bnobt_root + 2;
de046644 416 fino_bno = inobt_root + (2 * min(2, mp->m_ag_maxlevels)) + 1;
7b370905
BF
417 if (xfs_sb_version_hasfinobt(&mp->m_sb))
418 fino_bno++;
2bd0ea18 419
d4dd6ab5 420 /*
649bfa9a
CH
421 * If the log is allocated in the first allocation group we need to
422 * add the number of blocks used by the log to the above calculation.
423 *
424 * This can happens with filesystems that only have a single
425 * allocation group, or very odd geometries created by old mkfs
426 * versions on very small filesystems.
d4dd6ab5 427 */
649bfa9a
CH
428 if (mp->m_sb.sb_logstart &&
429 XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == 0) {
430
d4dd6ab5
CH
431 /*
432 * XXX(hch): verify that sb_logstart makes sense?
433 */
434 fino_bno += mp->m_sb.sb_logblocks;
435 }
436
2bd0ea18
NS
437 /*
438 * ditto the location of the first inode chunks in the fs ('/')
439 */
5e656dbb 440 if (xfs_sb_version_hasdalign(&mp->m_sb) && do_inoalign) {
2bd0ea18
NS
441 first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, roundup(fino_bno,
442 mp->m_sb.sb_unit), 0);
5e656dbb 443 } else if (xfs_sb_version_hasalign(&mp->m_sb) &&
2bd0ea18
NS
444 mp->m_sb.sb_inoalignmt > 1) {
445 first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp,
446 roundup(fino_bno,
447 mp->m_sb.sb_inoalignmt),
448 0);
449 } else {
450 first_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, fino_bno, 0);
451 }
452
ff105f75 453 ASSERT(mp->m_ialloc_blks > 0);
2bd0ea18 454
ff105f75 455 if (mp->m_ialloc_blks > 1)
2bd0ea18
NS
456 last_prealloc_ino = first_prealloc_ino + XFS_INODES_PER_CHUNK;
457 else
458 last_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, fino_bno + 1, 0);
459
460 /*
461 * now the first 3 inodes in the system
462 */
463 if (mp->m_sb.sb_rootino != first_prealloc_ino) {
464 do_warn(
5d1b7f0f 465_("sb root inode value %" PRIu64 " %sinconsistent with calculated value %u\n"),
507f4e33
NS
466 mp->m_sb.sb_rootino,
467 (mp->m_sb.sb_rootino == NULLFSINO ? "(NULLFSINO) ":""),
468 first_prealloc_ino);
2bd0ea18
NS
469
470 if (!no_modify)
471 do_warn(
5d1b7f0f 472 _("resetting superblock root inode pointer to %u\n"),
2bd0ea18
NS
473 first_prealloc_ino);
474 else
475 do_warn(
5d1b7f0f 476 _("would reset superblock root inode pointer to %u\n"),
2bd0ea18
NS
477 first_prealloc_ino);
478
479 /*
480 * just set the value -- safe since the superblock
481 * doesn't get flushed out if no_modify is set
482 */
483 mp->m_sb.sb_rootino = first_prealloc_ino;
484 }
485
486 if (mp->m_sb.sb_rbmino != first_prealloc_ino + 1) {
487 do_warn(
5d1b7f0f 488_("sb realtime bitmap inode %" PRIu64 " %sinconsistent with calculated value %u\n"),
507f4e33
NS
489 mp->m_sb.sb_rbmino,
490 (mp->m_sb.sb_rbmino == NULLFSINO ? "(NULLFSINO) ":""),
491 first_prealloc_ino + 1);
2bd0ea18
NS
492
493 if (!no_modify)
494 do_warn(
5d1b7f0f 495 _("resetting superblock realtime bitmap ino pointer to %u\n"),
2bd0ea18
NS
496 first_prealloc_ino + 1);
497 else
498 do_warn(
5d1b7f0f 499 _("would reset superblock realtime bitmap ino pointer to %u\n"),
2bd0ea18
NS
500 first_prealloc_ino + 1);
501
502 /*
503 * just set the value -- safe since the superblock
504 * doesn't get flushed out if no_modify is set
505 */
506 mp->m_sb.sb_rbmino = first_prealloc_ino + 1;
507 }
508
509 if (mp->m_sb.sb_rsumino != first_prealloc_ino + 2) {
510 do_warn(
5d1b7f0f
CH
511_("sb realtime summary inode %" PRIu64 " %sinconsistent with calculated value %u\n"),
512 mp->m_sb.sb_rsumino,
513 (mp->m_sb.sb_rsumino == NULLFSINO ? "(NULLFSINO) ":""),
514 first_prealloc_ino + 2);
2bd0ea18
NS
515
516 if (!no_modify)
517 do_warn(
5d1b7f0f 518 _("resetting superblock realtime summary ino pointer to %u\n"),
2bd0ea18
NS
519 first_prealloc_ino + 2);
520 else
521 do_warn(
5d1b7f0f 522 _("would reset superblock realtime summary ino pointer to %u\n"),
2bd0ea18
NS
523 first_prealloc_ino + 2);
524
525 /*
526 * just set the value -- safe since the superblock
527 * doesn't get flushed out if no_modify is set
528 */
529 mp->m_sb.sb_rsumino = first_prealloc_ino + 2;
530 }
531
532}
533
534int
535main(int argc, char **argv)
536{
2bd0ea18
NS
537 xfs_mount_t *temp_mp;
538 xfs_mount_t *mp;
5e656dbb 539 xfs_dsb_t *dsb;
2bd0ea18
NS
540 xfs_buf_t *sbp;
541 xfs_mount_t xfs_m;
06fbdda9 542 char *msgbuf;
88f364a9
DC
543 struct xfs_sb psb;
544 int rval;
2bd0ea18
NS
545
546 progname = basename(argv[0]);
507f4e33
NS
547 setlocale(LC_ALL, "");
548 bindtextdomain(PACKAGE, LOCALEDIR);
549 textdomain(PACKAGE);
beed0dc8 550 dinode_bmbt_translation_init();
2bd0ea18
NS
551
552 temp_mp = &xfs_m;
553 setbuf(stdout, NULL);
554
555 process_args(argc, argv);
d321ceac 556 xfs_init(&x);
2bd0ea18 557
2556c98b
BN
558 msgbuf = malloc(DURATION_BUF_SIZE);
559
06fbdda9
MV
560 timestamp(PHASE_START, 0, NULL);
561 timestamp(PHASE_END, 0, NULL);
562
2bd0ea18
NS
563 /* do phase1 to make sure we have a superblock */
564 phase1(temp_mp);
06fbdda9 565 timestamp(PHASE_END, 1, NULL);
2bd0ea18
NS
566
567 if (no_modify && primary_sb_modified) {
507f4e33
NS
568 do_warn(_("Primary superblock would have been modified.\n"
569 "Cannot proceed further in no_modify mode.\n"
570 "Exiting now.\n"));
2bd0ea18
NS
571 exit(1);
572 }
573
88f364a9
DC
574 rval = get_sb(&psb, 0, XFS_MAX_SECTORSIZE, 0);
575 if (rval != XR_OK) {
576 do_warn(_("Primary superblock bad after phase 1!\n"
577 "Exiting now.\n"));
578 exit(1);
579 }
2bd0ea18 580
76de6bb7
ES
581 /* -f forces this, but let's be nice and autodetect it, as well. */
582 if (!isa_file) {
583 int fd = libxfs_device_to_fd(x.ddev);
584 struct stat64 statbuf;
585
586 if (fstat64(fd, &statbuf) < 0)
587 do_warn(_("%s: couldn't stat \"%s\"\n"),
588 progname, fs_name);
589 else if (S_ISREG(statbuf.st_mode))
590 isa_file = 1;
591 }
592
f63fd268
DC
593 /*
594 * if the sector size of the filesystem we are trying to repair is
595 * smaller than that of the underlying filesystem (i.e. we are repairing
596 * an image), the we have to turn off direct IO because we cannot do IO
597 * smaller than the host filesystem's sector size.
598 */
599 if (isa_file) {
600 int fd = libxfs_device_to_fd(x.ddev);
601 struct xfs_fsop_geom_v1 geom = { 0 };
602
603 if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) {
604 do_warn(_("Cannot get host filesystem geometry.\n"
605 "Repair may fail if there is a sector size mismatch between\n"
606 "the image and the host filesystem.\n"));
607 geom.sectsize = BBSIZE;
608 }
609
88f364a9 610 if (psb.sb_sectsize < geom.sectsize) {
f63fd268
DC
611 long old_flags;
612
613 old_flags = fcntl(fd, F_GETFL, 0);
614 if (fcntl(fd, F_SETFL, old_flags & ~O_DIRECT) < 0) {
615 do_warn(_(
616 "Sector size on host filesystem larger than image sector size.\n"
617 "Cannot turn off direct IO, so exiting.\n"));
618 exit(1);
619 }
620 }
621 }
88f364a9
DC
622
623 /* prepare the mount structure */
624 memset(&xfs_m, 0, sizeof(xfs_mount_t));
625 mp = libxfs_mount(&xfs_m, &psb, x.ddev, x.logdev, x.rtdev, 0);
2bd0ea18
NS
626
627 if (!mp) {
507f4e33
NS
628 fprintf(stderr,
629 _("%s: cannot repair this filesystem. Sorry.\n"),
2bd0ea18
NS
630 progname);
631 exit(1);
632 }
2bd0ea18
NS
633
634 /*
635 * set XFS-independent status vars from the mount/sb structure
636 */
637 glob_agcount = mp->m_sb.sb_agcount;
638
639 chunks_pblock = mp->m_sb.sb_inopblock / XFS_INODES_PER_CHUNK;
e0607266 640 max_symlink_blocks = libxfs_symlink_blocks(mp, MAXPATHLEN);
edf3f9d0 641 inodes_per_cluster = MAX(mp->m_sb.sb_inopblock,
ff105f75 642 mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog);
2bd0ea18 643
0cce4aa1
DC
644 /*
645 * Automatic striding for high agcount filesystems.
646 *
647 * More AGs indicates that the filesystem is either large or can handle
648 * more IO parallelism. Either way, we should try to process multiple
649 * AGs at a time in such a configuration to try to saturate the
650 * underlying storage and speed the repair process. Only do this if
651 * prefetching is enabled.
652 *
653 * Given mkfs defaults for 16AGs for "multidisk" configurations, we want
654 * to target these for an increase in thread count. Hence a stride value
655 * of 15 is chosen to ensure we get at least 2 AGs being scanned at once
656 * on such filesystems.
12b55baf
DC
657 *
658 * Limit the maximum thread count based on the available CPU power that
659 * is available. If we use too many threads, we might run out of memory
660 * and CPU power before we run out of IO concurrency. We limit to 8
661 * threads/CPU as this is enough threads to saturate a CPU on fast
662 * devices, yet few enough that it will saturate but won't overload slow
663 * devices.
0cce4aa1
DC
664 */
665 if (!ag_stride && glob_agcount >= 16 && do_prefetch)
666 ag_stride = 15;
667
add3cb90 668 if (ag_stride) {
12b55baf
DC
669 int max_threads = platform_nproc() * 8;
670
2556c98b 671 thread_count = (glob_agcount + ag_stride - 1) / ag_stride;
12b55baf
DC
672 while (thread_count > max_threads) {
673 ag_stride *= 2;
674 thread_count = (glob_agcount + ag_stride - 1) /
675 ag_stride;
676 }
677 if (thread_count > 0)
678 thread_init();
679 else {
680 thread_count = 1;
681 ag_stride = 0;
682 }
add3cb90
BN
683 }
684
2556c98b 685 if (ag_stride && report_interval) {
06fbdda9 686 init_progress_rpt();
06fbdda9
MV
687 if (msgbuf) {
688 do_log(_(" - reporting progress in intervals of %s\n"),
689 duration(report_interval, msgbuf));
06fbdda9
MV
690 }
691 }
692
2556c98b
BN
693 /*
694 * Adjust libxfs cache sizes based on system memory,
695 * filesystem size and inode count.
696 *
697 * We'll set the cache size based on 3/4s the memory minus
698 * space used by the inode AVL tree and block usage map.
699 *
700 * Inode AVL tree space is approximately 4 bytes per inode,
701 * block usage map is currently 1 byte for 2 blocks.
702 *
703 * We assume most blocks will be inode clusters.
704 *
705 * Calculations are done in kilobyte units.
706 */
707
12be365e 708 if (!bhash_option_used || max_mem_specified) {
2556c98b 709 unsigned long mem_used;
12be365e
BN
710 unsigned long max_mem;
711 struct rlimit rlim;
2556c98b 712
2556c98b 713 libxfs_bcache_purge();
2556c98b
BN
714 cache_destroy(libxfs_bcache);
715
716 mem_used = (mp->m_sb.sb_icount >> (10 - 2)) +
12be365e
BN
717 (mp->m_sb.sb_dblocks >> (10 + 1)) +
718 50000; /* rough estimate of 50MB overhead */
719 max_mem = max_mem_specified ? max_mem_specified * 1024 :
720 libxfs_physmem() * 3 / 4;
721
722 if (getrlimit(RLIMIT_AS, &rlim) != -1 &&
723 rlim.rlim_cur != RLIM_INFINITY) {
724 rlim.rlim_cur = rlim.rlim_max;
725 setrlimit(RLIMIT_AS, &rlim);
726 /* use approximately 80% of rlimit to avoid overrun */
727 max_mem = MIN(max_mem, rlim.rlim_cur / 1280);
728 } else
729 max_mem = MIN(max_mem, (LONG_MAX >> 10) + 1);
2556c98b
BN
730
731 if (verbose > 1)
5d1b7f0f
CH
732 do_log(
733 _(" - max_mem = %lu, icount = %" PRIu64 ", imem = %" PRIu64 ", dblock = %" PRIu64 ", dmem = %" PRIu64 "\n"),
12be365e
BN
734 max_mem, mp->m_sb.sb_icount,
735 mp->m_sb.sb_icount >> (10 - 2),
736 mp->m_sb.sb_dblocks,
737 mp->m_sb.sb_dblocks >> (10 + 1));
738
739 if (max_mem <= mem_used) {
0335a835
DC
740 if (max_mem_specified) {
741 do_abort(
742 _("Required memory for repair is greater that the maximum specified\n"
743 "with the -m option. Please increase it to at least %lu.\n"),
12be365e 744 mem_used / 1024);
0335a835 745 }
61510437
DC
746 do_warn(
747 _("Memory available for repair (%luMB) may not be sufficient.\n"
748 "At least %luMB is needed to repair this filesystem efficiently\n"
749 "If repair fails due to lack of memory, please\n"),
750 max_mem / 1024, mem_used / 1024);
751 if (do_prefetch)
752 do_warn(
753 _("turn prefetching off (-P) to reduce the memory footprint.\n"));
754 else
755 do_warn(
756 _("increase system RAM and/or swap space to at least %luMB.\n"),
757 mem_used * 2 / 1024);
758
759 max_mem = mem_used;
2556c98b
BN
760 }
761
61510437
DC
762 max_mem -= mem_used;
763 if (max_mem >= (1 << 30))
764 max_mem = 1 << 30;
765 libxfs_bhash_size = max_mem / (HASH_CACHE_RATIO *
766 (mp->m_inode_cluster_size >> 10));
767 if (libxfs_bhash_size < 512)
768 libxfs_bhash_size = 512;
769
2556c98b
BN
770 if (verbose)
771 do_log(_(" - block cache size set to %d entries\n"),
772 libxfs_bhash_size * HASH_CACHE_RATIO);
773
ba9ecd40 774 libxfs_bcache = cache_init(0, libxfs_bhash_size,
2556c98b
BN
775 &libxfs_bcache_operations);
776 }
777
2bd0ea18
NS
778 /*
779 * calculate what mkfs would do to this filesystem
780 */
781 calc_mkfs(mp);
782
783 /*
c1f7a46c 784 * initialize block alloc map
2bd0ea18 785 */
c1f7a46c
BN
786 init_bmaps(mp);
787 incore_ino_init(mp);
788 incore_ext_init(mp);
789
790 /* initialize random globals now that we know the fs geometry */
791 inodes_per_block = mp->m_sb.sb_inopblock;
2bd0ea18
NS
792
793 if (parse_sb_version(&mp->m_sb)) {
794 do_warn(
507f4e33 795 _("Found unsupported filesystem features. Exiting now.\n"));
2bd0ea18
NS
796 return(1);
797 }
798
799 /* make sure the per-ag freespace maps are ok so we can mount the fs */
364a126c 800 phase2(mp, phase2_threads);
06fbdda9 801 timestamp(PHASE_END, 2, NULL);
2bd0ea18 802
2556c98b
BN
803 if (do_prefetch)
804 init_prefetch(mp);
805
2bd0ea18 806 phase3(mp);
06fbdda9 807 timestamp(PHASE_END, 3, NULL);
2bd0ea18
NS
808
809 phase4(mp);
06fbdda9 810 timestamp(PHASE_END, 4, NULL);
2bd0ea18
NS
811
812 if (no_modify)
507f4e33 813 printf(_("No modify flag set, skipping phase 5\n"));
3b6ac903 814 else {
2bd0ea18 815 phase5(mp);
3b6ac903 816 }
06fbdda9 817 timestamp(PHASE_END, 5, NULL);
2bd0ea18 818
c1f7a46c
BN
819 /*
820 * Done with the block usage maps, toss them...
821 */
822 free_bmaps(mp);
823
2bd0ea18
NS
824 if (!bad_ino_btree) {
825 phase6(mp);
06fbdda9 826 timestamp(PHASE_END, 6, NULL);
2bd0ea18
NS
827
828 phase7(mp);
06fbdda9 829 timestamp(PHASE_END, 7, NULL);
2bd0ea18
NS
830 } else {
831 do_warn(
507f4e33 832_("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
2bd0ea18
NS
833 }
834
0340d706 835 if (lost_quotas && !have_uquotino && !have_gquotino && !have_pquotino) {
2bd0ea18
NS
836 if (!no_modify) {
837 do_warn(
507f4e33 838_("Warning: no quota inodes were found. Quotas disabled.\n"));
2bd0ea18
NS
839 } else {
840 do_warn(
507f4e33 841_("Warning: no quota inodes were found. Quotas would be disabled.\n"));
2bd0ea18
NS
842 }
843 } else if (lost_quotas) {
844 if (!no_modify) {
845 do_warn(
507f4e33 846_("Warning: quota inodes were cleared. Quotas disabled.\n"));
2bd0ea18
NS
847 } else {
848 do_warn(
507f4e33 849_("Warning: quota inodes would be cleared. Quotas would be disabled.\n"));
2bd0ea18
NS
850 }
851 } else {
852 if (lost_uquotino) {
853 if (!no_modify) {
854 do_warn(
507f4e33
NS
855_("Warning: user quota information was cleared.\n"
856 "User quotas can not be enforced until limit information is recreated.\n"));
2bd0ea18
NS
857 } else {
858 do_warn(
507f4e33
NS
859_("Warning: user quota information would be cleared.\n"
860 "User quotas could not be enforced until limit information was recreated.\n"));
2bd0ea18
NS
861 }
862 }
863
b36eef04 864 if (lost_gquotino) {
2bd0ea18
NS
865 if (!no_modify) {
866 do_warn(
507f4e33
NS
867_("Warning: group quota information was cleared.\n"
868 "Group quotas can not be enforced until limit information is recreated.\n"));
2bd0ea18
NS
869 } else {
870 do_warn(
507f4e33
NS
871_("Warning: group quota information would be cleared.\n"
872 "Group quotas could not be enforced until limit information was recreated.\n"));
9b27bdbb
NS
873 }
874 }
875
876 if (lost_pquotino) {
877 if (!no_modify) {
878 do_warn(
879_("Warning: project quota information was cleared.\n"
880 "Project quotas can not be enforced until limit information is recreated.\n"));
881 } else {
882 do_warn(
883_("Warning: project quota information would be cleared.\n"
884 "Project quotas could not be enforced until limit information was recreated.\n"));
2bd0ea18
NS
885 }
886 }
887 }
888
2556c98b 889 if (ag_stride && report_interval)
06fbdda9 890 stop_progress_rpt();
9f38f08d 891
2bd0ea18
NS
892 if (no_modify) {
893 do_log(
507f4e33 894 _("No modify flag set, skipping filesystem flush and exiting.\n"));
3b6ac903 895 if (verbose)
06fbdda9 896 summary_report();
2bd0ea18
NS
897 if (fs_is_dirty)
898 return(1);
899
900 return(0);
901 }
902
903 /*
904 * Clear the quota flags if they're on.
905 */
906 sbp = libxfs_getsb(mp, 0);
907 if (!sbp)
507f4e33 908 do_error(_("couldn't get superblock\n"));
2bd0ea18 909
5e656dbb 910 dsb = XFS_BUF_TO_SBP(sbp);
2bd0ea18 911
342aef1e 912 if (be16_to_cpu(dsb->sb_qflags) & XFS_ALL_QUOTA_CHKD) {
5e656dbb
BN
913 do_warn(_("Note - quota info will be regenerated on next "
914 "quota mount.\n"));
342aef1e 915 dsb->sb_qflags &= cpu_to_be16(~XFS_ALL_QUOTA_CHKD);
2bd0ea18
NS
916 }
917
6bf4721d 918 if (copied_sunit) {
2bd0ea18 919 do_warn(
6bf4721d
ES
920_("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\n"
921 "Please reset with mount -o sunit=<value>,swidth=<value> if necessary\n"),
5e656dbb 922 be32_to_cpu(dsb->sb_unit), be32_to_cpu(dsb->sb_width));
dfc130f3 923 }
2bd0ea18
NS
924
925 libxfs_writebuf(sbp, 0);
926
2556c98b
BN
927 /*
928 * Done, flush all cached buffers and inodes.
929 */
930 libxfs_bcache_flush();
931
2bd0ea18 932 libxfs_umount(mp);
d321ceac
NS
933 if (x.rtdev)
934 libxfs_device_close(x.rtdev);
935 if (x.logdev && x.logdev != x.ddev)
936 libxfs_device_close(x.logdev);
937 libxfs_device_close(x.ddev);
2bd0ea18 938
06fbdda9
MV
939 if (verbose)
940 summary_report();
507f4e33 941 do_log(_("done\n"));
3ae81520
ES
942
943 if (dangerously && !no_modify)
944 do_warn(
945_("Repair of readonly mount complete. Immediate reboot encouraged.\n"));
946
4c0a98ae
BN
947 pftrace_done();
948
3b6ac903
MV
949 return (0);
950}