2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
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.
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.
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
19 #include <xfs/libxlog.h>
27 #include "err_protos.h"
32 #define rounddown(x, y) (((x)/(y))*(y))
34 extern void phase1(xfs_mount_t
*);
35 extern void phase2(xfs_mount_t
*);
36 extern void phase3(xfs_mount_t
*);
37 extern void phase4(xfs_mount_t
*);
38 extern void phase5(xfs_mount_t
*);
39 extern void phase6(xfs_mount_t
*);
40 extern void phase7(xfs_mount_t
*);
41 extern void incore_init(xfs_mount_t
*);
43 #define XR_MAX_SECT_SIZE (64 * 1024)
46 * option tables for getsubopt calls
50 * -o (user-supplied override options)
62 #define PREFETCH_INO_CNT 4
64 #define PREFETCH_DIR_CNT 5
66 #define PREFETCH_AIO_CNT 6
77 _("Usage: %s [-nLvV] [-o subopt[=value]] [-l logdev] [-r rtdev] devname\n"),
83 err_string(int err_code
)
85 static char *err_message
[XR_BAD_ERR_CODE
];
89 err_message
[XR_OK
] = _("no error");
90 err_message
[XR_BAD_MAGIC
] = _("bad magic number");
91 err_message
[XR_BAD_BLOCKSIZE
] = _("bad blocksize field");
92 err_message
[XR_BAD_BLOCKLOG
] = _("bad blocksize log field");
93 err_message
[XR_BAD_VERSION
] = _("bad version number");
94 err_message
[XR_BAD_INPROGRESS
] =
95 _("filesystem mkfs-in-progress bit set");
96 err_message
[XR_BAD_FS_SIZE_DATA
] =
97 _("inconsistent filesystem geometry information");
98 err_message
[XR_BAD_INO_SIZE_DATA
] =
99 _("bad inode size or inconsistent with number of inodes/block"),
100 err_message
[XR_BAD_SECT_SIZE_DATA
] = _("bad sector size");
101 err_message
[XR_AGF_GEO_MISMATCH
] =
102 _("AGF geometry info conflicts with filesystem geometry");
103 err_message
[XR_AGI_GEO_MISMATCH
] =
104 _("AGI geometry info conflicts with filesystem geometry");
105 err_message
[XR_SB_GEO_MISMATCH
] =
106 _("AG superblock geometry info conflicts with filesystem geometry");
107 err_message
[XR_EOF
] = _("attempted to perform I/O beyond EOF");
108 err_message
[XR_BAD_RT_GEO_DATA
] =
109 _("inconsistent filesystem geometry in realtime filesystem component");
110 err_message
[XR_BAD_INO_MAX_PCT
] =
111 _("maximum indicated percentage of inodes > 100%");
112 err_message
[XR_BAD_INO_ALIGN
] =
113 _("inconsistent inode alignment value");
114 err_message
[XR_INSUFF_SEC_SB
] =
115 _("not enough secondary superblocks with matching geometry");
116 err_message
[XR_BAD_SB_UNIT
] =
117 _("bad stripe unit in superblock");
118 err_message
[XR_BAD_SB_WIDTH
] =
119 _("bad stripe width in superblock");
120 err_message
[XR_BAD_SVN
] =
121 _("bad shared version number in superblock");
125 if (err_code
< XR_OK
|| err_code
>= XR_BAD_ERR_CODE
)
126 do_abort(_("bad error code - %d\n"), err_code
);
128 return(err_message
[err_code
]);
132 noval(char opt
, char *tbl
[], int idx
)
134 do_warn(_("-%c %s option cannot have a value\n"), opt
, tbl
[idx
]);
139 respec(char opt
, char *tbl
[], int idx
)
141 do_warn("-%c ", opt
);
143 do_warn("%s ", tbl
[idx
]);
144 do_warn(_("option respecified\n"));
149 unknown(char opt
, char *s
)
151 do_warn(_("unknown option -%c %s\n"), opt
, s
);
156 * sets only the global argument flags and variables
159 process_args(int argc
, char **argv
)
172 full_ino_ex_data
= 0;
180 fs_attributes_allowed
= 1;
181 fs_attributes2_allowed
= 1;
182 fs_inode_nlink_allowed
= 1;
183 fs_quotas_allowed
= 1;
184 fs_aligned_inodes_allowed
= 1;
185 fs_sb_feature_bits_allowed
= 1;
186 fs_has_extflgbit_allowed
= 1;
188 fs_shared_allowed
= 1;
189 report_interval
= PROG_RPT_DEFAULT
;
192 * XXX have to add suboption processing here
193 * attributes, quotas, nlinks, aligned_inos, sb_fbits
195 while ((c
= getopt(argc
, argv
, "o:fl:r:LnDvVdPMt:")) != EOF
) {
205 switch (getsubopt(&p
, (constpp
)o_opts
, &val
)) {
208 noval('o', o_opts
, ASSUME_XFS
);
210 respec('o', o_opts
, ASSUME_XFS
);
215 noval('o', o_opts
, PRE_65_BETA
);
222 libxfs_ihash_size
= (int) strtol(val
, 0, 0);
225 libxfs_bhash_size
= (int) strtol(val
, 0, 0);
227 case PREFETCH_INO_CNT
:
228 libxfs_lio_ino_count
= (int) strtol(val
, 0, 0);
230 case PREFETCH_DIR_CNT
:
231 libxfs_lio_dir_count
= (int) strtol(val
, 0, 0);
233 case PREFETCH_AIO_CNT
:
234 libxfs_lio_aio_count
= (int) strtol(val
, 0, 0);
237 thread_count
= (int) strtol(val
, 0, 0);
269 printf(_("%s version %s\n"), progname
, VERSION
);
278 report_interval
= (int) strtol(optarg
, 0, 0);
286 if (argc
- optind
!= 1)
289 if ((fs_name
= argv
[optind
]) == NULL
)
294 do_msg(int do_abort
, char const *msg
, va_list args
)
296 vfprintf(stderr
, msg
, args
);
306 do_error(char const *msg
, ...)
310 fprintf(stderr
, _("\nfatal error -- "));
313 do_msg(1, msg
, args
);
317 * like do_error, only the error is internal, no system
318 * error so no oserror processing
321 do_abort(char const *msg
, ...)
326 do_msg(1, msg
, args
);
330 do_warn(char const *msg
, ...)
337 do_msg(0, msg
, args
);
344 do_log(char const *msg
, ...)
349 do_msg(0, msg
, args
);
354 calc_mkfs(xfs_mount_t
*mp
)
356 xfs_agblock_t fino_bno
;
359 do_inoalign
= mp
->m_sinoalign
;
362 * pre-calculate geometry of ag 0. We know what it looks
363 * like because we know what mkfs does -- 3 btree roots,
364 * and some number of blocks to prefill the agfl.
366 bnobt_root
= howmany(4 * mp
->m_sb
.sb_sectsize
, mp
->m_sb
.sb_blocksize
);
367 bcntbt_root
= bnobt_root
+ 1;
368 inobt_root
= bnobt_root
+ 2;
369 fino_bno
= inobt_root
+ XFS_MIN_FREELIST_RAW(1, 1, mp
) + 1;
372 * ditto the location of the first inode chunks in the fs ('/')
374 if (XFS_SB_VERSION_HASDALIGN(&mp
->m_sb
) && do_inoalign
) {
375 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, roundup(fino_bno
,
376 mp
->m_sb
.sb_unit
), 0);
377 } else if (XFS_SB_VERSION_HASALIGN(&mp
->m_sb
) &&
378 mp
->m_sb
.sb_inoalignmt
> 1) {
379 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
,
381 mp
->m_sb
.sb_inoalignmt
),
384 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
, 0);
387 ASSERT(XFS_IALLOC_BLOCKS(mp
) > 0);
389 if (XFS_IALLOC_BLOCKS(mp
) > 1)
390 last_prealloc_ino
= first_prealloc_ino
+ XFS_INODES_PER_CHUNK
;
392 last_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
+ 1, 0);
395 * now the first 3 inodes in the system
397 if (mp
->m_sb
.sb_rootino
!= first_prealloc_ino
) {
399 _("sb root inode value %llu %sinconsistent with calculated value %lu\n"),
401 (mp
->m_sb
.sb_rootino
== NULLFSINO
? "(NULLFSINO) ":""),
406 _("resetting superblock root inode pointer to %lu\n"),
410 _("would reset superblock root inode pointer to %lu\n"),
414 * just set the value -- safe since the superblock
415 * doesn't get flushed out if no_modify is set
417 mp
->m_sb
.sb_rootino
= first_prealloc_ino
;
420 if (mp
->m_sb
.sb_rbmino
!= first_prealloc_ino
+ 1) {
422 _("sb realtime bitmap inode %llu %sinconsistent with calculated value %lu\n"),
424 (mp
->m_sb
.sb_rbmino
== NULLFSINO
? "(NULLFSINO) ":""),
425 first_prealloc_ino
+ 1);
429 _("resetting superblock realtime bitmap ino pointer to %lu\n"),
430 first_prealloc_ino
+ 1);
433 _("would reset superblock realtime bitmap ino pointer to %lu\n"),
434 first_prealloc_ino
+ 1);
437 * just set the value -- safe since the superblock
438 * doesn't get flushed out if no_modify is set
440 mp
->m_sb
.sb_rbmino
= first_prealloc_ino
+ 1;
443 if (mp
->m_sb
.sb_rsumino
!= first_prealloc_ino
+ 2) {
445 _("sb realtime summary inode %llu %sinconsistent with calculated value %lu\n"),
447 (mp
->m_sb
.sb_rsumino
== NULLFSINO
? "(NULLFSINO) ":""),
448 first_prealloc_ino
+ 2);
452 _("resetting superblock realtime summary ino pointer to %lu\n"),
453 first_prealloc_ino
+ 2);
456 _("would reset superblock realtime summary ino pointer to %lu\n"),
457 first_prealloc_ino
+ 2);
460 * just set the value -- safe since the superblock
461 * doesn't get flushed out if no_modify is set
463 mp
->m_sb
.sb_rsumino
= first_prealloc_ino
+ 2;
469 main(int argc
, char **argv
)
471 xfs_mount_t
*temp_mp
;
478 progname
= basename(argv
[0]);
479 setlocale(LC_ALL
, "");
480 bindtextdomain(PACKAGE
, LOCALEDIR
);
484 setbuf(stdout
, NULL
);
486 process_args(argc
, argv
);
489 timestamp(PHASE_START
, 0, NULL
);
490 timestamp(PHASE_END
, 0, NULL
);
492 /* do phase1 to make sure we have a superblock */
494 timestamp(PHASE_END
, 1, NULL
);
496 if (no_modify
&& primary_sb_modified
) {
497 do_warn(_("Primary superblock would have been modified.\n"
498 "Cannot proceed further in no_modify mode.\n"
503 /* prepare the mount structure */
504 sbp
= libxfs_readbuf(x
.ddev
, XFS_SB_DADDR
, 1, 0);
505 memset(&xfs_m
, 0, sizeof(xfs_mount_t
));
507 libxfs_xlate_sb(XFS_BUF_PTR(sbp
), sb
, 1, XFS_SB_ALL_BITS
);
509 mp
= libxfs_mount(&xfs_m
, sb
, x
.ddev
, x
.logdev
, x
.rtdev
, 0);
513 _("%s: cannot repair this filesystem. Sorry.\n"),
520 * set XFS-independent status vars from the mount/sb structure
522 glob_agcount
= mp
->m_sb
.sb_agcount
;
524 chunks_pblock
= mp
->m_sb
.sb_inopblock
/ XFS_INODES_PER_CHUNK
;
525 max_symlink_blocks
= howmany(MAXPATHLEN
- 1, mp
->m_sb
.sb_blocksize
);
526 inodes_per_cluster
= XFS_INODE_CLUSTER_SIZE(mp
) >> mp
->m_sb
.sb_inodelog
;
528 if (do_parallel
&& report_interval
) {
530 msgbuf
= malloc(DURATION_BUF_SIZE
);
532 do_log(_(" - reporting progress in intervals of %s\n"),
533 duration(report_interval
, msgbuf
));
539 * calculate what mkfs would do to this filesystem
544 * check sb filesystem stats and initialize in-core data structures
548 if (parse_sb_version(&mp
->m_sb
)) {
550 _("Found unsupported filesystem features. Exiting now.\n"));
554 /* make sure the per-ag freespace maps are ok so we can mount the fs */
556 timestamp(PHASE_END
, 2, NULL
);
559 timestamp(PHASE_END
, 3, NULL
);
562 timestamp(PHASE_END
, 4, NULL
);
564 /* XXX: nathans - something in phase4 ain't playing by */
565 /* the buffer cache rules.. why doesn't IRIX hit this? */
566 libxfs_bcache_flush();
569 printf(_("No modify flag set, skipping phase 5\n"));
573 timestamp(PHASE_END
, 5, NULL
);
575 if (!bad_ino_btree
) {
577 timestamp(PHASE_END
, 6, NULL
);
579 libxfs_bcache_flush();
582 timestamp(PHASE_END
, 7, NULL
);
585 _("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
588 if (lost_quotas
&& !have_uquotino
&& !have_gquotino
) {
591 _("Warning: no quota inodes were found. Quotas disabled.\n"));
594 _("Warning: no quota inodes were found. Quotas would be disabled.\n"));
596 } else if (lost_quotas
) {
599 _("Warning: quota inodes were cleared. Quotas disabled.\n"));
602 _("Warning: quota inodes would be cleared. Quotas would be disabled.\n"));
608 _("Warning: user quota information was cleared.\n"
609 "User quotas can not be enforced until limit information is recreated.\n"));
612 _("Warning: user quota information would be cleared.\n"
613 "User quotas could not be enforced until limit information was recreated.\n"));
620 _("Warning: group quota information was cleared.\n"
621 "Group quotas can not be enforced until limit information is recreated.\n"));
624 _("Warning: group quota information would be cleared.\n"
625 "Group quotas could not be enforced until limit information was recreated.\n"));
632 _("Warning: project quota information was cleared.\n"
633 "Project quotas can not be enforced until limit information is recreated.\n"));
636 _("Warning: project quota information would be cleared.\n"
637 "Project quotas could not be enforced until limit information was recreated.\n"));
642 if (do_parallel
&& report_interval
)
647 _("No modify flag set, skipping filesystem flush and exiting.\n"));
657 * Done, flush all cached buffers and inodes.
659 libxfs_icache_purge();
660 libxfs_bcache_purge();
663 * Clear the quota flags if they're on.
665 sbp
= libxfs_getsb(mp
, 0);
667 do_error(_("couldn't get superblock\n"));
669 sb
= XFS_BUF_TO_SBP(sbp
);
671 if (sb
->sb_qflags
& (XFS_UQUOTA_CHKD
|XFS_OQUOTA_CHKD
)) {
673 _("Note - quota info will be regenerated on next quota mount.\n"));
674 sb
->sb_qflags
&= ~(XFS_UQUOTA_CHKD
|XFS_OQUOTA_CHKD
);
679 _("Note - stripe unit (%d) and width (%d) fields have been reset.\n"
680 "Please set with mount -o sunit=<value>,swidth=<value>\n"),
681 sb
->sb_unit
, sb
->sb_width
);
686 libxfs_writebuf(sbp
, 0);
690 libxfs_device_close(x
.rtdev
);
691 if (x
.logdev
&& x
.logdev
!= x
.ddev
)
692 libxfs_device_close(x
.logdev
);
693 libxfs_device_close(x
.ddev
);