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)
75 do_warn("Usage: %s [-nLvV] [-o subopt[=value]] [-l logdev] [-r rtdev] devname\n",
80 static char *err_message
[] = {
83 "bad blocksize field",
84 "bad blocksize log field",
86 "filesystem mkfs-in-progress bit set",
87 "inconsistent filesystem geometry information",
88 "bad inode size or inconsistent with number of inodes/block",
90 "AGF geometry info conflicts with filesystem geometry",
91 "AGI geometry info conflicts with filesystem geometry",
92 "AG superblock geometry info conflicts with filesystem geometry",
93 "attempted to perform I/O beyond EOF",
94 "inconsistent filesystem geometry in realtime filesystem component",
95 "maximum indicated percentage of inodes > 100%",
96 "inconsistent inode alignment value",
97 "not enough secondary superblocks with matching geometry",
98 "bad stripe unit in superblock",
99 "bad stripe width in superblock",
100 "bad shared version number in superblock"
104 err_string(int err_code
)
106 if (err_code
< XR_OK
|| err_code
>= XR_BAD_ERR_CODE
)
107 do_abort("bad error code - %d\n", err_code
);
109 return(err_message
[err_code
]);
113 noval(char opt
, char *tbl
[], int idx
)
115 do_warn("-%c %s option cannot have a value\n", opt
, tbl
[idx
]);
120 respec(char opt
, char *tbl
[], int idx
)
122 do_warn("-%c ", opt
);
124 do_warn("%s ", tbl
[idx
]);
125 do_warn("option respecified\n");
130 unknown(char opt
, char *s
)
132 do_warn("unknown option -%c %s\n", opt
, s
);
137 * sets only the global argument flags and variables
140 process_args(int argc
, char **argv
)
160 fs_attributes_allowed
= 1;
161 fs_inode_nlink_allowed
= 1;
162 fs_quotas_allowed
= 1;
163 fs_aligned_inodes_allowed
= 1;
164 fs_sb_feature_bits_allowed
= 1;
165 fs_has_extflgbit_allowed
= 1;
167 fs_shared_allowed
= 1;
170 * XXX have to add suboption processing here
171 * attributes, quotas, nlinks, aligned_inos, sb_fbits
173 while ((c
= getopt(argc
, argv
, "o:fl:r:LnDvV")) != EOF
) {
183 switch (getsubopt(&p
, (constpp
)o_opts
, &val
)) {
186 noval('o', o_opts
, ASSUME_XFS
);
188 respec('o', o_opts
, ASSUME_XFS
);
193 noval('o', o_opts
, PRE_65_BETA
);
226 printf("%s version %s\n", progname
, VERSION
);
233 if (argc
- optind
!= 1)
236 if ((fs_name
= argv
[optind
]) == NULL
)
241 do_msg(int do_abort
, char const *msg
, va_list args
)
243 vfprintf(stderr
, msg
, args
);
253 do_error(char const *msg
, ...)
257 fprintf(stderr
, "\nfatal error -- ");
260 do_msg(1, msg
, args
);
264 * like do_error, only the error is internal, no system
265 * error so no oserror processing
268 do_abort(char const *msg
, ...)
273 do_msg(1, msg
, args
);
277 do_warn(char const *msg
, ...)
284 do_msg(0, msg
, args
);
291 do_log(char const *msg
, ...)
296 do_msg(0, msg
, args
);
301 calc_mkfs(xfs_mount_t
*mp
)
303 xfs_agblock_t fino_bno
;
306 do_inoalign
= mp
->m_sinoalign
;
309 * pre-calculate geometry of ag 0. We know what it looks
310 * like because we know what mkfs does -- 3 btree roots,
311 * and some number of blocks to prefill the agfl.
313 bnobt_root
= howmany(4 * mp
->m_sb
.sb_sectsize
, mp
->m_sb
.sb_blocksize
);
314 bcntbt_root
= bnobt_root
+ 1;
315 inobt_root
= bnobt_root
+ 2;
316 fino_bno
= inobt_root
+ XFS_MIN_FREELIST_RAW(1, 1, mp
) + 1;
319 * ditto the location of the first inode chunks in the fs ('/')
321 if (XFS_SB_VERSION_HASDALIGN(&mp
->m_sb
) && do_inoalign
) {
322 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, roundup(fino_bno
,
323 mp
->m_sb
.sb_unit
), 0);
324 } else if (XFS_SB_VERSION_HASALIGN(&mp
->m_sb
) &&
325 mp
->m_sb
.sb_inoalignmt
> 1) {
326 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
,
328 mp
->m_sb
.sb_inoalignmt
),
331 first_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
, 0);
334 ASSERT(XFS_IALLOC_BLOCKS(mp
) > 0);
336 if (XFS_IALLOC_BLOCKS(mp
) > 1)
337 last_prealloc_ino
= first_prealloc_ino
+ XFS_INODES_PER_CHUNK
;
339 last_prealloc_ino
= XFS_OFFBNO_TO_AGINO(mp
, fino_bno
+ 1, 0);
342 * now the first 3 inodes in the system
344 if (mp
->m_sb
.sb_rootino
!= first_prealloc_ino
) {
346 "sb root inode value %llu inconsistent with calculated value %llu\n",
347 mp
->m_sb
.sb_rootino
, first_prealloc_ino
);
351 "resetting superblock root inode pointer to %llu\n",
355 "would reset superblock root inode pointer to %llu\n",
359 * just set the value -- safe since the superblock
360 * doesn't get flushed out if no_modify is set
362 mp
->m_sb
.sb_rootino
= first_prealloc_ino
;
365 if (mp
->m_sb
.sb_rbmino
!= first_prealloc_ino
+ 1) {
367 "sb realtime bitmap inode %llu inconsistent with calculated value %llu\n",
368 mp
->m_sb
.sb_rbmino
, first_prealloc_ino
+ 1);
372 "resetting superblock realtime bitmap ino pointer to %llu\n",
373 first_prealloc_ino
+ 1);
376 "would reset superblock realtime bitmap ino pointer to %llu\n",
377 first_prealloc_ino
+ 1);
380 * just set the value -- safe since the superblock
381 * doesn't get flushed out if no_modify is set
383 mp
->m_sb
.sb_rbmino
= first_prealloc_ino
+ 1;
386 if (mp
->m_sb
.sb_rsumino
!= first_prealloc_ino
+ 2) {
388 "sb realtime summary inode %llu inconsistent with calculated value %llu\n",
389 mp
->m_sb
.sb_rsumino
, first_prealloc_ino
+ 2);
393 "resetting superblock realtime summary ino pointer to %llu\n",
394 first_prealloc_ino
+ 2);
397 "would reset superblock realtime summary ino pointer to %llu\n",
398 first_prealloc_ino
+ 2);
401 * just set the value -- safe since the superblock
402 * doesn't get flushed out if no_modify is set
404 mp
->m_sb
.sb_rsumino
= first_prealloc_ino
+ 2;
410 main(int argc
, char **argv
)
412 xfs_mount_t
*temp_mp
;
418 progname
= basename(argv
[0]);
421 setbuf(stdout
, NULL
);
423 process_args(argc
, argv
);
426 /* do phase1 to make sure we have a superblock */
429 if (no_modify
&& primary_sb_modified
) {
430 do_warn("primary superblock would have been modified.\n");
431 do_warn("cannot proceed further in no_modify mode.\n");
432 do_warn("exiting now.\n");
436 /* prepare the mount structure */
437 sbp
= libxfs_readbuf(x
.ddev
, XFS_SB_DADDR
, 1, 0);
438 memset(&xfs_m
, 0, sizeof(xfs_mount_t
));
440 libxfs_xlate_sb(XFS_BUF_PTR(sbp
), sb
, 1, ARCH_CONVERT
, XFS_SB_ALL_BITS
);
442 mp
= libxfs_mount(&xfs_m
, sb
, x
.ddev
, x
.logdev
, x
.rtdev
, 0);
445 fprintf(stderr
, "%s: cannot repair this filesystem. Sorry.\n",
452 * set XFS-independent status vars from the mount/sb structure
454 glob_agcount
= mp
->m_sb
.sb_agcount
;
456 chunks_pblock
= mp
->m_sb
.sb_inopblock
/ XFS_INODES_PER_CHUNK
;
457 max_symlink_blocks
= howmany(MAXPATHLEN
- 1, mp
->m_sb
.sb_blocksize
);
458 inodes_per_cluster
= XFS_INODE_CLUSTER_SIZE(mp
) >> mp
->m_sb
.sb_inodelog
;
461 * calculate what mkfs would do to this filesystem
466 * check sb filesystem stats and initialize in-core data structures
470 if (parse_sb_version(&mp
->m_sb
)) {
472 "Found unsupported filesystem features. Exiting now.\n");
476 /* make sure the per-ag freespace maps are ok so we can mount the fs */
485 printf("No modify flag set, skipping phase 5\n");
489 if (!bad_ino_btree
) {
495 "Inode allocation btrees are too corrupted, skipping phases 6 and 7\n");
498 if (lost_quotas
&& !have_uquotino
&& !have_gquotino
) {
501 "Warning: no quota inodes were found. Quotas disabled.\n");
504 "Warning: no quota inodes were found. Quotas would be disabled.\n");
506 } else if (lost_quotas
) {
509 "Warning: quota inodes were cleared. Quotas disabled.\n");
512 "Warning: quota inodes would be cleared. Quotas would be disabled.\n");
518 "Warning: user quota information was cleared.\n");
520 "User quotas can not be enforced until limit information is recreated.\n");
523 "Warning: user quota information would be cleared.\n");
525 "User quotas could not be enforced until limit information was recreated.\n");
532 "Warning: group quota information was cleared.\n");
534 "Group quotas can not be enforced until limit information is recreated.\n");
537 "Warning: group quota information would be cleared.\n");
539 "Group quotas could not be enforced until limit information was recreated.\n");
546 "No modify flag set, skipping filesystem flush and exiting.\n");
554 * Clear the quota flags if they're on.
556 sbp
= libxfs_getsb(mp
, 0);
558 do_error("couldn't get superblock\n");
560 sb
= XFS_BUF_TO_SBP(sbp
);
562 if (sb
->sb_qflags
& (XFS_UQUOTA_CHKD
|XFS_GQUOTA_CHKD
)) {
564 "Note - quota info will be regenerated on next quota mount.\n");
565 sb
->sb_qflags
&= ~(XFS_UQUOTA_CHKD
|XFS_GQUOTA_CHKD
);
570 "Note - stripe unit (%d) and width (%d) fields have been reset.\n"
571 "Please set with mount -o sunit=<value>,swidth=<value>\n",
572 sb
->sb_unit
, sb
->sb_width
);
577 libxfs_writebuf(sbp
, 0);
581 libxfs_device_close(x
.rtdev
);
582 if (x
.logdev
&& x
.logdev
!= x
.ddev
)
583 libxfs_device_close(x
.logdev
);
584 libxfs_device_close(x
.ddev
);