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