2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
41 #include "err_protos.h"
43 #define rounddown(x, y) (((x)/(y))*(y))
45 extern void phase1(xfs_mount_t
*);
46 extern void phase2(xfs_mount_t
*);
47 extern void phase3(xfs_mount_t
*);
48 extern void phase4(xfs_mount_t
*);
49 extern void phase5(xfs_mount_t
*);
50 extern void phase6(xfs_mount_t
*);
51 extern void phase7(xfs_mount_t
*);
52 extern void incore_init(xfs_mount_t
*);
54 #define XR_MAX_SECT_SIZE (64 * 1024)
57 * option tables for getsubopt calls
61 * -o (user-supplied override options)
76 _("Usage: %s [-nLvV] [-o subopt[=value]] [-l logdev] [-r rtdev] devname\n"),
82 err_string(int err_code
)
84 static char *err_message
[XR_BAD_ERR_CODE
];
88 err_message
[XR_OK
] = _("no error");
89 err_message
[XR_BAD_MAGIC
] = _("bad magic number");
90 err_message
[XR_BAD_BLOCKSIZE
] = _("bad blocksize field");
91 err_message
[XR_BAD_BLOCKLOG
] = _("bad blocksize log field");
92 err_message
[XR_BAD_VERSION
] = _("bad version number");
93 err_message
[XR_BAD_INPROGRESS
] =
94 _("filesystem mkfs-in-progress bit set");
95 err_message
[XR_BAD_FS_SIZE_DATA
] =
96 _("inconsistent filesystem geometry information");
97 err_message
[XR_BAD_INO_SIZE_DATA
] =
98 _("bad inode size or inconsistent with number of inodes/block"),
99 err_message
[XR_BAD_SECT_SIZE_DATA
] = _("bad sector size");
100 err_message
[XR_AGF_GEO_MISMATCH
] =
101 _("AGF geometry info conflicts with filesystem geometry");
102 err_message
[XR_AGI_GEO_MISMATCH
] =
103 _("AGI geometry info conflicts with filesystem geometry");
104 err_message
[XR_SB_GEO_MISMATCH
] =
105 _("AG superblock geometry info conflicts with filesystem geometry");
106 err_message
[XR_EOF
] = _("attempted to perform I/O beyond EOF");
107 err_message
[XR_BAD_RT_GEO_DATA
] =
108 _("inconsistent filesystem geometry in realtime filesystem component");
109 err_message
[XR_BAD_INO_MAX_PCT
] =
110 _("maximum indicated percentage of inodes > 100%");
111 err_message
[XR_BAD_INO_ALIGN
] =
112 _("inconsistent inode alignment value");
113 err_message
[XR_INSUFF_SEC_SB
] =
114 _("not enough secondary superblocks with matching geometry");
115 err_message
[XR_BAD_SB_UNIT
] =
116 _("bad stripe unit in superblock");
117 err_message
[XR_BAD_SB_WIDTH
] =
118 _("bad stripe width in superblock");
119 err_message
[XR_BAD_SVN
] =
120 _("bad shared version number in superblock");
124 if (err_code
< XR_OK
|| err_code
>= XR_BAD_ERR_CODE
)
125 do_abort(_("bad error code - %d\n"), err_code
);
127 return(err_message
[err_code
]);
131 noval(char opt
, char *tbl
[], int idx
)
133 do_warn(_("-%c %s option cannot have a value\n"), opt
, tbl
[idx
]);
138 respec(char opt
, char *tbl
[], int idx
)
140 do_warn("-%c ", opt
);
142 do_warn("%s ", tbl
[idx
]);
143 do_warn(_("option respecified\n"));
148 unknown(char opt
, char *s
)
150 do_warn(_("unknown option -%c %s\n"), opt
, s
);
155 * sets only the global argument flags and variables
158 process_args(int argc
, char **argv
)
178 fs_attributes_allowed
= 1;
179 fs_inode_nlink_allowed
= 1;
180 fs_quotas_allowed
= 1;
181 fs_aligned_inodes_allowed
= 1;
182 fs_sb_feature_bits_allowed
= 1;
183 fs_has_extflgbit_allowed
= 1;
185 fs_shared_allowed
= 1;
188 * XXX have to add suboption processing here
189 * attributes, quotas, nlinks, aligned_inos, sb_fbits
191 while ((c
= getopt(argc
, argv
, "o:fl:r:LnDvV")) != EOF
) {
201 switch (getsubopt(&p
, (constpp
)o_opts
, &val
)) {
204 noval('o', o_opts
, ASSUME_XFS
);
206 respec('o', o_opts
, ASSUME_XFS
);
211 noval('o', o_opts
, PRE_65_BETA
);
244 printf(_("%s version %s\n"), progname
, VERSION
);
251 if (argc
- optind
!= 1)
254 if ((fs_name
= argv
[optind
]) == NULL
)
259 do_msg(int do_abort
, char const *msg
, va_list args
)
261 vfprintf(stderr
, msg
, args
);
271 do_error(char const *msg
, ...)
275 fprintf(stderr
, _("\nfatal error -- "));
278 do_msg(1, msg
, args
);
282 * like do_error, only the error is internal, no system
283 * error so no oserror processing
286 do_abort(char const *msg
, ...)
291 do_msg(1, msg
, args
);
295 do_warn(char const *msg
, ...)
302 do_msg(0, msg
, args
);
309 do_log(char const *msg
, ...)
314 do_msg(0, msg
, args
);
319 calc_mkfs(xfs_mount_t
*mp
)
321 xfs_agblock_t fino_bno
;
324 do_inoalign
= mp
->m_sinoalign
;
327 * pre-calculate geometry of ag 0. We know what it looks
328 * like because we know what mkfs does -- 3 btree roots,
329 * and some number of blocks to prefill the agfl.
331 bnobt_root
= howmany(4 * mp
->m_sb
.sb_sectsize
, mp
->m_sb
.sb_blocksize
);
332 bcntbt_root
= bnobt_root
+ 1;
333 inobt_root
= bnobt_root
+ 2;
334 fino_bno
= inobt_root
+ XFS_MIN_FREELIST_RAW(1, 1, mp
) + 1;
337 * ditto the location of the first inode chunks in the fs ('/')
339 if (XFS_SB_VERSION_HASDALIGN(&mp
->m_sb
) && do_inoalign
) {
340 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, roundup(fino_bno
,
341 mp
->m_sb
.sb_unit
), 0);
342 } else if (XFS_SB_VERSION_HASALIGN(&mp
->m_sb
) &&
343 mp
->m_sb
.sb_inoalignmt
> 1) {
344 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
,
346 mp
->m_sb
.sb_inoalignmt
),
349 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
, 0);
352 ASSERT(XFS_IALLOC_BLOCKS(mp
) > 0);
354 if (XFS_IALLOC_BLOCKS(mp
) > 1)
355 last_prealloc_ino
= first_prealloc_ino
+ XFS_INODES_PER_CHUNK
;
357 last_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
+ 1, 0);
360 * now the first 3 inodes in the system
362 if (mp
->m_sb
.sb_rootino
!= first_prealloc_ino
) {
364 _("sb root inode value %llu %sinconsistent with calculated value %lu\n"),
366 (mp
->m_sb
.sb_rootino
== NULLFSINO
? "(NULLFSINO) ":""),
371 _("resetting superblock root inode pointer to %lu\n"),
375 _("would reset superblock root inode pointer to %lu\n"),
379 * just set the value -- safe since the superblock
380 * doesn't get flushed out if no_modify is set
382 mp
->m_sb
.sb_rootino
= first_prealloc_ino
;
385 if (mp
->m_sb
.sb_rbmino
!= first_prealloc_ino
+ 1) {
387 _("sb realtime bitmap inode %llu %sinconsistent with calculated value %lu\n"),
389 (mp
->m_sb
.sb_rbmino
== NULLFSINO
? "(NULLFSINO) ":""),
390 first_prealloc_ino
+ 1);
394 _("resetting superblock realtime bitmap ino pointer to %lu\n"),
395 first_prealloc_ino
+ 1);
398 _("would reset superblock realtime bitmap ino pointer to %lu\n"),
399 first_prealloc_ino
+ 1);
402 * just set the value -- safe since the superblock
403 * doesn't get flushed out if no_modify is set
405 mp
->m_sb
.sb_rbmino
= first_prealloc_ino
+ 1;
408 if (mp
->m_sb
.sb_rsumino
!= first_prealloc_ino
+ 2) {
410 _("sb realtime summary inode %llu %sinconsistent with calculated value %lu\n"),
412 (mp
->m_sb
.sb_rsumino
== NULLFSINO
? "(NULLFSINO) ":""),
413 first_prealloc_ino
+ 2);
417 _("resetting superblock realtime summary ino pointer to %lu\n"),
418 first_prealloc_ino
+ 2);
421 _("would reset superblock realtime summary ino pointer to %lu\n"),
422 first_prealloc_ino
+ 2);
425 * just set the value -- safe since the superblock
426 * doesn't get flushed out if no_modify is set
428 mp
->m_sb
.sb_rsumino
= first_prealloc_ino
+ 2;
434 main(int argc
, char **argv
)
436 xfs_mount_t
*temp_mp
;
442 progname
= basename(argv
[0]);
443 setlocale(LC_ALL
, "");
444 bindtextdomain(PACKAGE
, LOCALEDIR
);
448 setbuf(stdout
, NULL
);
450 process_args(argc
, argv
);
453 /* do phase1 to make sure we have a superblock */
456 if (no_modify
&& primary_sb_modified
) {
457 do_warn(_("Primary superblock would have been modified.\n"
458 "Cannot proceed further in no_modify mode.\n"
463 /* prepare the mount structure */
464 sbp
= libxfs_readbuf(x
.ddev
, XFS_SB_DADDR
, 1, 0);
465 memset(&xfs_m
, 0, sizeof(xfs_mount_t
));
467 libxfs_xlate_sb(XFS_BUF_PTR(sbp
), sb
, 1, ARCH_CONVERT
, XFS_SB_ALL_BITS
);
469 mp
= libxfs_mount(&xfs_m
, sb
, x
.ddev
, x
.logdev
, x
.rtdev
, 0);
473 _("%s: cannot repair this filesystem. Sorry.\n"),
480 * set XFS-independent status vars from the mount/sb structure
482 glob_agcount
= mp
->m_sb
.sb_agcount
;
484 chunks_pblock
= mp
->m_sb
.sb_inopblock
/ XFS_INODES_PER_CHUNK
;
485 max_symlink_blocks
= howmany(MAXPATHLEN
- 1, mp
->m_sb
.sb_blocksize
);
486 inodes_per_cluster
= XFS_INODE_CLUSTER_SIZE(mp
) >> mp
->m_sb
.sb_inodelog
;
489 * calculate what mkfs would do to this filesystem
494 * check sb filesystem stats and initialize in-core data structures
498 if (parse_sb_version(&mp
->m_sb
)) {
500 _("Found unsupported filesystem features. Exiting now.\n"));
504 /* make sure the per-ag freespace maps are ok so we can mount the fs */
513 printf(_("No modify flag set, skipping phase 5\n"));
517 if (!bad_ino_btree
) {
523 _("Inode allocation btrees are too corrupted, skipping phases 6 and 7\n"));
526 if (lost_quotas
&& !have_uquotino
&& !have_gquotino
) {
529 _("Warning: no quota inodes were found. Quotas disabled.\n"));
532 _("Warning: no quota inodes were found. Quotas would be disabled.\n"));
534 } else if (lost_quotas
) {
537 _("Warning: quota inodes were cleared. Quotas disabled.\n"));
540 _("Warning: quota inodes would be cleared. Quotas would be disabled.\n"));
546 _("Warning: user quota information was cleared.\n"
547 "User quotas can not be enforced until limit information is recreated.\n"));
550 _("Warning: user quota information would be cleared.\n"
551 "User quotas could not be enforced until limit information was recreated.\n"));
558 _("Warning: group quota information was cleared.\n"
559 "Group quotas can not be enforced until limit information is recreated.\n"));
562 _("Warning: group quota information would be cleared.\n"
563 "Group quotas could not be enforced until limit information was recreated.\n"));
570 _("No modify flag set, skipping filesystem flush and exiting.\n"));
578 * Clear the quota flags if they're on.
580 sbp
= libxfs_getsb(mp
, 0);
582 do_error(_("couldn't get superblock\n"));
584 sb
= XFS_BUF_TO_SBP(sbp
);
586 if (sb
->sb_qflags
& (XFS_UQUOTA_CHKD
|XFS_GQUOTA_CHKD
)) {
588 _("Note - quota info will be regenerated on next quota mount.\n"));
589 sb
->sb_qflags
&= ~(XFS_UQUOTA_CHKD
|XFS_GQUOTA_CHKD
);
594 _("Note - stripe unit (%d) and width (%d) fields have been reset.\n"
595 "Please set with mount -o sunit=<value>,swidth=<value>\n"),
596 sb
->sb_unit
, sb
->sb_width
);
601 libxfs_writebuf(sbp
, 0);
605 libxfs_device_close(x
.rtdev
);
606 if (x
.logdev
&& x
.logdev
!= x
.ddev
)
607 libxfs_device_close(x
.logdev
);
608 libxfs_device_close(x
.ddev
);