static char version
[] = "@(#)setup.c 3.1 (Berkeley) %G%";
daddr_t super
= bflag
? bflag
: SBLOCK
;
# define altsblock asblk.b_un.b_fs
if (stat("/", &statb
) < 0)
errexit("Can't stat root\n");
if (stat(dev
, &statb
) < 0) {
error("Can't stat %s\n", dev
);
if ((statb
.st_mode
& S_IFMT
) == S_IFBLK
)
else if ((statb
.st_mode
& S_IFMT
) == S_IFCHR
)
if (reply("file is not a block or character device; OK") == 0)
if (rootdev
== statb
.st_rdev
)
if ((dfile
.rfdes
= open(dev
, 0)) < 0) {
error("Can't open %s\n", dev
);
if (nflag
|| (dfile
.wfdes
= open(dev
, 1)) < 0) {
pfatal("NO WRITE ACCESS");
fixcg
= 0; inosumbad
= 0; offsumbad
= 0; frsumbad
= 0; sbsumbad
= 0;
n_files
= n_blks
= n_ffree
= n_bfree
= 0;
muldup
= enddup
= &duplist
[0];
* Read in the super block and its summary info.
if (bread(&dfile
, (char *)&sblock
, super
, (long)SBSIZE
) == 0)
* run a few consistency checks of the super block
if (sblock
.fs_magic
!= FS_MAGIC
)
{ badsb("MAGIC NUMBER WRONG"); return (0); }
{ badsb("NCG OUT OF RANGE"); return (0); }
if (sblock
.fs_cpg
< 1 || sblock
.fs_cpg
> MAXCPG
)
{ badsb("CPG OUT OF RANGE"); return (0); }
if (sblock
.fs_ncg
* sblock
.fs_cpg
< sblock
.fs_ncyl
||
(sblock
.fs_ncg
- 1) * sblock
.fs_cpg
>= sblock
.fs_ncyl
)
{ badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); }
if (sblock
.fs_sbsize
> SBSIZE
)
{ badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); }
* Set all possible fields that could differ, then do check
* of whole super block against an alternate super block.
* When an alternate super-block is specified this check is skipped.
if (getblk(&asblk
, cgsblock(&sblock
, sblock
.fs_ncg
- 1),
altsblock
.fs_link
= sblock
.fs_link
;
altsblock
.fs_rlink
= sblock
.fs_rlink
;
altsblock
.fs_time
= sblock
.fs_time
;
altsblock
.fs_cstotal
= sblock
.fs_cstotal
;
altsblock
.fs_cgrotor
= sblock
.fs_cgrotor
;
altsblock
.fs_fmod
= sblock
.fs_fmod
;
altsblock
.fs_clean
= sblock
.fs_clean
;
altsblock
.fs_ronly
= sblock
.fs_ronly
;
altsblock
.fs_flags
= sblock
.fs_flags
;
altsblock
.fs_maxcontig
= sblock
.fs_maxcontig
;
altsblock
.fs_minfree
= sblock
.fs_minfree
;
altsblock
.fs_rotdelay
= sblock
.fs_rotdelay
;
altsblock
.fs_maxbpg
= sblock
.fs_maxbpg
;
bcopy((char *)sblock
.fs_csp
, (char *)altsblock
.fs_csp
,
bcopy((char *)sblock
.fs_fsmnt
, (char *)altsblock
.fs_fsmnt
,
if (bcmp((char *)&sblock
, (char *)&altsblock
, (int)sblock
.fs_sbsize
))
{ badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); }
imax
= sblock
.fs_ncg
* sblock
.fs_ipg
;
n_bad
= cgsblock(&sblock
, 0); /* boot block plus dedicated sblock */
* read in the summary info.
for (i
= 0, j
= 0; i
< sblock
.fs_cssize
; i
+= sblock
.fs_bsize
, j
++) {
size
= sblock
.fs_cssize
- i
< sblock
.fs_bsize
?
sblock
.fs_cssize
- i
: sblock
.fs_bsize
;
sblock
.fs_csp
[j
] = (struct csum
*)calloc(1, (unsigned)size
);
if (bread(&dfile
, (char *)sblock
.fs_csp
[j
],
fsbtodb(&sblock
, sblock
.fs_csaddr
+ j
* sblock
.fs_frag
),
* allocate and initialize the necessary maps
bmapsz
= roundup(howmany(fmax
, NBBY
), sizeof(short));
blockmap
= calloc((unsigned)bmapsz
, sizeof (char));
printf("cannot alloc %d bytes for blockmap\n", bmapsz
);
freemap
= calloc((unsigned)bmapsz
, sizeof (char));
printf("cannot alloc %d bytes for freemap\n", bmapsz
);
statemap
= calloc((unsigned)(imax
+ 1), sizeof(char));
printf("cannot alloc %d bytes for statemap\n", imax
+ 1);
lncntp
= (short *)calloc((unsigned)(imax
+ 1), sizeof(short));
printf("cannot alloc %d bytes for lncntp\n",
(imax
+ 1) * sizeof(short));
for (c
= 0; c
< sblock
.fs_ncg
; c
++) {
cgd
= cgdmin(&sblock
, c
);
cgd
+= howmany(sblock
.fs_cssize
, sblock
.fs_fsize
);
d
= cgsblock(&sblock
, c
);
printf("BAD SUPER BLOCK: %s\n", s
);
pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n");
pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n");