2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
11 * All rights reserved.
13 * Redistribution and use in source and binary forms are permitted
14 * provided that: (1) source distributions retain this entire copyright
15 * notice and comment, and (2) distributions including binaries display
16 * the following acknowledgement: ``This product includes software
17 * developed by the University of California, Berkeley and its contributors''
18 * in the documentation or other materials provided with the distribution
19 * and in all advertising materials mentioning features or use of this
20 * software. Neither the name of the University nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
35 #include <sys/param.h>
36 #include <sys/types.h>
37 #include <sys/sysmacros.h>
38 #include <sys/mntent.h>
40 #include <sys/filio.h>
41 #include <sys/isa_defs.h> /* for ENDIAN defines */
42 #include <sys/int_const.h>
43 #include <sys/fs/ufs_fs.h>
44 #include <sys/vnode.h>
45 #include <sys/fs/ufs_fs.h>
46 #include <sys/fs/ufs_inode.h>
47 #include <sys/fs/ufs_log.h>
49 #include <sys/fcntl.h>
53 #include <sys/vfstab.h>
58 * The size of a cylinder group is calculated by CGSIZE. The maximum size
59 * is limited by the fact that cylinder groups are at most one block.
60 * Its size is derived from the size of the maps maintained in the
61 * cylinder group and the (struct cg) size.
64 /* base cg */ (sizeof (struct cg) + \
65 /* blktot size */ (fs)->fs_cpg * sizeof (int32_t) + \
66 /* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof (short) + \
67 /* inode map */ howmany((fs)->fs_ipg, NBBY) + \
68 /* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY))
70 #define altsblock (*asblk.b_un.b_fs)
71 #define POWEROF2(num) (((num) & ((num) - 1)) == 0)
74 * Methods of determining where alternate superblocks should
75 * be. MAX_SB_STYLES must be the last one, and the others need
79 MKFS_STYLE
= 1, NEWFS_STYLE
, MAX_SB_STYLES
82 static caddr_t calcsb_names
[] = {
83 "<UNKNOWN>", "MKFS", "NEWFS", "<OUT OF RANGE>"
86 struct shadowclientinfo
*shadowclientinfo
= NULL
;
87 struct shadowclientinfo
*attrclientinfo
= NULL
;
88 int maxshadowclients
= 1024; /* allocation size, not limit */
90 static void badsb(int, caddr_t
);
91 static int calcsb(calcsb_t
, caddr_t
, int, struct fs
*);
92 static int checksb(int);
93 static void flush_fs(void);
94 static void sblock_init(void);
95 static void uncreate_maps(void);
98 read_super_block(int listerr
)
103 if (mount_point
!= NULL
) {
104 fd
= open(mount_point
, O_RDONLY
);
106 errexit("fsck: open mount point error: %s",
110 /* get the latest super block */
111 if (ioctl(fd
, _FIOGETSUPERBLOCK
, &sblock
)) {
112 errexit("fsck: ioctl _FIOGETSUPERBLOCK error: %s",
118 (void) fsck_bread(fsreadfd
, (caddr_t
)&sblock
,
119 bflag
!= 0 ? (diskaddr_t
)bflag
: (diskaddr_t
)SBLOCK
,
124 * Don't let trash from the disk trip us up later
125 * in ungetsummaryinfo().
127 sblock
.fs_u
.fs_csp
= NULL
;
130 * Rudimentary consistency checks. Can't really call
131 * checksb() here, because there may be outstanding
132 * deltas that still need to be applied.
134 if ((sblock
.fs_magic
!= FS_MAGIC
) &&
135 (sblock
.fs_magic
!= MTB_UFS_MAGIC
)) {
136 err
= "MAGIC NUMBER WRONG";
139 if (sblock
.fs_magic
== FS_MAGIC
&&
140 (sblock
.fs_version
!= UFS_EFISTYLE4NONEFI_VERSION_2
&&
141 sblock
.fs_version
!= UFS_VERSION_MIN
)) {
142 err
= "UNRECOGNIZED VERSION";
145 if (sblock
.fs_magic
== MTB_UFS_MAGIC
&&
146 (sblock
.fs_version
> MTB_UFS_VERSION_1
||
147 sblock
.fs_version
< MTB_UFS_VERSION_MIN
)) {
148 err
= "UNRECOGNIZED VERSION";
151 if (sblock
.fs_ncg
< 1) {
152 err
= "NCG OUT OF RANGE";
155 if (sblock
.fs_cpg
< 1) {
156 err
= "CPG OUT OF RANGE";
159 if (sblock
.fs_ncg
* sblock
.fs_cpg
< sblock
.fs_ncyl
||
160 (sblock
.fs_ncg
- 1) * sblock
.fs_cpg
>= sblock
.fs_ncyl
) {
161 err
= "NCYL IS INCONSISTENT WITH NCG*CPG";
164 if (sblock
.fs_sbsize
< 0 || sblock
.fs_sbsize
> SBSIZE
) {
165 err
= "SIZE OUT OF RANGE";
181 if (mount_point
!= NULL
) {
182 fd
= open(mount_point
, O_RDONLY
);
184 errexit("fsck: open mount point error: %s",
188 if (ioctl(fd
, _FIOFFS
, NULL
)) { /* flush file system */
189 errexit("fsck: ioctl _FIOFFS error: %s",
198 * Roll the embedded log, if any, and set up the global variables
202 logsetup(caddr_t devstr
)
213 return (1); /* can't roll log while alternate sb specified */
216 * Roll the log, if any. A bad sb implies we'll be using
217 * an alternate sb as far as logging goes, so just fail back
218 * to the caller if we can't read the default sb. Suppress
219 * complaints, because the caller will be reading the same
220 * superblock again and running full verification on it, so
221 * whatever is bad will be reported then.
223 sblock
.fs_logbno
= 0;
225 if (!read_super_block(0))
229 * Roll the log in 3 cases:
230 * 1. If it's unmounted (mount_point == NULL) and it's not marked
231 * as fully rolled (sblock.fs_rolled != FS_ALL_ROLLED)
232 * 2. If it's mounted and anything other than a sanity
233 * check fsck (mflag) is being done, as we have the current
234 * super block. Note, only a sanity check is done for
235 * root/usr at boot. If a roll were done then the expensive
236 * ufs_flush() gets called, leading to a slower boot.
237 * 3. If anything other then a sanity check (mflag) is being done
238 * to a mounted filesystem while it is in read-only state
239 * (e.g. root during early boot stages) we have to detect this
240 * and have to roll the log as well. NB. the read-only mount
241 * will flip fs_clean from FSLOG to FSSTABLE and marks the
242 * log as FS_NEED_ROLL.
244 if (sblock
.fs_logbno
&&
245 (((mount_point
== NULL
) && (sblock
.fs_rolled
!= FS_ALL_ROLLED
)) ||
246 ((mount_point
!= NULL
) && !mflag
))) {
247 int roll_log_err
= 0;
249 if (sblock
.fs_ronly
&& (sblock
.fs_clean
== FSSTABLE
) &&
250 (sblock
.fs_state
+ sblock
.fs_time
== FSOKAY
)) {
252 * roll the log without a mount
256 if (sblock
.fs_clean
== FSLOG
&&
257 (sblock
.fs_state
+ sblock
.fs_time
== FSOKAY
)) {
258 if (rl_roll_log(devstr
) != RL_SUCCESS
)
262 (void) printf("Can't roll the log for %s.\n", devstr
);
264 * There are two cases where we want to set
265 * an error code and return:
267 * - We're not on a live root and the user
268 * chose *not* to ignore the log
269 * Otherwise, we want to mark the log as bad
270 * and continue to check the filesystem. This
271 * has the side effect of destroying the log.
273 if (preen
|| (!hotroot
&&
275 "DISCARDING THE LOG MAY DISCARD PENDING TRANSACTIONS.\n"
276 "DISCARD THE LOG AND CONTINUE") == 0)) {
277 exitstat
= EXERRFATAL
;
284 /* Logging UFS may be enabled */
285 if (sblock
.fs_logbno
) {
288 /* log is not okay; check the fs */
289 if (FSOKAY
!= (sblock
.fs_state
+ sblock
.fs_time
))
293 * If logging or (stable and mounted) then continue
295 if (!((sblock
.fs_clean
== FSLOG
) ||
296 (sblock
.fs_clean
== FSSTABLE
) && (mount_point
!= NULL
)))
299 /* get the log allocation block */
300 buf
= malloc(dev_bsize
);
304 ud_buf
= malloc(dev_bsize
);
305 if (ud_buf
== NULL
) {
309 (void) fsck_bread(fsreadfd
, buf
,
310 logbtodb(&sblock
, sblock
.fs_logbno
),
312 ebp
= (extent_block_t
*)buf
;
314 /* log allocation block is not okay; check the fs */
315 if (ebp
->type
!= LUFS_EXTENTS
) {
321 /* get the log state block(s) */
322 if (fsck_bread(fsreadfd
, ud_buf
,
323 (logbtodb(&sblock
, ebp
->extents
[0].pbno
)),
325 (void) fsck_bread(fsreadfd
, ud_buf
,
326 (logbtodb(&sblock
, ebp
->extents
[0].pbno
)) + 1,
329 ud
= (ml_odunit_t
*)ud_buf
;
330 ul
= (ml_unit_t
*)malloc(sizeof (*ul
));
338 /* log state is okay; don't need to check the fs */
339 if ((ul
->un_chksum
== ul
->un_head_ident
+ ul
->un_tail_ident
) &&
340 (ul
->un_version
== LUFS_VERSION_LATEST
) &&
341 (ul
->un_badlog
== 0) && (!badlog
)) {
353 * - given a pathname, determine the pathname to actually check
355 * - if it is in mnttab, set devstr to the special (block) name
356 * - if it is in vfstab, set devstr to the special (block) name
357 * - if it has not been found, bail
358 * - a file is used as-is, clear rflag
359 * - a device is converted to block version (so can search mnttab)
362 derive_devstr(const caddr_t dev
, caddr_t devstr
, size_t str_size
)
367 if (stat(dev
, &statb
) < 0) {
369 errexit("fsck: could not stat %s: %s", dev
, strerror(errno
));
372 mode
= statb
.st_mode
& S_IFMT
;
376 * The check_*() routines update devstr with the name.
379 if (!(check_mnttab(dev
, devstr
, str_size
) ||
380 check_vfstab(dev
, devstr
, str_size
))) {
381 exitstat
= EXBADPARM
;
383 "fsck: could not find mountpoint %s in mnttab nor vfstab",
389 (void) strlcpy(devstr
, dev
, str_size
);
393 (void) strlcpy(devstr
, unrawname(dev
), str_size
);
396 exitstat
= EXBADPARM
;
397 errexit("fsck: %s must be a mountpoint, device, or file", dev
);
403 * Reports the index of the magic filesystem that mntp names.
404 * If it does not correspond any of them, returns zero (hence
405 * the backwards loop).
408 which_corefs(const caddr_t mntp
)
412 for (corefs
= MAGIC_LIMIT
- 1; corefs
> 0; corefs
--)
413 if (strcmp(mntp
, magic_fs
[corefs
]) == 0)
420 * - set mount_point to NULL
421 * - if name is mounted (search mnttab)
422 * - if it is a device, clear rflag
423 * - if mounted on /, /usr, or /var, set corefs
424 * - if corefs and read-only, set hotroot and continue
425 * - if errorlocked, continue
426 * - if preening, bail
427 * - ask user whether to continue, bail if not
428 * - if it is a device and not mounted and rflag, convert
429 * name to raw version
432 check_mount_state(caddr_t devstr
, size_t str_size
)
438 if (stat(devstr
, &statb
) < 0) {
440 errexit("fsck: could not stat %s: %s", devstr
, strerror(errno
));
442 if (S_ISCHR(statb
.st_mode
) || S_ISBLK(statb
.st_mode
))
446 * mounted() will update mount_point when returning true.
449 if ((mountedfs
= mounted(devstr
, devstr
, str_size
)) != M_NOMNT
) {
452 corefs
= which_corefs(mount_point
);
453 if (corefs
&& (mountedfs
== M_RO
)) {
455 } else if (errorlocked
) {
458 exitstat
= EXMOUNTED
;
459 pfatal("%s IS CURRENTLY MOUNTED%s.",
460 devstr
, mountedfs
== M_RW
? " READ/WRITE" : "");
462 if (!nflag
&& !mflag
) {
463 pwarn("%s IS CURRENTLY MOUNTED READ/%s.",
464 devstr
, mountedfs
== M_RW
? "WRITE" :
466 if (reply("CONTINUE") == 0) {
467 exitstat
= EXMOUNTED
;
468 errexit("Program terminated");
472 } else if (is_dev
&& rflag
) {
473 (void) strlcpy(devstr
, rawname(devstr
), str_size
);
481 open_and_intro(caddr_t devstr
, int corefs
)
485 if ((fsreadfd
= open64(devstr
, O_RDONLY
)) < 0) {
486 (void) printf("Can't open %s: %s\n", devstr
, strerror(errno
));
491 if (!preen
|| debug
!= 0)
492 (void) printf("** %s", devstr
);
495 if (debug
&& elock_combuf
!= NULL
)
496 (void) printf(" error-lock comment: \"%s\" ",
501 if (nflag
|| roflag
|| (fswritefd
= open64(devstr
, O_WRONLY
)) < 0) {
504 pfatal("(NO WRITE ACCESS)\n");
505 (void) printf(" (NO WRITE)");
510 (void) printf(" pid %d\n", pid
);
511 if (debug
&& (hotroot
|| (mountedfs
!= M_NOMNT
))) {
512 (void) printf("** %s", devstr
);
514 (void) printf(" is %s fs", magic_fs
[corefs
]);
515 if (mountedfs
!= M_NOMNT
)
516 (void) printf(" and is mounted read-%s",
517 (mountedfs
== M_RO
) ? "only" : "write");
519 (void) printf(" and is error-locked");
521 (void) printf(".\n");
529 find_superblock(caddr_t devstr
)
539 * Check the superblock, looking for alternates if necessary.
540 * In more-recent times, some UFS instances get created with
541 * only the first ten and last ten superblock backups. Since
542 * if we can't get the necessary information from any of those,
543 * the odds are also against us for the ones in between, we'll
544 * just look at those twenty to save time.
546 if (!read_super_block(1) || !checksb(1)) {
547 if (bflag
|| preen
) {
551 for (style
= MKFS_STYLE
; style
< MAX_SB_STYLES
; style
++) {
552 if (reply("LOOK FOR ALTERNATE SUPERBLOCKS WITH %s",
553 calcsb_names
[style
]) == 0)
557 if (!calcsb(style
, devstr
, fsreadfd
, &proto
)) {
563 "debug: calcsb(%s) gave fpg %d, cgoffset %d, ",
565 proto
.fs_fpg
, proto
.fs_cgoffset
);
566 (void) printf("cgmask 0x%x, sblk %d, ncg %d\n",
567 proto
.fs_cgmask
, proto
.fs_sblkno
,
570 for (cg
= 0; cg
< proto
.fs_ncg
; cg
++) {
571 bflag
= fsbtodb(&proto
, cgsblock(&proto
, cg
));
574 "debug: trying block %lld\n",
576 if (read_super_block(0) && checksb(0)) {
578 "FOUND ALTERNATE SUPERBLOCK %d WITH %s\n",
579 bflag
, calcsb_names
[style
]);
581 "USE ALTERNATE SUPERBLOCK") == 1) {
586 if (first
&& (cg
>= 9)) {
588 if (proto
.fs_ncg
<= 9)
590 else if (proto
.fs_ncg
<= 19)
593 cg
= proto
.fs_ncg
- 10;
602 * Didn't find one? Try to fake it.
604 if (style
>= MAX_SB_STYLES
) {
605 pwarn("SEARCH FOR ALTERNATE SUPERBLOCKS FAILED.\n");
606 for (style
= MKFS_STYLE
; style
< MAX_SB_STYLES
;
608 if (reply("USE GENERIC SUPERBLOCK FROM %s",
609 calcsb_names
[style
]) == 1 &&
610 calcsb(style
, devstr
, fsreadfd
, &sblock
)) {
615 * We got something from mkfs/newfs, so use it.
617 if (style
< MAX_SB_STYLES
) {
618 proto
.fs_ncg
= sblock
.fs_ncg
;
624 * Still no luck? Tell the user they're on their own.
626 if (style
>= MAX_SB_STYLES
) {
627 pwarn("SEARCH FOR ALTERNATE SUPERBLOCKS FAILED. "
628 "YOU MUST USE THE -o b OPTION\n"
629 "TO FSCK TO SPECIFY THE LOCATION OF A VALID "
630 "ALTERNATE SUPERBLOCK TO\n"
631 "SUPPLY NEEDED INFORMATION; SEE fsck(1M).\n");
638 * Need to make sure a human really wants us to use
639 * this. -y mode could've gotten us this far, so
640 * we need to ask something that has to be answered
643 * Note that we can't get here when preening.
646 pwarn("CALCULATED GENERIC SUPERBLOCK WITH %s\n",
647 calcsb_names
[style
]);
649 pwarn("FOUND ALTERNATE SUPERBLOCK AT %d USING %s\n",
650 bflag
, calcsb_names
[style
]);
652 pwarn("If filesystem was created with manually-specified ");
653 pwarn("geometry, using\nauto-discovered superblock may ");
654 pwarn("result in irrecoverable damage to\nfilesystem and ");
655 pwarn("user data.\n");
656 if (reply("CANCEL FILESYSTEM CHECK") == 1) {
658 pwarn("Please verify that the indicated block "
659 "contains a proper\nsuperblock for the "
660 "filesystem (see fsdb(1M)).\n");
662 pwarn("\nFSCK was running in YES "
663 "mode. If you wish to run in "
664 "that mode using\nthe alternate "
666 "`fsck -y -o b=%d %s'.\n",
674 * Pretend we found it as an alternate, so everything
675 * gets updated when we clean up at the end.
679 sblk
.b_bno
= fsbtodb(&sblock
, cgsblock(&sblock
, 0));
680 bwrite(fswritefd
, (caddr_t
)&sblock
, SBLOCK
, SBSIZE
);
681 write_altsb(fswritefd
);
690 * Check and potentially fix certain fields in the super block.
693 fixup_superblock(void)
696 * Kernel looks for FS_OPTTIME, and assumes that if that's not
697 * what's there, it must be FS_OPTSPACE, so not fixing does not
698 * require setting iscorrupt.
700 if (sblock
.fs_optim
!= FS_OPTTIME
&& sblock
.fs_optim
!= FS_OPTSPACE
) {
701 pfatal("UNDEFINED OPTIMIZATION IN SUPERBLOCK");
702 if (reply("SET TO DEFAULT") == 1) {
703 sblock
.fs_optim
= FS_OPTTIME
;
707 if ((sblock
.fs_minfree
< 0 || sblock
.fs_minfree
> 99)) {
708 pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK",
710 if (reply("SET TO DEFAULT") == 1) {
711 sblock
.fs_minfree
= 10;
713 } else if (sblock
.fs_minfree
< 0) {
715 * Kernel uses minfree without verification,
716 * and a negative value would do bad things.
724 initial_error_state_adjust(void)
728 /* do this right away to prevent any other fscks on this fs */
729 switch (sblock
.fs_clean
) {
734 errexit("ERROR-LOCKED; MARKED \"FSFIX\"\n");
735 if (reply("marked FSFIX, CONTINUE") == 0) {
742 errexit("ERROR-LOCKED; MARKED \"FSCLEAN\"\n");
743 if (reply("marked FSCLEAN, CONTINUE") == 0) {
751 pwarn("ERRORLOCKED; NOT MARKED \"FSBAD\"\n");
753 errexit("ERRORLOCKED; NOT MARKED \"FSBAD\"\n");
755 (void) printf("error-locked but not marked \"FSBAD\";");
756 if (reply(" CONTINUE") == 0) {
764 if (!do_errorlock(LOCKFS_ELOCK
)) {
769 if (reply("error-lock reset failed; CONTINUE") == 0) {
775 sblock
.fs_state
= FSOKAY
- (long)sblock
.fs_time
;
776 sblock
.fs_clean
= FSFIX
;
778 write_altsb(fswritefd
);
794 * read in the summary info.
796 sblock
.fs_u
.fs_csp
= calloc(1, sblock
.fs_cssize
);
797 if (sblock
.fs_u
.fs_csp
== NULL
)
799 "cannot allocate %u bytes for cylinder group summary info\n",
800 (unsigned)sblock
.fs_cssize
);
801 sip
= (caddr_t
)sblock
.fs_u
.fs_csp
;
803 for (i
= 0, j
= 0; i
< sblock
.fs_cssize
; i
+= sblock
.fs_bsize
, j
++) {
804 size
= sblock
.fs_cssize
- i
< sblock
.fs_bsize
?
805 sblock
.fs_cssize
- i
: sblock
.fs_bsize
;
806 failed
= fsck_bread(fsreadfd
, sip
,
807 fsbtodb(&sblock
, sblock
.fs_csaddr
+ j
* sblock
.fs_frag
),
809 if (failed
&& !asked
) {
810 pfatal("BAD SUMMARY INFORMATION");
811 if (reply("CONTINUE") == 0) {
822 * Reverses the effects of getsummaryinfo().
825 ungetsummaryinfo(void)
827 if ((sblk
.b_un
.b_fs
!= NULL
) &&
828 (sblk
.b_un
.b_fs
->fs_u
.fs_csp
!= NULL
)) {
829 free(sblk
.b_un
.b_fs
->fs_u
.fs_csp
);
830 sblk
.b_un
.b_fs
->fs_u
.fs_csp
= NULL
;
835 * Allocate and initialize the global tables.
836 * It is the responsibility of the caller to clean up and allocations
837 * if an error is returned.
840 create_and_init_maps(void)
845 maxfsblock
= sblock
.fs_size
;
846 maxino
= sblock
.fs_ncg
* sblock
.fs_ipg
;
848 bmapsize
= roundup(howmany((uint64_t)maxfsblock
, NBBY
),
850 blockmap
= calloc((size_t)bmapsize
, sizeof (char));
851 if (blockmap
== NULL
) {
852 (void) printf("cannot alloc %lld bytes for blockmap\n",
853 (longlong_t
)bmapsize
);
857 statemap
= calloc((size_t)(maxino
+ 1), sizeof (*statemap
));
858 if (statemap
== NULL
) {
859 (void) printf("cannot alloc %lld bytes for statemap\n",
860 (longlong_t
)(maxino
+ 1) * sizeof (*statemap
));
864 lncntp
= (short *)calloc((size_t)(maxino
+ 1), sizeof (short));
865 if (lncntp
== NULL
) {
866 (void) printf("cannot alloc %lld bytes for lncntp\n",
867 (longlong_t
)(maxino
+ 1) * sizeof (short));
873 * If we had to fake up a superblock, it won't show that there
874 * are any directories at all. This causes problems when we
875 * use numdirs to calculate hash keys, so use something at least
878 numdirs
= sblock
.fs_cstotal
.cs_ndir
;
880 numdirs
= sblock
.fs_ipg
* sblock
.fs_ncg
/ 2;
881 listmax
= numdirs
+ 10;
882 inpsort
= (struct inoinfo
**)calloc((unsigned)listmax
,
883 sizeof (struct inoinfo
*));
884 inphead
= (struct inoinfo
**)calloc((unsigned)numdirs
,
885 sizeof (struct inoinfo
*));
886 if (inpsort
== NULL
|| inphead
== NULL
) {
887 (void) printf("cannot alloc %lld bytes for inphead\n",
888 (longlong_t
)numdirs
* sizeof (struct inoinfo
*));
893 if (listmax
> ULONG_MAX
)
894 errexit("create_and_init_maps: listmax overflowed\n");
895 if (numdirs
> ULONG_MAX
)
896 errexit("create_and_init_maps: numdirs overflowed\n");
900 aclmax
= numdirs
+ 10;
901 aclpsort
= (struct inoinfo
**)calloc((unsigned)aclmax
,
902 sizeof (struct inoinfo
*));
903 aclphead
= (struct inoinfo
**)calloc((unsigned)numacls
,
904 sizeof (struct inoinfo
*));
905 if (aclpsort
== NULL
|| aclphead
== NULL
) {
906 (void) printf("cannot alloc %lld bytes for aclphead\n",
907 (longlong_t
)numacls
* sizeof (struct inoinfo
*));
912 if (aclmax
> ULONG_MAX
)
913 errexit("create_and_init_maps: aclmax overflowed\n");
914 if (numacls
> ULONG_MAX
)
915 errexit("create_and_init_maps: numacls overflowed\n");
928 static char devstr
[MAXPATHLEN
+ 1];
933 derive_devstr(dev
, devstr
, sizeof (devstr
));
934 errorlocked
= is_errorlocked(devstr
);
935 corefs
= check_mount_state(devstr
, sizeof (devstr
));
939 if (open_and_intro(devstr
, corefs
) == -1)
942 if (mflag
&& mounted(devstr
, devstr
,
943 sizeof (devstr
)) == M_RW
)
949 if (!logsetup(devstr
))
953 * Flush fs if we're going to do anything other than a sanity check.
954 * Note, if logging then the fs was already flushed in logsetup().
956 if (!islog
&& !mflag
)
959 if (find_superblock(devstr
) == -1)
965 (initial_error_state_adjust() == -1))
969 * asblk could be dirty because we found a mismatch between
970 * the primary superblock and one of its backups in checksb().
972 if (asblk
.b_dirty
&& !bflag
) {
973 (void) memmove(&altsblock
, &sblock
, (size_t)sblock
.fs_sbsize
);
974 flush(fswritefd
, &asblk
);
980 * if not error-locked, using the standard superblock,
981 * not bad log, not forced, preening, and is clean;
984 if (!errorlocked
&& (bflag
== 0) &&
985 ((!islog
|| islogok
) &&
986 (fflag
== 0) && preen
&&
987 (FSOKAY
== (sblock
.fs_state
+ sblock
.fs_time
)) &&
988 ((sblock
.fs_clean
== FSLOG
&& islog
) ||
989 ((sblock
.fs_clean
== FSCLEAN
) || (sblock
.fs_clean
== FSSTABLE
))))) {
995 if (create_and_init_maps() == -1)
1003 exitstat
= EXERRFATAL
;
1012 * Can't get rid of the superblock buffer, because our
1013 * caller references it to generate the summary statistics.
1020 * Undoes the allocations in create_and_init_maps()
1026 * No ordering dependency amongst these, so they are here in
1027 * the same order they were calculated.
1029 if (blockmap
!= NULL
)
1031 if (statemap
!= NULL
)
1035 if (inpsort
!= NULL
)
1037 if (inphead
!= NULL
)
1039 if (aclpsort
!= NULL
)
1041 if (aclphead
!= NULL
)
1046 * mkfs limits the size of the inode map to be no more than a third of
1047 * the cylinder group space. We'll use that value for sanity checking
1048 * the superblock's inode per group value.
1050 #define MAXIpG (roundup(sblock.fs_bsize * NBBY / 3, sblock.fs_inopb))
1053 * Check the super block and its summary info.
1056 checksb(int listerr
)
1061 * When the fs check is successfully completed, the alternate super
1062 * block at sblk.b_bno will be overwritten by ckfini() with the
1063 * repaired super block.
1065 sblk
.b_bno
= bflag
? bflag
: (SBOFF
/ dev_bsize
);
1066 sblk
.b_size
= SBSIZE
;
1069 * Sanity-check some of the values we are going to use later
1070 * in allocation requests.
1072 if (sblock
.fs_cstotal
.cs_ndir
< 1 ||
1073 sblock
.fs_cstotal
.cs_ndir
> sblock
.fs_ncg
* sblock
.fs_ipg
) {
1076 "Found %d directories, should be between 1 and %d inclusive.\n",
1077 sblock
.fs_cstotal
.cs_ndir
,
1078 sblock
.fs_ncg
* sblock
.fs_ipg
);
1079 err
= "NUMBER OF DIRECTORIES OUT OF RANGE";
1083 if (sblock
.fs_nrpos
<= 0 || sblock
.fs_postbloff
< 0 ||
1084 sblock
.fs_cpc
< 0 ||
1085 (sblock
.fs_postbloff
+
1086 (sblock
.fs_nrpos
* sblock
.fs_cpc
* sizeof (short))) >
1088 err
= "ROTATIONAL POSITION TABLE SIZE OUT OF RANGE";
1092 if (sblock
.fs_cssize
!=
1093 fragroundup(&sblock
, sblock
.fs_ncg
* sizeof (struct csum
))) {
1094 err
= "SIZE OF CYLINDER GROUP SUMMARY AREA WRONG";
1098 if (sblock
.fs_inopb
!= (sblock
.fs_bsize
/ sizeof (struct dinode
))) {
1099 err
= "INOPB NONSENSICAL RELATIVE TO BSIZE";
1103 if (sblock
.fs_bsize
> MAXBSIZE
) {
1104 err
= "BLOCK SIZE LARGER THAN MAXIMUM SUPPORTED";
1108 if (sblock
.fs_bsize
!= (sblock
.fs_frag
* sblock
.fs_fsize
)) {
1109 err
= "FRAGS PER BLOCK OR FRAG SIZE WRONG";
1113 if (sblock
.fs_dsize
>= sblock
.fs_size
) {
1114 err
= "NUMBER OF DATA BLOCKS OUT OF RANGE";
1119 if (sblock
.fs_size
>
1120 (sblock
.fs_nsect
* sblock
.fs_ntrak
* sblock
.fs_ncyl
)) {
1121 err
= "FILESYSTEM SIZE LARGER THAN DEVICE";
1127 * Check that the number of inodes per group isn't less than or
1128 * equal to zero. Also makes sure it isn't more than the
1129 * maximum number mkfs enforces.
1131 if (sblock
.fs_ipg
<= 0 || sblock
.fs_ipg
> MAXIpG
) {
1132 err
= "INODES PER GROUP OUT OF RANGE";
1136 if (sblock
.fs_cgsize
> sblock
.fs_bsize
) {
1137 err
= "CG HEADER LARGER THAN ONE BLOCK";
1142 * Set all possible fields that could differ, then do check
1143 * of whole super block against an alternate super block.
1144 * When an alternate super-block is specified this check is skipped.
1146 (void) getblk(&asblk
, cgsblock(&sblock
, sblock
.fs_ncg
- 1),
1147 (size_t)sblock
.fs_sbsize
);
1148 if (asblk
.b_errs
!= 0) {
1154 * Invalidate clean flag and state information.
1155 * Note that we couldn't return until after the
1156 * above getblk(), because we're going to want to
1157 * update asblk when everything's done.
1159 sblock
.fs_clean
= FSACTIVE
;
1160 sblock
.fs_state
= (long)sblock
.fs_time
;
1161 sblock
.fs_reclaim
= 0;
1166 altsblock
.fs_link
= sblock
.fs_link
;
1167 altsblock
.fs_rolled
= sblock
.fs_rolled
;
1168 altsblock
.fs_time
= sblock
.fs_time
;
1169 altsblock
.fs_state
= sblock
.fs_state
;
1170 altsblock
.fs_cstotal
= sblock
.fs_cstotal
;
1171 altsblock
.fs_cgrotor
= sblock
.fs_cgrotor
;
1172 altsblock
.fs_fmod
= sblock
.fs_fmod
;
1173 altsblock
.fs_clean
= sblock
.fs_clean
;
1174 altsblock
.fs_ronly
= sblock
.fs_ronly
;
1175 altsblock
.fs_flags
= sblock
.fs_flags
;
1176 altsblock
.fs_maxcontig
= sblock
.fs_maxcontig
;
1177 altsblock
.fs_minfree
= sblock
.fs_minfree
;
1178 altsblock
.fs_optim
= sblock
.fs_optim
;
1179 altsblock
.fs_rotdelay
= sblock
.fs_rotdelay
;
1180 altsblock
.fs_maxbpg
= sblock
.fs_maxbpg
;
1181 altsblock
.fs_logbno
= sblock
.fs_logbno
;
1182 altsblock
.fs_reclaim
= sblock
.fs_reclaim
;
1183 altsblock
.fs_si
= sblock
.fs_si
;
1184 (void) memmove((void *)altsblock
.fs_fsmnt
, (void *)sblock
.fs_fsmnt
,
1185 sizeof (sblock
.fs_fsmnt
));
1187 * The following should not have to be copied.
1189 (void) memmove((void *)altsblock
.fs_u
.fs_csp_pad
,
1190 (void *)sblock
.fs_u
.fs_csp_pad
, sizeof (sblock
.fs_u
.fs_csp_pad
));
1191 altsblock
.fs_fsbtodb
= sblock
.fs_fsbtodb
;
1192 altsblock
.fs_npsect
= sblock
.fs_npsect
;
1193 altsblock
.fs_nrpos
= sblock
.fs_nrpos
;
1194 if (memcmp((void *)&sblock
, (void *)&altsblock
,
1195 (size_t)sblock
.fs_sbsize
) != 0) {
1196 err
= "BAD VALUES IN SUPER BLOCK";
1203 badsb(listerr
, err
);
1208 badsb(int listerr
, caddr_t s
)
1213 (void) printf("%s: ", devname
);
1214 (void) printf("BAD SUPERBLOCK AT BLOCK %d: %s\n",
1215 bflag
!= 0 ? bflag
: SBLOCK
, s
);
1218 "USE AN ALTERNATE SUPERBLOCK TO SUPPLY NEEDED INFORMATION;\n");
1219 pwarn("e.g. fsck [-F ufs] -o b=# [special ...] \n");
1220 exitstat
= EXERRFATAL
;
1222 "where # is the alternate super block. SEE fsck_ufs(1M). \n");
1224 /* we're expected to return if not preening */
1228 * Write out the super block into each of the alternate super blocks.
1235 for (cylno
= 0; cylno
< sblock
.fs_ncg
; cylno
++)
1236 bwrite(fd
, (caddr_t
)&sblock
, fsbtodb(&sblock
,
1237 cgsblock(&sblock
, cylno
)), sblock
.fs_sbsize
);
1251 * May have buffer left over from previous filesystem check.
1253 if (sblk
.b_un
.b_buf
== NULL
)
1254 sblk
.b_un
.b_buf
= calloc(1, SBSIZE
);
1255 if (asblk
.b_un
.b_buf
== NULL
)
1256 asblk
.b_un
.b_buf
= calloc(1, SBSIZE
);
1257 if (sblk
.b_un
.b_buf
== NULL
|| asblk
.b_un
.b_buf
== NULL
)
1258 errexit("cannot allocate space for superblock\n");
1260 * Could get the actual sector size from the device here,
1261 * but considering how much would need to change in the rest
1262 * of the system before it'd be a problem for us, it's not
1263 * worth worrying about right now.
1265 dev_bsize
= secsize
= DEV_BSIZE
;
1269 * Calculate a prototype superblock based on information in the disk label.
1270 * When done the cgsblock macro can be calculated and the fs_ncg field
1271 * can be used. Do NOT attempt to use other macros without verifying that
1272 * their needed information is available!
1274 * In BSD, the disk label includes all sorts of useful information,
1275 * like cpg. Solaris doesn't have that, and deriving it (as well as
1276 * some other parameters) is difficult. Rather than duplicate the
1277 * code, just ask mkfs what it would've come up with by default.
1278 * Ideally, we'd just link in the code, but given the source base
1279 * involved, it's more practical to just get a binary dump.
1281 * The one minor drawback to the above approach is that newfs and mkfs
1282 * will produce vastly different layouts for the same partition if
1283 * they're allowed to default everything. So, if the superblock that
1284 * mkfs gives us doesn't work for guessing where the alternates are,
1285 * we need to try newfs.
1288 calcsb(calcsb_t style
, caddr_t dev
, int devfd
, struct fs
*fs
)
1290 #define FROM_CHILD 0
1297 caddr_t mkfsline
[] = {
1302 NULL
, /* SIZE_IDX */
1305 caddr_t newfsline
[] = {
1312 int pending
, transferred
;
1315 caddr_t sizestr
= NULL
;
1316 caddr_t path_old
, path_new
, mkfs_dir
, mkfs_path
, newfs_path
;
1324 (void) printf("calcsb() going with style MKFS\n");
1329 (void) printf("calcsb() going with style NEWFS\n");
1330 cmdline
= newfsline
;
1334 (void) printf("calcsb() doesn't undestand style %d\n",
1339 cmdline
[DEV_IDX
] = dev
;
1342 * Normally, only use the stock versions of the utilities.
1343 * However, if we're debugging, the odds are that we're
1344 * using experimental versions of them as well, so allow
1347 mkfs_path
= getenv("MKFS_PATH");
1348 if (!debug
|| (mkfs_path
== NULL
))
1349 mkfs_path
= MKFS_PATH
;
1351 newfs_path
= getenv("NEWFS_PATH");
1352 if (!debug
|| (newfs_path
== NULL
))
1353 newfs_path
= NEWFS_PATH
;
1355 if (style
== MKFS_STYLE
) {
1356 cmdline
[CMD_IDX
] = mkfs_path
;
1358 size
= getdisksize(dev
, devfd
);
1362 (void) fsck_asprintf(&sizestr
, "%lld", (longlong_t
)size
);
1363 cmdline
[SIZE_IDX
] = sizestr
;
1364 } else if (style
== NEWFS_STYLE
) {
1366 * Make sure that newfs will find the right version of mkfs.
1368 cmdline
[CMD_IDX
] = newfs_path
;
1369 path_old
= getenv("PATH");
1370 /* mkfs_path is always initialized, despite lint's concerns */
1371 mkfs_dir
= strdup(mkfs_path
);
1372 if (mkfs_dir
== NULL
)
1375 * If no location data for mkfs, don't need to do
1376 * anything about PATH.
1378 slash
= strrchr(mkfs_dir
, '/');
1379 if (slash
!= NULL
) {
1381 * Just want the dir, so discard the executable name.
1386 * newfs uses system() to find mkfs, so make sure
1387 * that the one we want to use is first on the
1388 * list. Don't free path_new upon success, as it
1389 * has become part of the environment.
1391 (void) fsck_asprintf(&path_new
, "PATH=%s:%s",
1392 mkfs_dir
, path_old
);
1393 if (putenv(path_new
) != 0) {
1402 * Bad search style, quietly return failure.
1405 (void) printf("calcsb: got bad style number %d\n",
1411 if (pipe(child_pipe
) < 0) {
1412 pfatal("calcsb: could not create pipe: %s\n", strerror(errno
));
1413 if (sizestr
!= NULL
)
1420 pfatal("calcsb: fork failed: %s\n", strerror(errno
));
1421 if (sizestr
!= NULL
)
1425 if (dup2(child_pipe
[TO_FSCK
], fileno(stdout
)) < 0) {
1427 "calcsb: could not rename file descriptor: %s\n",
1431 devnull
= open("/dev/null", O_WRONLY
);
1432 if (devnull
== -1) {
1433 (void) printf("calcsb: could not open /dev/null: %s\n",
1437 if (dup2(devnull
, fileno(stderr
)) < 0) {
1439 "calcsb: could not rename file descriptor: %s\n",
1443 (void) close(child_pipe
[FROM_CHILD
]);
1444 (void) execv(cmdline
[CMD_IDX
], cmdline
);
1445 (void) printf("calcsb: could not exec %s: %s\n",
1446 cmdline
[CMD_IDX
], strerror(errno
));
1453 (void) close(child_pipe
[TO_FSCK
]);
1454 if (sizestr
!= NULL
)
1457 pending
= sizeof (struct fs
);
1458 target
= (caddr_t
)fs
;
1460 transferred
= read(child_pipe
[FROM_CHILD
], target
, pending
);
1461 pending
-= transferred
;
1462 target
+= transferred
;
1463 } while ((pending
> 0) && (transferred
> 0));
1466 if (transferred
< 0)
1468 "calcsb: binary read of superblock from %s failed: %s\n",
1469 (style
== MKFS_STYLE
) ? "mkfs" : "newfs",
1470 (transferred
< 0) ? strerror(errno
) : "");
1473 "calcsb: short read of superblock from %s\n",
1474 (style
== MKFS_STYLE
) ? "mkfs" : "newfs");
1478 (void) close(child_pipe
[FROM_CHILD
]);
1481 if ((fs
->fs_magic
!= FS_MAGIC
) &&
1482 (fs
->fs_magic
!= MTB_UFS_MAGIC
))