* Copyright (c) 1980, 1986 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 5.19 (Berkeley) %G%";
char *rawname(), *unrawname(), *blockcheck(), *malloc();
void catch(), catchquit(), voidquit();
char *name
; /* device name */
char *fsname
; /* mounted filesystem name */
struct part
*next
; /* forward link of partitions on disk */
} *badlist
, **badnext
= &badlist
;
char *name
; /* disk base name */
struct disk
*next
; /* forward link for list of disks */
struct part
*part
; /* head of list of partitions on disk */
int pid
; /* If != 0, pid of proc working on */
int nrun
, ndisks
, maxrun
;
int pid
, passno
, sumstatus
;
register struct disk
*dk
, *nextdisk
;
register struct part
*pt
;
while (--argc
> 0 && **++argv
== '-') {
if (argv
[0][1] != '\0') {
printf("Alternate super block location: %d\n", bflag
);
if (!isdigit(argv
[1][0]))
errexit("-l flag requires a number\n");
if (!isdigit(argv
[1][0]))
errexit("-m flag requires a mode\n");
sscanf(*++argv
, "%o", &lfmode
);
errexit("bad mode to -m: %o\n", lfmode
);
printf("** lost+found creation mode %o\n", lfmode
);
errexit("%c option?\n", **argv
);
if (signal(SIGINT
, SIG_IGN
) != SIG_IGN
)
(void)signal(SIGINT
, catch);
(void)signal(SIGQUIT
, catchquit
);
for (passno
= 1; passno
<= 2; passno
++) {
errexit("Can't open checklist file: %s\n", _PATH_FSTAB
);
while ((fsp
= getfsent()) != 0) {
if (strcmp(fsp
->fs_type
, FSTAB_RW
) &&
strcmp(fsp
->fs_type
, FSTAB_RO
) &&
strcmp(fsp
->fs_type
, FSTAB_RQ
))
if (strcmp(fsp
->fs_vfstype
, "ufs"))
passno
== 1 && fsp
->fs_passno
== 1) {
name
= blockcheck(fsp
->fs_spec
);
} else if (passno
== 2 && fsp
->fs_passno
> 1) {
name
= blockcheck(fsp
->fs_spec
);
pwarn("BAD DISK NAME %s\n",
addpart(name
, fsp
->fs_file
);
for (passno
= 0; passno
< maxrun
; ++passno
) {
nextdisk
= nextdisk
->next
;
while ((pid
= wait(&status
)) != -1) {
for (dk
= disks
; dk
; dk
= dk
->next
)
printf("Unknown pid %d\n", pid
);
printf("%s (%s): EXITED WITH SIGNAL %d\n",
dk
->part
->name
, dk
->part
->fsname
,
if (status
.w_retcode
!= 0) {
sumstatus
|= status
.w_retcode
;
badnext
= &dk
->part
->next
;
dk
->part
= dk
->part
->next
;
dk
->part
= dk
->part
->next
;
} else if (nrun
< maxrun
&& nrun
< ndisks
) {
if ((nextdisk
= nextdisk
->next
) == NULL
)
if (nextdisk
->part
!= NULL
&&
printf("THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
badlist
->next
? "S" : "", "UNEXPECTED INCONSISTENCY:");
for (pt
= badlist
; pt
; pt
= pt
->next
)
printf("%s (%s)%s", pt
->name
, pt
->fsname
,
register struct disk
*dk
, **dkp
;
for (p
= name
+ strlen(name
) - 1; p
>= name
; --p
)
for (dk
= disks
, dkp
= &disks
; dk
; dkp
= &dk
->next
, dk
= dk
->next
) {
if (strncmp(dk
->name
, name
, len
) == 0 &&
if ((*dkp
= (struct disk
*)malloc(sizeof(struct disk
))) == NULL
)
errexit("out of memory");
if ((dk
->name
= malloc((unsigned int)len
+ 1)) == NULL
)
errexit("out of memory");
strncpy(dk
->name
, name
, len
);
struct disk
*dk
= finddisk(name
);
register struct part
*pt
, **ppt
= &dk
->part
;
for (pt
= dk
->part
; pt
; ppt
= &pt
->next
, pt
= pt
->next
)
if (strcmp(pt
->name
, name
) == 0) {
printf("%s in fstab more than once!\n", name
);
if ((*ppt
= (struct part
*)malloc(sizeof(struct part
))) == NULL
)
errexit("out of memory");
if ((pt
->name
= malloc((unsigned int)strlen(name
) + 1)) == NULL
)
errexit("out of memory");
if ((pt
->fsname
= malloc((unsigned int)strlen(fsname
) + 1)) == NULL
)
errexit("out of memory");
strcpy(pt
->fsname
, fsname
);
register struct disk
*dk
;
(void)signal(SIGQUIT
, voidquit
);
checkfilesys(dk
->part
->name
);
daddr_t n_ffree
, n_bfree
;
if (setup(filesys
) == 0) {
pfatal("CAN'T CHECK FILE SYSTEM.");
* 1: scan inodes tallying blocks used
printf("** Last Mounted on %s\n", sblock
.fs_fsmnt
);
printf("** Root file system\n");
printf("** Phase 1 - Check Blocks and Sizes\n");
* 1b: locate first references to duplicates, if any
pfatal("INTERNAL ERROR: dups with -p");
printf("** Phase 1b - Rescan For More DUPS\n");
* 2: traverse directories from root to mark all connected directories
printf("** Phase 2 - Check Pathnames\n");
* 3: scan inodes looking for disconnected directories
printf("** Phase 3 - Check Connectivity\n");
* 4: scan inodes looking for disconnected files; check reference counts
printf("** Phase 4 - Check Reference Counts\n");
* 5: check and repair resource counts in cylinder groups
printf("** Phase 5 - Check Cyl groups\n");
* print out summary statistics
n_ffree
= sblock
.fs_cstotal
.cs_nffree
;
n_bfree
= sblock
.fs_cstotal
.cs_nbfree
;
pwarn("%d files, %d used, %d free ",
n_files
, n_blks
, n_ffree
+ sblock
.fs_frag
* n_bfree
);
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
n_ffree
, n_bfree
, (float)(n_ffree
* 100) / sblock
.fs_dsize
);
(n_files
-= maxino
- ROOTINO
- sblock
.fs_cstotal
.cs_nifree
))
printf("%d files missing\n", n_files
);
n_blks
+= sblock
.fs_ncg
*
(cgdmin(&sblock
, 0) - cgsblock(&sblock
, 0));
n_blks
+= cgsblock(&sblock
, 0) - cgbase(&sblock
, 0);
n_blks
+= howmany(sblock
.fs_cssize
, sblock
.fs_fsize
);
if (n_blks
-= maxfsblock
- (n_ffree
+ sblock
.fs_frag
* n_bfree
))
printf("%d blocks missing\n", n_blks
);
printf("The following duplicate blocks remain:");
for (dp
= duplist
; dp
; dp
= dp
->next
)
printf("The following zero link count inodes remain:");
for (zlnp
= zlnhead
; zlnp
; zlnp
= zlnp
->next
)
printf(" %d,", zlnp
->zlncnt
);
zlnhead
= (struct zlncnt
*)0;
duplist
= (struct dups
*)0;
(void)time(&sblock
.fs_time
);
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
printf("\n***** REBOOT UNIX *****\n");
struct stat stslash
, stblock
, stchar
;
if (stat("/", &stslash
) < 0) {
printf("Can't stat root\n");
if (stat(name
, &stblock
) < 0) {
printf("Can't stat %s\n", name
);
if ((stblock
.st_mode
& S_IFMT
) == S_IFBLK
) {
if (stslash
.st_dev
== stblock
.st_rdev
) {
if (stat(raw
, &stchar
) < 0) {
printf("Can't stat %s\n", raw
);
if ((stchar
.st_mode
& S_IFMT
) == S_IFCHR
) {
printf("%s is not a character device\n", raw
);
} else if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
&& !retried
) {
printf("Can't make sense out of name %s\n", name
);
if ((dp
= rindex(name
, '/')) == 0)
if (stat(name
, &stb
) < 0)
if ((stb
.st_mode
& S_IFMT
) != S_IFCHR
)
(void)strcpy(dp
+ 1, dp
+ 2);
if ((dp
= rindex(name
, '/')) == 0)
(void)strcpy(rawbuf
, name
);
(void)strcat(rawbuf
, "/r");
(void)strcat(rawbuf
, dp
+ 1);