Reviewed by: Don Lewis <Don.Lewis@tsc.tdk.com>
Submitted by: Kirk McKusick <mckusick@McKusick.COM> Obtained from: Mckusick, BSDI and a host of others This exactly matches Kirks sources imported under the Tag MCKUSICK2. These are as supplied by kirk with one small change needed to compile under freeBSD. Some FreeBSD patches will be added back, though many have been added to Kirk's sources already.
This commit is contained in:
parent
233fbe28b0
commit
d33e92f93e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=41474
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: dir.c,v 1.11 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -88,9 +85,9 @@ propagate()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0)
|
if (inp->i_parent == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE) {
|
inoinfo(inp->i_number)->ino_state == DSTATE) {
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
change++;
|
change++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +120,8 @@ dirscan(idesc)
|
|||||||
idesc->id_loc = 0;
|
idesc->id_loc = 0;
|
||||||
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
||||||
dsize = dp->d_reclen;
|
dsize = dp->d_reclen;
|
||||||
|
if (dsize > sizeof(dbuf))
|
||||||
|
dsize = sizeof(dbuf);
|
||||||
memmove(dbuf, dp, (size_t)dsize);
|
memmove(dbuf, dp, (size_t)dsize);
|
||||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||||
if (!newinofmt) {
|
if (!newinofmt) {
|
||||||
@ -235,8 +234,7 @@ dircheck(idesc, dp)
|
|||||||
int spaceleft;
|
int spaceleft;
|
||||||
|
|
||||||
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||||
if (dp->d_ino >= maxino ||
|
if (dp->d_reclen == 0 ||
|
||||||
dp->d_reclen == 0 ||
|
|
||||||
dp->d_reclen > spaceleft ||
|
dp->d_reclen > spaceleft ||
|
||||||
(dp->d_reclen & 0x3) != 0)
|
(dp->d_reclen & 0x3) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
@ -306,13 +304,40 @@ adjust(idesc, lcnt)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
int lcnt;
|
int lcnt;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
struct dinode *dp;
|
||||||
|
int saveresolved;
|
||||||
|
|
||||||
dp = ginode(idesc->id_number);
|
dp = ginode(idesc->id_number);
|
||||||
if (dp->di_nlink == lcnt) {
|
if (dp->di_nlink == lcnt) {
|
||||||
if (linkup(idesc->id_number, (ino_t)0) == 0)
|
/*
|
||||||
clri(idesc, "UNREF", 0);
|
* If we have not hit any unresolved problems, are running
|
||||||
} else {
|
* in preen mode, and are on a filesystem using soft updates,
|
||||||
|
* then just toss any partially allocated files.
|
||||||
|
*/
|
||||||
|
if (resolved && preen && usedsoftdep) {
|
||||||
|
clri(idesc, "UNREF", 1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The filesystem can be marked clean even if
|
||||||
|
* a file is not linked up, but is cleared.
|
||||||
|
* Hence, resolved should not be cleared when
|
||||||
|
* linkup is answered no, but clri is answered yes.
|
||||||
|
*/
|
||||||
|
saveresolved = resolved;
|
||||||
|
if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) {
|
||||||
|
resolved = saveresolved;
|
||||||
|
clri(idesc, "UNREF", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Account for the new reference created by linkup().
|
||||||
|
*/
|
||||||
|
dp = ginode(idesc->id_number);
|
||||||
|
lcnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lcnt != 0) {
|
||||||
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
||||||
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
||||||
pinode(idesc->id_number);
|
pinode(idesc->id_number);
|
||||||
@ -355,7 +380,7 @@ mkentry(idesc)
|
|||||||
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
||||||
dirp->d_reclen = newent.d_reclen;
|
dirp->d_reclen = newent.d_reclen;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
dirp->d_namlen = newent.d_namlen;
|
dirp->d_namlen = newent.d_namlen;
|
||||||
@ -388,16 +413,17 @@ chgino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dirp->d_ino = idesc->id_parent;
|
dirp->d_ino = idesc->id_parent;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
return (ALTERED|STOP);
|
return (ALTERED|STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
linkup(orphan, parentdir)
|
linkup(orphan, parentdir, name)
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
ino_t parentdir;
|
ino_t parentdir;
|
||||||
|
char *name;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
register struct dinode *dp;
|
||||||
int lostdir;
|
int lostdir;
|
||||||
@ -410,7 +436,7 @@ linkup(orphan, parentdir)
|
|||||||
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
||||||
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
||||||
pinode(orphan);
|
pinode(orphan);
|
||||||
if ((preen || usedsoftdep) && dp->di_size == 0)
|
if (preen && dp->di_size == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (RECONNECTED)\n");
|
printf(" (RECONNECTED)\n");
|
||||||
@ -431,6 +457,7 @@ linkup(orphan, parentdir)
|
|||||||
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
||||||
if (lfdir != 0) {
|
if (lfdir != 0) {
|
||||||
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
||||||
|
numdirs++;
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (CREATED)\n");
|
printf(" (CREATED)\n");
|
||||||
} else {
|
} else {
|
||||||
@ -466,21 +493,21 @@ linkup(orphan, parentdir)
|
|||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
idesc.id_number = oldlfdir;
|
idesc.id_number = oldlfdir;
|
||||||
adjust(&idesc, lncntp[oldlfdir] + 1);
|
adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1);
|
||||||
lncntp[oldlfdir] = 0;
|
inoinfo(oldlfdir)->ino_linkcnt = 0;
|
||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
}
|
}
|
||||||
if (statemap[lfdir] != DFOUND) {
|
if (inoinfo(lfdir)->ino_state != DFOUND) {
|
||||||
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
(void)lftempname(tempname, orphan);
|
(void)lftempname(tempname, orphan);
|
||||||
if (makeentry(lfdir, orphan, tempname) == 0) {
|
if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) {
|
||||||
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
lncntp[orphan]--;
|
inoinfo(orphan)->ino_linkcnt--;
|
||||||
if (lostdir) {
|
if (lostdir) {
|
||||||
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
||||||
parentdir != (ino_t)-1)
|
parentdir != (ino_t)-1)
|
||||||
@ -488,19 +515,11 @@ linkup(orphan, parentdir)
|
|||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
inodirty();
|
inodirty();
|
||||||
lncntp[lfdir]++;
|
inoinfo(lfdir)->ino_linkcnt++;
|
||||||
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
||||||
if (parentdir != (ino_t)-1) {
|
if (parentdir != (ino_t)-1) {
|
||||||
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
||||||
/*
|
inoinfo(parentdir)->ino_linkcnt++;
|
||||||
* The parent directory, because of the ordering
|
|
||||||
* guarantees, has had the link count incremented
|
|
||||||
* for the child, but no entry was made. This
|
|
||||||
* fixes the parent link count so that fsck does
|
|
||||||
* not need to be rerun.
|
|
||||||
*/
|
|
||||||
lncntp[parentdir]++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (preen == 0)
|
if (preen == 0)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -658,19 +677,20 @@ allocdir(parent, request, mode)
|
|||||||
dp->di_nlink = 2;
|
dp->di_nlink = 2;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (ino == ROOTINO) {
|
if (ino == ROOTINO) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
return(ino);
|
return(ino);
|
||||||
}
|
}
|
||||||
if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) {
|
if (inoinfo(parent)->ino_state != DSTATE &&
|
||||||
|
inoinfo(parent)->ino_state != DFOUND) {
|
||||||
freeino(ino);
|
freeino(ino);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
statemap[ino] = statemap[parent];
|
inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
|
||||||
if (statemap[ino] == DSTATE) {
|
if (inoinfo(ino)->ino_state == DSTATE) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
lncntp[parent]++;
|
inoinfo(parent)->ino_linkcnt++;
|
||||||
}
|
}
|
||||||
dp = ginode(parent);
|
dp = ginode(parent);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
|
112
sbin/fsck/fsck.8
112
sbin/fsck/fsck.8
@ -1,3 +1,4 @@
|
|||||||
|
.\"
|
||||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -10,7 +11,7 @@
|
|||||||
.\" notice, this list of conditions and the following disclaimer in the
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
.\" 3. All advertising materials mentioning features or use of this software
|
.\" 3. All advertising materials mentioning features or use of this software
|
||||||
.\" must display the following acknowledgment:
|
.\" must display the following acknowledgement:
|
||||||
.\" This product includes software developed by the University of
|
.\" This product includes software developed by the University of
|
||||||
.\" California, Berkeley and its contributors.
|
.\" California, Berkeley and its contributors.
|
||||||
.\" 4. Neither the name of the University nor the names of its contributors
|
.\" 4. Neither the name of the University nor the names of its contributors
|
||||||
@ -30,9 +31,8 @@
|
|||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
||||||
.\" $Id: fsck.8,v 1.10 1997/03/12 16:35:26 bde Exp $
|
|
||||||
.\"
|
.\"
|
||||||
.Dd May 9, 1995
|
.Dd November 15, 1996
|
||||||
.Dt FSCK 8
|
.Dt FSCK 8
|
||||||
.Os BSD 4
|
.Os BSD 4
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -43,24 +43,25 @@
|
|||||||
.Fl p
|
.Fl p
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
|
.Op Ar filesystem
|
||||||
|
.Ar ...
|
||||||
.Nm fsck
|
.Nm fsck
|
||||||
|
.Op Fl ny
|
||||||
.Op Fl b Ar block#
|
.Op Fl b Ar block#
|
||||||
.Op Fl c Ar level
|
.Op Fl c Ar level
|
||||||
.Op Fl l Ar maxparallel
|
.Op Fl l Ar maxparallel
|
||||||
.Op Fl y
|
|
||||||
.Op Fl n
|
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
.Op Ar filesystem
|
.Op Ar filesystem
|
||||||
.Ar ...
|
.Ar ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The first form of
|
The first form of
|
||||||
.Nm
|
.Nm fsck
|
||||||
preens a standard set of filesystems or the specified filesystems.
|
preens a standard set of filesystems or the specified filesystems.
|
||||||
It is normally used in the script
|
It is normally used in the script
|
||||||
.Pa /etc/rc
|
.Pa /etc/rc
|
||||||
during automatic reboot.
|
during automatic reboot.
|
||||||
Here
|
Here
|
||||||
.Nm
|
.Nm fsck
|
||||||
reads the table
|
reads the table
|
||||||
.Pa /etc/fstab
|
.Pa /etc/fstab
|
||||||
to determine which filesystems to check.
|
to determine which filesystems to check.
|
||||||
@ -73,22 +74,18 @@ running one process per disk drive.
|
|||||||
The disk drive containing each filesystem is inferred from the longest prefix
|
The disk drive containing each filesystem is inferred from the longest prefix
|
||||||
of the device name that ends in a digit; the remaining characters are assumed
|
of the device name that ends in a digit; the remaining characters are assumed
|
||||||
to be the partition designator.
|
to be the partition designator.
|
||||||
.Pp
|
In preening mode,
|
||||||
The clean flag of each filesystem's superblock is examined and only those filesystems that
|
filesystems that are marked clean are skipped.
|
||||||
are not marked clean are checked.
|
|
||||||
Filesystems are marked clean when they are unmounted,
|
Filesystems are marked clean when they are unmounted,
|
||||||
when they have been mounted read-only, or when
|
when they have been mounted read-only, or when
|
||||||
.Nm
|
.Nm fsck
|
||||||
runs on them successfully.
|
runs on them successfully.
|
||||||
If the
|
|
||||||
.Fl f
|
|
||||||
option is specified, the filesystems
|
|
||||||
will be checked regardless of the state of their clean flag.
|
|
||||||
.Pp
|
.Pp
|
||||||
The kernel takes care that only a restricted class of innocuous filesystem
|
The kernel takes care that only a restricted class of innocuous filesystem
|
||||||
inconsistencies can happen unless hardware or software failures intervene.
|
inconsistencies can happen unless hardware or software failures intervene.
|
||||||
These are limited to the following:
|
These are limited to the following:
|
||||||
.Bl -item -compact
|
.Pp
|
||||||
|
.Bl -item -compact -offset indent
|
||||||
.It
|
.It
|
||||||
Unreferenced inodes
|
Unreferenced inodes
|
||||||
.It
|
.It
|
||||||
@ -102,7 +99,7 @@ Counts in the super-block wrong
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
These are the only inconsistencies that
|
These are the only inconsistencies that
|
||||||
.Nm
|
.Nm fsck
|
||||||
with the
|
with the
|
||||||
.Fl p
|
.Fl p
|
||||||
option will correct; if it encounters other inconsistencies, it exits
|
option will correct; if it encounters other inconsistencies, it exits
|
||||||
@ -110,7 +107,7 @@ with an abnormal return status and an automatic reboot will then fail.
|
|||||||
For each corrected inconsistency one or more lines will be printed
|
For each corrected inconsistency one or more lines will be printed
|
||||||
identifying the filesystem on which the correction will take place,
|
identifying the filesystem on which the correction will take place,
|
||||||
and the nature of the correction. After successfully correcting a filesystem,
|
and the nature of the correction. After successfully correcting a filesystem,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will print the number of files on that filesystem,
|
will print the number of files on that filesystem,
|
||||||
the number of used and free blocks,
|
the number of used and free blocks,
|
||||||
and the percentage of fragmentation.
|
and the percentage of fragmentation.
|
||||||
@ -118,7 +115,7 @@ and the percentage of fragmentation.
|
|||||||
If sent a
|
If sent a
|
||||||
.Dv QUIT
|
.Dv QUIT
|
||||||
signal,
|
signal,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will finish the filesystem checks, then exit with an abnormal
|
will finish the filesystem checks, then exit with an abnormal
|
||||||
return status that causes an automatic reboot to fail.
|
return status that causes an automatic reboot to fail.
|
||||||
This is useful when you want to finish the filesystem checks during an
|
This is useful when you want to finish the filesystem checks during an
|
||||||
@ -128,7 +125,7 @@ but do not want the machine to come up multiuser after the checks complete.
|
|||||||
Without the
|
Without the
|
||||||
.Fl p
|
.Fl p
|
||||||
option,
|
option,
|
||||||
.Nm
|
.Nm fsck
|
||||||
audits and interactively repairs inconsistent conditions for filesystems.
|
audits and interactively repairs inconsistent conditions for filesystems.
|
||||||
If the filesystem is inconsistent the operator is prompted for concurrence
|
If the filesystem is inconsistent the operator is prompted for concurrence
|
||||||
before each correction is attempted.
|
before each correction is attempted.
|
||||||
@ -144,7 +141,7 @@ is to wait for the operator to respond
|
|||||||
or
|
or
|
||||||
.Li no .
|
.Li no .
|
||||||
If the operator does not have write permission on the filesystem
|
If the operator does not have write permission on the filesystem
|
||||||
.Nm
|
.Nm fsck
|
||||||
will default to a
|
will default to a
|
||||||
.Fl n
|
.Fl n
|
||||||
action.
|
action.
|
||||||
@ -158,38 +155,12 @@ and
|
|||||||
combined.
|
combined.
|
||||||
.Pp
|
.Pp
|
||||||
The following flags are interpreted by
|
The following flags are interpreted by
|
||||||
.Nm Ns .
|
.Nm fsck .
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl b
|
.It Fl b
|
||||||
Use the block specified immediately after the flag as
|
Use the block specified immediately after the flag as
|
||||||
the super block for the filesystem. Block 32 is usually
|
the super block for the filesystem. Block 32 is usually
|
||||||
an alternate super block.
|
an alternate super block.
|
||||||
.It Fl l
|
|
||||||
Limit the number of parallel checks to the number specified in the following
|
|
||||||
argument.
|
|
||||||
By default, the limit is the number of disks, running one process per disk.
|
|
||||||
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
|
||||||
at a time.
|
|
||||||
.It Fl m
|
|
||||||
Use the mode specified in octal immediately after the flag as the
|
|
||||||
permission bits to use when creating the
|
|
||||||
.Pa lost+found
|
|
||||||
directory rather than the default 1777.
|
|
||||||
In particular, systems that do not wish to have lost files accessible
|
|
||||||
by all users on the system should use a more restrictive
|
|
||||||
set of permissions such as 700.
|
|
||||||
.It Fl y
|
|
||||||
Assume a yes response to all questions asked by
|
|
||||||
.Nm Ns ;
|
|
||||||
this should be used with great caution as this is a free license
|
|
||||||
to continue after essentially unlimited trouble has been encountered.
|
|
||||||
.It Fl n
|
|
||||||
Assume a no response to all questions asked by
|
|
||||||
.Nm
|
|
||||||
except for
|
|
||||||
.Ql CONTINUE? ,
|
|
||||||
which is assumed to be affirmative;
|
|
||||||
do not open the filesystem for writing.
|
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Convert the filesystem to the specified level.
|
Convert the filesystem to the specified level.
|
||||||
Note that the level of a filesystem can only be raised.
|
Note that the level of a filesystem can only be raised.
|
||||||
@ -210,7 +181,7 @@ If maxcontig is equal to one, delete any existing segment maps.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
In interactive mode,
|
In interactive mode,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will list the conversion to be made
|
will list the conversion to be made
|
||||||
and ask whether the conversion should be done.
|
and ask whether the conversion should be done.
|
||||||
If a negative answer is given,
|
If a negative answer is given,
|
||||||
@ -223,10 +194,44 @@ are being converted at once.
|
|||||||
The format of a filesystem can be determined from the
|
The format of a filesystem can be determined from the
|
||||||
first line of output from
|
first line of output from
|
||||||
.Xr dumpfs 8 .
|
.Xr dumpfs 8 .
|
||||||
|
.It Fl f
|
||||||
|
Force
|
||||||
|
.Nm fsck
|
||||||
|
to check
|
||||||
|
.Sq clean
|
||||||
|
filesystems when preening.
|
||||||
|
.It Fl l
|
||||||
|
Limit the number of parallel checks to the number specified in the following
|
||||||
|
argument.
|
||||||
|
By default, the limit is the number of disks, running one process per disk.
|
||||||
|
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
||||||
|
at a time.
|
||||||
|
.It Fl m
|
||||||
|
Use the mode specified in octal immediately after the flag as the
|
||||||
|
permission bits to use when creating the
|
||||||
|
.Pa lost+found
|
||||||
|
directory rather than the default 1777.
|
||||||
|
In particular, systems that do not wish to have lost files accessible
|
||||||
|
by all users on the system should use a more restrictive
|
||||||
|
set of permissions such as 700.
|
||||||
|
.It Fl n
|
||||||
|
Assume a no response to all questions asked by
|
||||||
|
.Nm fsck
|
||||||
|
except for
|
||||||
|
.Ql CONTINUE? ,
|
||||||
|
which is assumed to be affirmative;
|
||||||
|
do not open the filesystem for writing.
|
||||||
|
.It Fl p
|
||||||
|
Preen filesystems (see above).
|
||||||
|
.It Fl y
|
||||||
|
Assume a yes response to all questions asked by
|
||||||
|
.Nm fsck ;
|
||||||
|
this should be used with great caution as this is a free license
|
||||||
|
to continue after essentially unlimited trouble has been encountered.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If no filesystems are given to
|
If no filesystems are given to
|
||||||
.Nm
|
.Nm fsck
|
||||||
then a default list of filesystems is read from
|
then a default list of filesystems is read from
|
||||||
the file
|
the file
|
||||||
.Pa /etc/fstab .
|
.Pa /etc/fstab .
|
||||||
@ -259,7 +264,7 @@ File pointing to unallocated inode.
|
|||||||
.It
|
.It
|
||||||
Inode number out of range.
|
Inode number out of range.
|
||||||
.It
|
.It
|
||||||
Holes in directories.
|
Directories with unallocated blocks (holes).
|
||||||
.It
|
.It
|
||||||
Dot or dot-dot not the first two entries of a directory
|
Dot or dot-dot not the first two entries of a directory
|
||||||
or having the wrong inode number.
|
or having the wrong inode number.
|
||||||
@ -296,14 +301,13 @@ contains default list of filesystems to check.
|
|||||||
.El
|
.El
|
||||||
.Sh DIAGNOSTICS
|
.Sh DIAGNOSTICS
|
||||||
The diagnostics produced by
|
The diagnostics produced by
|
||||||
.Nm
|
.Nm fsck
|
||||||
are fully enumerated and explained in Appendix A of
|
are fully enumerated and explained in Appendix A of
|
||||||
.Rs
|
.Rs
|
||||||
.%T "Fsck \- The UNIX File System Check Program"
|
.%T "Fsck \- The UNIX File System Check Program"
|
||||||
.Re
|
.Re
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr fs 5 ,
|
|
||||||
.Xr fstab 5 ,
|
.Xr fstab 5 ,
|
||||||
.Xr fsdb 8 ,
|
.Xr fs 5 ,
|
||||||
.Xr newfs 8 ,
|
.Xr newfs 8 ,
|
||||||
.Xr reboot 8
|
.Xr reboot 8
|
||||||
|
@ -42,16 +42,35 @@
|
|||||||
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
||||||
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
||||||
|
|
||||||
#ifndef BUFSIZ
|
/*
|
||||||
#define BUFSIZ 1024
|
* Each inode on the filesystem is described by the following structure.
|
||||||
#endif
|
* The linkcnt is initially set to the value in the inode. Each time it
|
||||||
|
* is found during the descent in passes 2, 3, and 4 the count is
|
||||||
|
* decremented. Any inodes whose count is non-zero after pass 4 needs to
|
||||||
|
* have its link count adjusted by the value remaining in ino_linkcnt.
|
||||||
|
*/
|
||||||
|
struct inostat {
|
||||||
|
char ino_state; /* state of inode, see below */
|
||||||
|
char ino_type; /* type of inode */
|
||||||
|
short ino_linkcnt; /* number of links not found */
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Inode states.
|
||||||
|
*/
|
||||||
#define USTATE 01 /* inode not allocated */
|
#define USTATE 01 /* inode not allocated */
|
||||||
#define FSTATE 02 /* inode is file */
|
#define FSTATE 02 /* inode is file */
|
||||||
#define DSTATE 03 /* inode is directory */
|
#define DSTATE 03 /* inode is directory */
|
||||||
#define DFOUND 04 /* directory found during descent */
|
#define DFOUND 04 /* directory found during descent */
|
||||||
#define DCLEAR 05 /* directory is to be cleared */
|
#define DCLEAR 05 /* directory is to be cleared */
|
||||||
#define FCLEAR 06 /* file is to be cleared */
|
#define FCLEAR 06 /* file is to be cleared */
|
||||||
|
/*
|
||||||
|
* Inode state information is contained on per cylinder group lists
|
||||||
|
* which are described by the following structure.
|
||||||
|
*/
|
||||||
|
struct inostatlist {
|
||||||
|
long il_numalloced; /* number of inodes allocated in this cg */
|
||||||
|
struct inostat *il_stat;/* inostat info for this cylinder group */
|
||||||
|
} *inostathead;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* buffer cache structure.
|
* buffer cache structure.
|
||||||
@ -163,11 +182,12 @@ struct inoinfo {
|
|||||||
ufs_daddr_t i_blks[1]; /* actually longer */
|
ufs_daddr_t i_blks[1]; /* actually longer */
|
||||||
} **inphead, **inpsort;
|
} **inphead, **inpsort;
|
||||||
long numdirs, listmax, inplast;
|
long numdirs, listmax, inplast;
|
||||||
|
long countdirs; /* number of directories we actually found */
|
||||||
|
|
||||||
char *cdevname; /* name of device being checked */
|
char *cdevname; /* name of device being checked */
|
||||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||||
long secsize; /* actual disk sector size */
|
long secsize; /* actual disk sector size */
|
||||||
char fflag; /* force fs check (ignore clean flag) */
|
char fflag; /* force check, ignore clean flag */
|
||||||
char nflag; /* assume a no response */
|
char nflag; /* assume a no response */
|
||||||
char yflag; /* assume a yes response */
|
char yflag; /* assume a yes response */
|
||||||
int bflag; /* location of alternate super block */
|
int bflag; /* location of alternate super block */
|
||||||
@ -177,23 +197,19 @@ int doinglevel1; /* converting to new cylinder group format */
|
|||||||
int doinglevel2; /* converting to new inode format */
|
int doinglevel2; /* converting to new inode format */
|
||||||
int newinofmt; /* filesystem has new inode format */
|
int newinofmt; /* filesystem has new inode format */
|
||||||
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
||||||
char resolved; /* cleared if unresolved changes => not clean */
|
|
||||||
char preen; /* just fix normal inconsistencies */
|
char preen; /* just fix normal inconsistencies */
|
||||||
|
char rerun; /* rerun fsck. Only used in non-preen mode */
|
||||||
|
int returntosingle; /* 1 => return to single user mode on exit */
|
||||||
|
char resolved; /* cleared if unresolved changes => not clean */
|
||||||
char hotroot; /* checking root device */
|
char hotroot; /* checking root device */
|
||||||
char havesb; /* superblock has been read */
|
char havesb; /* superblock has been read */
|
||||||
int fsmodified; /* 1 => write done to file system */
|
int fsmodified; /* 1 => write done to file system */
|
||||||
int fsreadfd; /* file descriptor for reading file system */
|
int fsreadfd; /* file descriptor for reading file system */
|
||||||
int fswritefd; /* file descriptor for writing file system */
|
int fswritefd; /* file descriptor for writing file system */
|
||||||
int returntosingle; /* return to single user mode */
|
|
||||||
int rerun; /* rerun fsck. Only used in non-preen mode */
|
|
||||||
|
|
||||||
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
||||||
char *blockmap; /* ptr to primary blk allocation map */
|
char *blockmap; /* ptr to primary blk allocation map */
|
||||||
ino_t maxino; /* number of inodes in file system */
|
ino_t maxino; /* number of inodes in file system */
|
||||||
ino_t lastino; /* last inode in use */
|
|
||||||
char *statemap; /* ptr to inode state table */
|
|
||||||
u_char *typemap; /* ptr to inode type table */
|
|
||||||
short *lncntp; /* ptr to link count table */
|
|
||||||
|
|
||||||
ino_t lfdir; /* lost & found directory inode number */
|
ino_t lfdir; /* lost & found directory inode number */
|
||||||
char *lfname; /* lost & found directory name */
|
char *lfname; /* lost & found directory name */
|
||||||
@ -219,6 +235,7 @@ struct dinode zino;
|
|||||||
|
|
||||||
struct fstab;
|
struct fstab;
|
||||||
|
|
||||||
|
|
||||||
void adjust __P((struct inodesc *, int lcnt));
|
void adjust __P((struct inodesc *, int lcnt));
|
||||||
ufs_daddr_t allocblk __P((long frags));
|
ufs_daddr_t allocblk __P((long frags));
|
||||||
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
||||||
@ -239,6 +256,7 @@ int chkrange __P((ufs_daddr_t blk, int cnt));
|
|||||||
void ckfini __P((int markclean));
|
void ckfini __P((int markclean));
|
||||||
int ckinode __P((struct dinode *dp, struct inodesc *));
|
int ckinode __P((struct dinode *dp, struct inodesc *));
|
||||||
void clri __P((struct inodesc *, char *type, int flag));
|
void clri __P((struct inodesc *, char *type, int flag));
|
||||||
|
int clearentry __P((struct inodesc *));
|
||||||
void direrror __P((ino_t ino, char *errmesg));
|
void direrror __P((ino_t ino, char *errmesg));
|
||||||
int dirscan __P((struct inodesc *));
|
int dirscan __P((struct inodesc *));
|
||||||
int dofix __P((struct inodesc *, char *msg));
|
int dofix __P((struct inodesc *, char *msg));
|
||||||
@ -262,7 +280,8 @@ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
|
|||||||
struct dinode *ginode __P((ino_t inumber));
|
struct dinode *ginode __P((ino_t inumber));
|
||||||
void inocleanup __P((void));
|
void inocleanup __P((void));
|
||||||
void inodirty __P((void));
|
void inodirty __P((void));
|
||||||
int linkup __P((ino_t orphan, ino_t parentdir));
|
struct inostat *inoinfo __P((ino_t inum));
|
||||||
|
int linkup __P((ino_t orphan, ino_t parentdir, char *name));
|
||||||
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
||||||
void panic __P((const char *fmt, ...));
|
void panic __P((const char *fmt, ...));
|
||||||
void pass1 __P((void));
|
void pass1 __P((void));
|
||||||
@ -278,6 +297,6 @@ void pinode __P((ino_t ino));
|
|||||||
void propagate __P((void));
|
void propagate __P((void));
|
||||||
void pwarn __P((const char *fmt, ...));
|
void pwarn __P((const char *fmt, ...));
|
||||||
int reply __P((char *question));
|
int reply __P((char *question));
|
||||||
void resetinodebuf __P((void));
|
void setinodebuf __P((ino_t));
|
||||||
int setup __P((char *dev));
|
int setup __P((char *dev));
|
||||||
void voidquit __P((int));
|
void voidquit __P((int));
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: inode.c,v 1.15 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -62,7 +58,8 @@ ckinode(dp, idesc)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
{
|
{
|
||||||
ufs_daddr_t *ap;
|
ufs_daddr_t *ap;
|
||||||
long ret, n, ndb, offset;
|
int ret;
|
||||||
|
long n, ndb, offset;
|
||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
quad_t remsize, sizepb;
|
quad_t remsize, sizepb;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
@ -74,7 +71,7 @@ ckinode(dp, idesc)
|
|||||||
idesc->id_filesize = dp->di_size;
|
idesc->id_filesize = dp->di_size;
|
||||||
mode = dp->di_mode & IFMT;
|
mode = dp->di_mode & IFMT;
|
||||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
||||||
(dp->di_size < sblock.fs_maxsymlinklen || dp->di_blocks == 0)))
|
dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dino = *dp;
|
dino = *dp;
|
||||||
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
||||||
@ -239,8 +236,16 @@ chkrange(blk, cnt)
|
|||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
if (blk < 0 || blk >= maxfsblock || cnt < 0 || cnt > maxfsblock - blk)
|
if (cnt <= 0 || blk <= 0 || blk > maxfsblock ||
|
||||||
|
cnt - 1 > maxfsblock - blk)
|
||||||
return (1);
|
return (1);
|
||||||
|
if (cnt > sblock.fs_frag ||
|
||||||
|
fragnum(&sblock, blk) + cnt > sblock.fs_frag) {
|
||||||
|
if (debug)
|
||||||
|
printf("bad size: blk %ld, offset %ld, size %ld\n",
|
||||||
|
blk, fragnum(&sblock, blk), cnt);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
c = dtog(&sblock, blk);
|
c = dtog(&sblock, blk);
|
||||||
if (blk < cgdmin(&sblock, c)) {
|
if (blk < cgdmin(&sblock, c)) {
|
||||||
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
||||||
@ -317,20 +322,29 @@ getnextinode(inumber)
|
|||||||
size = inobufsize;
|
size = inobufsize;
|
||||||
lastinum += fullcnt;
|
lastinum += fullcnt;
|
||||||
}
|
}
|
||||||
(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
|
/*
|
||||||
|
* If bread returns an error, it will already have zeroed
|
||||||
|
* out the buffer, so we do not need to do so here.
|
||||||
|
*/
|
||||||
|
(void)bread(fsreadfd, (char *)inodebuf, dblk, size);
|
||||||
dp = inodebuf;
|
dp = inodebuf;
|
||||||
}
|
}
|
||||||
return (dp++);
|
return (dp++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
resetinodebuf()
|
setinodebuf(inum)
|
||||||
|
ino_t inum;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (inum % sblock.fs_ipg != 0)
|
||||||
|
errx(EEXIT, "bad inode number %d to setinodebuf", inum);
|
||||||
startinum = 0;
|
startinum = 0;
|
||||||
nextino = 0;
|
nextino = inum;
|
||||||
lastinum = 0;
|
lastinum = inum;
|
||||||
readcnt = 0;
|
readcnt = 0;
|
||||||
|
if (inodebuf != NULL)
|
||||||
|
return;
|
||||||
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
||||||
fullcnt = inobufsize / sizeof(struct dinode);
|
fullcnt = inobufsize / sizeof(struct dinode);
|
||||||
readpercg = sblock.fs_ipg / fullcnt;
|
readpercg = sblock.fs_ipg / fullcnt;
|
||||||
@ -342,11 +356,8 @@ resetinodebuf()
|
|||||||
partialcnt = fullcnt;
|
partialcnt = fullcnt;
|
||||||
partialsize = inobufsize;
|
partialsize = inobufsize;
|
||||||
}
|
}
|
||||||
if (inodebuf == NULL &&
|
if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
||||||
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
|
||||||
errx(EEXIT, "cannot allocate space for inode buffer");
|
errx(EEXIT, "cannot allocate space for inode buffer");
|
||||||
while (nextino < ROOTINO)
|
|
||||||
(void)getnextinode(nextino);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -380,14 +391,11 @@ cacheino(dp, inumber)
|
|||||||
inp = (struct inoinfo *)
|
inp = (struct inoinfo *)
|
||||||
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
||||||
if (inp == NULL)
|
if (inp == NULL)
|
||||||
return;
|
errx(EEXIT, "cannot increase directory list");
|
||||||
inpp = &inphead[inumber % numdirs];
|
inpp = &inphead[inumber % numdirs];
|
||||||
inp->i_nexthash = *inpp;
|
inp->i_nexthash = *inpp;
|
||||||
*inpp = inp;
|
*inpp = inp;
|
||||||
if (inumber == ROOTINO)
|
inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
|
||||||
inp->i_parent = ROOTINO;
|
|
||||||
else
|
|
||||||
inp->i_parent = (ino_t)0;
|
|
||||||
inp->i_dotdot = (ino_t)0;
|
inp->i_dotdot = (ino_t)0;
|
||||||
inp->i_number = inumber;
|
inp->i_number = inumber;
|
||||||
inp->i_isize = dp->di_size;
|
inp->i_isize = dp->di_size;
|
||||||
@ -465,7 +473,7 @@ clri(idesc, type, flag)
|
|||||||
n_files--;
|
n_files--;
|
||||||
(void)ckinode(dp, idesc);
|
(void)ckinode(dp, idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
statemap[idesc->id_number] = USTATE;
|
inoinfo(idesc->id_number)->ino_state = USTATE;
|
||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,8 +484,10 @@ findname(idesc)
|
|||||||
{
|
{
|
||||||
register struct direct *dirp = idesc->id_dirp;
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
if (dirp->d_ino != idesc->id_parent)
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
|
}
|
||||||
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
||||||
return (STOP|FOUND);
|
return (STOP|FOUND);
|
||||||
}
|
}
|
||||||
@ -498,6 +508,20 @@ findino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
clearentry(idesc)
|
||||||
|
struct inodesc *idesc;
|
||||||
|
{
|
||||||
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
|
return (KEEPON);
|
||||||
|
}
|
||||||
|
dirp->d_ino = 0;
|
||||||
|
return (STOP|FOUND|ALTERED);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pinode(ino)
|
pinode(ino)
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
@ -534,14 +558,14 @@ blkerror(ino, type, blk)
|
|||||||
|
|
||||||
pfatal("%ld %s I=%lu", blk, type, ino);
|
pfatal("%ld %s I=%lu", blk, type, ino);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
switch (statemap[ino]) {
|
switch (inoinfo(ino)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
statemap[ino] = FCLEAR;
|
inoinfo(ino)->ino_state = FCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
statemap[ino] = DCLEAR;
|
inoinfo(ino)->ino_state = DCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
@ -549,7 +573,7 @@ blkerror(ino, type, blk)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
|
errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,10 +593,10 @@ allocino(request, type)
|
|||||||
|
|
||||||
if (request == 0)
|
if (request == 0)
|
||||||
request = ROOTINO;
|
request = ROOTINO;
|
||||||
else if (statemap[request] != USTATE)
|
else if (inoinfo(request)->ino_state != USTATE)
|
||||||
return (0);
|
return (0);
|
||||||
for (ino = request; ino < maxino; ino++)
|
for (ino = request; ino < maxino; ino++)
|
||||||
if (statemap[ino] == USTATE)
|
if (inoinfo(ino)->ino_state == USTATE)
|
||||||
break;
|
break;
|
||||||
if (ino == maxino)
|
if (ino == maxino)
|
||||||
return (0);
|
return (0);
|
||||||
@ -584,12 +608,12 @@ allocino(request, type)
|
|||||||
cgp->cg_cs.cs_nifree--;
|
cgp->cg_cs.cs_nifree--;
|
||||||
switch (type & IFMT) {
|
switch (type & IFMT) {
|
||||||
case IFDIR:
|
case IFDIR:
|
||||||
statemap[ino] = DSTATE;
|
inoinfo(ino)->ino_state = DSTATE;
|
||||||
cgp->cg_cs.cs_ndir++;
|
cgp->cg_cs.cs_ndir++;
|
||||||
break;
|
break;
|
||||||
case IFREG:
|
case IFREG:
|
||||||
case IFLNK:
|
case IFLNK:
|
||||||
statemap[ino] = FSTATE;
|
inoinfo(ino)->ino_state = FSTATE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (0);
|
return (0);
|
||||||
@ -598,11 +622,11 @@ allocino(request, type)
|
|||||||
dp = ginode(ino);
|
dp = ginode(ino);
|
||||||
dp->di_db[0] = allocblk((long)1);
|
dp->di_db[0] = allocblk((long)1);
|
||||||
if (dp->di_db[0] == 0) {
|
if (dp->di_db[0] == 0) {
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
dp->di_flags = 0;
|
|
||||||
dp->di_mode = type;
|
dp->di_mode = type;
|
||||||
|
dp->di_flags = 0;
|
||||||
dp->di_atime = time(NULL);
|
dp->di_atime = time(NULL);
|
||||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||||
dp->di_size = sblock.fs_fsize;
|
dp->di_size = sblock.fs_fsize;
|
||||||
@ -610,7 +634,7 @@ allocino(request, type)
|
|||||||
n_files++;
|
n_files++;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
typemap[ino] = IFTODT(type);
|
inoinfo(ino)->ino_type = IFTODT(type);
|
||||||
return (ino);
|
return (ino);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,6 +656,6 @@ freeino(ino)
|
|||||||
(void)ckinode(dp, &idesc);
|
(void)ckinode(dp, &idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
n_files--;
|
n_files--;
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,7 @@ static const char copyright[] =
|
|||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
||||||
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: main.c,v 1.14 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -56,11 +52,10 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
int returntosingle;
|
|
||||||
|
|
||||||
static int argtoi __P((int flag, char *req, char *str, int base));
|
static int argtoi __P((int flag, char *req, char *str, int base));
|
||||||
static int docheck __P((struct fstab *fsp));
|
static int docheck __P((struct fstab *fsp));
|
||||||
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
||||||
@ -74,12 +69,8 @@ main(argc, argv)
|
|||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
int ret, maxrun = 0;
|
int ret, maxrun = 0;
|
||||||
struct rlimit rlim;
|
struct rlimit rlimit;
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_DATA, &rlim) == 0) {
|
|
||||||
rlim.rlim_cur = rlim.rlim_max;
|
|
||||||
(void) setrlimit(RLIMIT_DATA, &rlim);
|
|
||||||
}
|
|
||||||
sync();
|
sync();
|
||||||
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@ -137,9 +128,24 @@ main(argc, argv)
|
|||||||
(void)signal(SIGINT, catch);
|
(void)signal(SIGINT, catch);
|
||||||
if (preen)
|
if (preen)
|
||||||
(void)signal(SIGQUIT, catchquit);
|
(void)signal(SIGQUIT, catchquit);
|
||||||
|
/*
|
||||||
|
* Push up our allowed memory limit so we can cope
|
||||||
|
* with huge filesystems.
|
||||||
|
*/
|
||||||
|
if (getrlimit(RLIMIT_DATA, &rlimit) == 0) {
|
||||||
|
rlimit.rlim_cur = rlimit.rlim_max;
|
||||||
|
(void)setrlimit(RLIMIT_DATA, &rlimit);
|
||||||
|
}
|
||||||
if (argc) {
|
if (argc) {
|
||||||
while (argc-- > 0)
|
while (argc-- > 0) {
|
||||||
(void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
|
char *path = blockcheck(*argv);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
pfatal("Can't check %s\n", *argv);
|
||||||
|
else
|
||||||
|
(void)checkfilesys(path, 0, 0L, 0);
|
||||||
|
++argv;
|
||||||
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
||||||
@ -203,16 +209,10 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
case 0:
|
case 0:
|
||||||
if (preen)
|
if (preen)
|
||||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||||
return (0);
|
/* fall through */
|
||||||
case -1:
|
case -1:
|
||||||
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
|
||||||
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
|
||||||
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
|
|
||||||
sblock.fs_cstotal.cs_nffree, sblock.fs_cstotal.cs_nbfree,
|
|
||||||
sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleared if any questions answered no. Used to decide if
|
* Cleared if any questions answered no. Used to decide if
|
||||||
* the superblock should be marked clean.
|
* the superblock should be marked clean.
|
||||||
@ -304,7 +304,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
muldup = (struct dups *)0;
|
muldup = (struct dups *)0;
|
||||||
inocleanup();
|
inocleanup();
|
||||||
if (fsmodified) {
|
if (fsmodified) {
|
||||||
(void)time(&sblock.fs_time);
|
sblock.fs_time = time(NULL);
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (cvtlevel && sblk.b_dirty) {
|
if (cvtlevel && sblk.b_dirty) {
|
||||||
@ -329,12 +329,13 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
resolved = 0;
|
resolved = 0;
|
||||||
}
|
}
|
||||||
ckfini(resolved);
|
ckfini(resolved);
|
||||||
free(blockmap);
|
|
||||||
free(statemap);
|
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
|
||||||
free((char *)lncntp);
|
if (inostathead[cylno].il_stat != NULL)
|
||||||
if (!fsmodified)
|
free((char *)inostathead[cylno].il_stat);
|
||||||
return (0);
|
free((char *)inostathead);
|
||||||
if (!preen)
|
inostathead = NULL;
|
||||||
|
if (fsmodified && !preen)
|
||||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
||||||
if (rerun)
|
if (rerun)
|
||||||
printf("\n***** PLEASE RERUN FSCK *****\n");
|
printf("\n***** PLEASE RERUN FSCK *****\n");
|
||||||
@ -354,6 +355,8 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
if (!fsmodified)
|
||||||
|
return (0);
|
||||||
if (!preen)
|
if (!preen)
|
||||||
printf("\n***** REBOOT NOW *****\n");
|
printf("\n***** REBOOT NOW *****\n");
|
||||||
sync();
|
sync();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass1.c,v 1.11 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -52,14 +49,17 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
static ufs_daddr_t badblk;
|
static ufs_daddr_t badblk;
|
||||||
static ufs_daddr_t dupblk;
|
static ufs_daddr_t dupblk;
|
||||||
|
static ino_t lastino; /* last inode in use */
|
||||||
|
|
||||||
static void checkinode __P((ino_t inumber, struct inodesc *));
|
static void checkinode __P((ino_t inumber, struct inodesc *));
|
||||||
|
|
||||||
void
|
void
|
||||||
pass1()
|
pass1()
|
||||||
{
|
{
|
||||||
|
u_int8_t *cp;
|
||||||
ino_t inumber;
|
ino_t inumber;
|
||||||
int c, i, cgd;
|
int c, i, cgd, inosused;
|
||||||
|
struct inostat *info;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,15 +81,84 @@ pass1()
|
|||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass1check;
|
idesc.id_func = pass1check;
|
||||||
inumber = 0;
|
|
||||||
n_files = n_blks = 0;
|
n_files = n_blks = 0;
|
||||||
resetinodebuf();
|
|
||||||
for (c = 0; c < sblock.fs_ncg; c++) {
|
for (c = 0; c < sblock.fs_ncg; c++) {
|
||||||
for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
|
inumber = c * sblock.fs_ipg;
|
||||||
if (inumber < ROOTINO)
|
setinodebuf(inumber);
|
||||||
|
inosused = sblock.fs_ipg;
|
||||||
|
/*
|
||||||
|
* If we are using soft updates, then we can trust the
|
||||||
|
* cylinder group inode allocation maps to tell us which
|
||||||
|
* inodes are allocated. We will scan the used inode map
|
||||||
|
* to find the inodes that are really in use, and then
|
||||||
|
* read only those inodes in from disk.
|
||||||
|
*/
|
||||||
|
if (preen && usedsoftdep) {
|
||||||
|
getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
|
||||||
|
if (!cg_chkmagic(&cgrp))
|
||||||
|
pfatal("CG %d: BAD MAGIC NUMBER\n", c);
|
||||||
|
cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY];
|
||||||
|
for ( ; inosused > 0; inosused -= NBBY, cp--) {
|
||||||
|
if (*cp == 0)
|
||||||
|
continue;
|
||||||
|
for (i = 1 << (NBBY - 1); i > 0; i >>= 1) {
|
||||||
|
if (*cp & i)
|
||||||
|
break;
|
||||||
|
inosused--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Allocate inoinfo structures for the allocated inodes.
|
||||||
|
*/
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
|
/*
|
||||||
|
* Scan the allocated inodes.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < inosused; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO) {
|
||||||
|
(void)getnextinode(inumber);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
checkinode(inumber, &idesc);
|
checkinode(inumber, &idesc);
|
||||||
}
|
}
|
||||||
|
lastino += 1;
|
||||||
|
if (inosused < sblock.fs_ipg || inumber == lastino)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* If we were not able to determine in advance which inodes
|
||||||
|
* were in use, then reduce the size of the inoinfo structure
|
||||||
|
* to the size necessary to describe the inodes that we
|
||||||
|
* really found.
|
||||||
|
*/
|
||||||
|
inosused = lastino - (c * sblock.fs_ipg);
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
}
|
}
|
||||||
freeinodebuf();
|
freeinodebuf();
|
||||||
}
|
}
|
||||||
@ -120,7 +189,7 @@ checkinode(inumber, idesc)
|
|||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastino = inumber;
|
lastino = inumber;
|
||||||
@ -158,8 +227,7 @@ checkinode(inumber, idesc)
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
symbuf[dp->di_size] = 0;
|
symbuf[dp->di_size] = 0;
|
||||||
printf("convert symlink %lu(%s) of size %ld\n",
|
printf("convert symlink %lu(%s) of size %ld\n",
|
||||||
(u_long)inumber, symbuf,
|
(u_long)inumber, symbuf, (long)dp->di_size);
|
||||||
(long)dp->di_size);
|
|
||||||
}
|
}
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
||||||
@ -170,8 +238,7 @@ checkinode(inumber, idesc)
|
|||||||
* Fake ndb value so direct/indirect block checks below
|
* Fake ndb value so direct/indirect block checks below
|
||||||
* will detect any garbage after symlink string.
|
* will detect any garbage after symlink string.
|
||||||
*/
|
*/
|
||||||
if (dp->di_size < sblock.fs_maxsymlinklen ||
|
if (dp->di_size < sblock.fs_maxsymlinklen) {
|
||||||
dp->di_blocks == 0) {
|
|
||||||
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
||||||
if (ndb > NDADDR) {
|
if (ndb > NDADDR) {
|
||||||
j = ndb - NDADDR;
|
j = ndb - NDADDR;
|
||||||
@ -200,7 +267,7 @@ checkinode(inumber, idesc)
|
|||||||
if (ftypeok(dp) == 0)
|
if (ftypeok(dp) == 0)
|
||||||
goto unknown;
|
goto unknown;
|
||||||
n_files++;
|
n_files++;
|
||||||
lncntp[inumber] = dp->di_nlink;
|
inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
|
||||||
if (dp->di_nlink <= 0) {
|
if (dp->di_nlink <= 0) {
|
||||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||||
if (zlnp == NULL) {
|
if (zlnp == NULL) {
|
||||||
@ -217,13 +284,14 @@ checkinode(inumber, idesc)
|
|||||||
}
|
}
|
||||||
if (mode == IFDIR) {
|
if (mode == IFDIR) {
|
||||||
if (dp->di_size == 0)
|
if (dp->di_size == 0)
|
||||||
statemap[inumber] = DCLEAR;
|
inoinfo(inumber)->ino_state = DCLEAR;
|
||||||
else
|
else
|
||||||
statemap[inumber] = DSTATE;
|
inoinfo(inumber)->ino_state = DSTATE;
|
||||||
cacheino(dp, inumber);
|
cacheino(dp, inumber);
|
||||||
|
countdirs++;
|
||||||
} else
|
} else
|
||||||
statemap[inumber] = FSTATE;
|
inoinfo(inumber)->ino_state = FSTATE;
|
||||||
typemap[inumber] = IFTODT(mode);
|
inoinfo(inumber)->ino_type = IFTODT(mode);
|
||||||
if (doinglevel2 &&
|
if (doinglevel2 &&
|
||||||
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
@ -251,9 +319,9 @@ checkinode(inumber, idesc)
|
|||||||
return;
|
return;
|
||||||
unknown:
|
unknown:
|
||||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||||
statemap[inumber] = FCLEAR;
|
inoinfo(inumber)->ino_state = FCLEAR;
|
||||||
if (reply("CLEAR") == 1) {
|
if (reply("CLEAR") == 1) {
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -72,7 +69,7 @@ pass1b()
|
|||||||
if (dp == NULL)
|
if (dp == NULL)
|
||||||
continue;
|
continue;
|
||||||
idesc.id_number = inumber;
|
idesc.id_number = inumber;
|
||||||
if (statemap[inumber] != USTATE &&
|
if (inoinfo(inumber)->ino_state != USTATE &&
|
||||||
(ckinode(dp, &idesc) & STOP))
|
(ckinode(dp, &idesc) & STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -64,7 +62,7 @@ pass2()
|
|||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
char pathbuf[MAXPATHLEN + 1];
|
char pathbuf[MAXPATHLEN + 1];
|
||||||
|
|
||||||
switch (statemap[ROOTINO]) {
|
switch (inoinfo(ROOTINO)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
pfatal("ROOT INODE UNALLOCATED");
|
pfatal("ROOT INODE UNALLOCATED");
|
||||||
@ -113,12 +111,13 @@ pass2()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
|
errx(EEXIT, "BAD STATE %d FOR ROOT INODE",
|
||||||
|
inoinfo(ROOTINO)->ino_state);
|
||||||
}
|
}
|
||||||
statemap[ROOTINO] = DFOUND;
|
inoinfo(ROOTINO)->ino_state = DFOUND;
|
||||||
if (newinofmt) {
|
if (newinofmt) {
|
||||||
statemap[WINO] = FSTATE;
|
inoinfo(WINO)->ino_state = FSTATE;
|
||||||
typemap[WINO] = DT_WHT;
|
inoinfo(WINO)->ino_type = DT_WHT;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Sort the directory list into disk block order.
|
* Sort the directory list into disk block order.
|
||||||
@ -181,9 +180,9 @@ pass2()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0 || inp->i_isize == 0)
|
if (inp->i_parent == 0 || inp->i_isize == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE)
|
inoinfo(inp->i_number)->ino_state == DSTATE)
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
if (inp->i_dotdot == inp->i_parent ||
|
if (inp->i_dotdot == inp->i_parent ||
|
||||||
inp->i_dotdot == (ino_t)-1)
|
inp->i_dotdot == (ino_t)-1)
|
||||||
continue;
|
continue;
|
||||||
@ -193,15 +192,15 @@ pass2()
|
|||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fileerror(inp->i_parent, inp->i_number,
|
fileerror(inp->i_parent, inp->i_number,
|
||||||
"BAD INODE NUMBER FOR '..'");
|
"BAD INODE NUMBER FOR '..'");
|
||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
lncntp[inp->i_dotdot]++;
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
inp->i_dotdot = inp->i_parent;
|
inp->i_dotdot = inp->i_parent;
|
||||||
(void)changeino(inp->i_number, "..", inp->i_parent);
|
(void)changeino(inp->i_number, "..", inp->i_parent);
|
||||||
}
|
}
|
||||||
@ -228,7 +227,7 @@ pass2check(idesc)
|
|||||||
* If converting, set directory entry type.
|
* If converting, set directory entry type.
|
||||||
*/
|
*/
|
||||||
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -284,7 +283,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = entrysize;
|
proto.d_reclen = entrysize;
|
||||||
memmove(dirp, &proto, (size_t)entrysize);
|
memmove(dirp, &proto, (size_t)entrysize);
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
||||||
memset(dirp, 0, (size_t)n);
|
memset(dirp, 0, (size_t)n);
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
@ -319,7 +318,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = dirp->d_reclen - n;
|
proto.d_reclen = dirp->d_reclen - n;
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + n);
|
dirp = (struct direct *)((char *)(dirp) + n);
|
||||||
memset(dirp, 0, (size_t)proto.d_reclen);
|
memset(dirp, 0, (size_t)proto.d_reclen);
|
||||||
dirp->d_reclen = proto.d_reclen;
|
dirp->d_reclen = proto.d_reclen;
|
||||||
@ -356,7 +355,7 @@ pass2check(idesc)
|
|||||||
}
|
}
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
if (dirp->d_ino != 0)
|
if (dirp->d_ino != 0)
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
return (ret|KEEPON);
|
return (ret|KEEPON);
|
||||||
chk2:
|
chk2:
|
||||||
if (dirp->d_ino == 0)
|
if (dirp->d_ino == 0)
|
||||||
@ -394,7 +393,7 @@ pass2check(idesc)
|
|||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
} else {
|
} else {
|
||||||
again:
|
again:
|
||||||
switch (statemap[dirp->d_ino]) {
|
switch (inoinfo(dirp->d_ino)->ino_state) {
|
||||||
case USTATE:
|
case USTATE:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
@ -406,7 +405,7 @@ pass2check(idesc)
|
|||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
if (statemap[dirp->d_ino] == FCLEAR)
|
if (inoinfo(dirp->d_ino)->ino_state == FCLEAR)
|
||||||
errmsg = "DUP/BAD";
|
errmsg = "DUP/BAD";
|
||||||
else if (!preen && !usedsoftdep)
|
else if (!preen && !usedsoftdep)
|
||||||
errmsg = "ZERO LENGTH DIRECTORY";
|
errmsg = "ZERO LENGTH DIRECTORY";
|
||||||
@ -418,14 +417,14 @@ pass2check(idesc)
|
|||||||
if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
dp = ginode(dirp->d_ino);
|
dp = ginode(dirp->d_ino);
|
||||||
statemap[dirp->d_ino] =
|
inoinfo(dirp->d_ino)->ino_state =
|
||||||
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
||||||
lncntp[dirp->d_ino] = dp->di_nlink;
|
inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink;
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
if (statemap[idesc->id_number] == DFOUND)
|
if (inoinfo(idesc->id_number)->ino_state == DFOUND)
|
||||||
statemap[dirp->d_ino] = DFOUND;
|
inoinfo(dirp->d_ino)->ino_state = DFOUND;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
@ -439,10 +438,10 @@ pass2check(idesc)
|
|||||||
namebuf);
|
namebuf);
|
||||||
if (preen) {
|
if (preen) {
|
||||||
printf(" (REMOVED)\n");
|
printf(" (REMOVED)\n");
|
||||||
n = 1;
|
n = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idesc->id_entryno > 2)
|
if (idesc->id_entryno > 2)
|
||||||
@ -450,19 +449,20 @@ pass2check(idesc)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) {
|
if (newinofmt &&
|
||||||
|
dirp->d_type != inoinfo(dirp->d_ino)->ino_type) {
|
||||||
fileerror(idesc->id_number, dirp->d_ino,
|
fileerror(idesc->id_number, dirp->d_ino,
|
||||||
"BAD TYPE VALUE");
|
"BAD TYPE VALUE");
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
if (reply("FIX") == 1)
|
if (reply("FIX") == 1)
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
statemap[dirp->d_ino], dirp->d_ino);
|
inoinfo(dirp->d_ino)->ino_state, dirp->d_ino);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
@ -32,45 +32,84 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
pass3()
|
pass3()
|
||||||
{
|
{
|
||||||
register struct inoinfo **inpp, *inp;
|
struct inoinfo *inp;
|
||||||
|
int loopcnt, inpindex, state;
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
int loopcnt;
|
struct inodesc idesc;
|
||||||
|
char namebuf[MAXNAMLEN+1];
|
||||||
|
|
||||||
for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) {
|
for (inpindex = inplast - 1; inpindex >= 0; inpindex--) {
|
||||||
inp = *inpp;
|
inp = inpsort[inpindex];
|
||||||
|
state = inoinfo(inp->i_number)->ino_state;
|
||||||
if (inp->i_number == ROOTINO ||
|
if (inp->i_number == ROOTINO ||
|
||||||
!(inp->i_parent == 0 || statemap[inp->i_number] == DSTATE))
|
(inp->i_parent != 0 && state != DSTATE))
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_number] == DCLEAR)
|
if (state == DCLEAR)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
|
* If we are running with soft updates and we come
|
||||||
|
* across unreferenced directories, we just leave
|
||||||
|
* them in DSTATE which will cause them to be pitched
|
||||||
|
* in pass 4.
|
||||||
|
*/
|
||||||
|
if (preen && resolved && usedsoftdep && state == DSTATE) {
|
||||||
|
if (inp->i_dotdot >= ROOTINO)
|
||||||
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (loopcnt = 0; ; loopcnt++) {
|
for (loopcnt = 0; ; loopcnt++) {
|
||||||
orphan = inp->i_number;
|
orphan = inp->i_number;
|
||||||
if (inp->i_parent == 0 ||
|
if (inp->i_parent == 0 ||
|
||||||
statemap[inp->i_parent] != DSTATE ||
|
inoinfo(inp->i_parent)->ino_state != DSTATE ||
|
||||||
loopcnt > numdirs)
|
loopcnt > countdirs)
|
||||||
break;
|
break;
|
||||||
inp = getinoinfo(inp->i_parent);
|
inp = getinoinfo(inp->i_parent);
|
||||||
}
|
}
|
||||||
(void)linkup(orphan, inp->i_dotdot);
|
if (loopcnt <= countdirs) {
|
||||||
inp->i_parent = inp->i_dotdot = lfdir;
|
if (linkup(orphan, inp->i_dotdot, NULL)) {
|
||||||
lncntp[lfdir]--;
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
statemap[orphan] = DFOUND;
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
|
propagate();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", orphan);
|
||||||
|
if (reply("RECONNECT") == 0)
|
||||||
|
continue;
|
||||||
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
|
idesc.id_type = DATA;
|
||||||
|
idesc.id_number = inp->i_parent;
|
||||||
|
idesc.id_parent = orphan;
|
||||||
|
idesc.id_func = findname;
|
||||||
|
idesc.id_name = namebuf;
|
||||||
|
if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0)
|
||||||
|
pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY");
|
||||||
|
if (linkup(orphan, inp->i_parent, namebuf)) {
|
||||||
|
idesc.id_func = clearentry;
|
||||||
|
if (ckinode(ginode(inp->i_parent), &idesc) & FOUND)
|
||||||
|
inoinfo(orphan)->ino_linkcnt++;
|
||||||
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
propagate();
|
propagate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -55,22 +53,27 @@ pass4()
|
|||||||
register struct zlncnt *zlnp;
|
register struct zlncnt *zlnp;
|
||||||
struct dinode *dp;
|
struct dinode *dp;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
int n;
|
int i, n, cg;
|
||||||
|
|
||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
for (inumber = ROOTINO; inumber <= lastino; inumber++) {
|
for (cg = 0; cg < sblock.fs_ncg; cg++) {
|
||||||
idesc.id_number = inumber;
|
inumber = cg * sblock.fs_ipg;
|
||||||
switch (statemap[inumber]) {
|
for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO)
|
||||||
|
continue;
|
||||||
|
idesc.id_number = inumber;
|
||||||
|
switch (inoinfo(inumber)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
n = lncntp[inumber];
|
n = inoinfo(inumber)->ino_linkcnt;
|
||||||
if (n)
|
if (n) {
|
||||||
adjust(&idesc, (short)n);
|
adjust(&idesc, (short)n);
|
||||||
else {
|
break;
|
||||||
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
|
}
|
||||||
|
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) {
|
||||||
if (zlnp->zlncnt == inumber) {
|
if (zlnp->zlncnt == inumber) {
|
||||||
zlnp->zlncnt = zlnhead->zlncnt;
|
zlnp->zlncnt = zlnhead->zlncnt;
|
||||||
zlnp = zlnhead;
|
zlnp = zlnhead;
|
||||||
@ -79,30 +82,31 @@ pass4()
|
|||||||
clri(&idesc, "UNREF", 1);
|
clri(&idesc, "UNREF", 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case DSTATE:
|
|
||||||
clri(&idesc, "UNREF", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DCLEAR:
|
|
||||||
dp = ginode(inumber);
|
|
||||||
if (dp->di_size == 0) {
|
|
||||||
clri(&idesc, "ZERO LENGTH", 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DSTATE:
|
||||||
|
clri(&idesc, "UNREF", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DCLEAR:
|
||||||
|
dp = ginode(inumber);
|
||||||
|
if (dp->di_size == 0) {
|
||||||
|
clri(&idesc, "ZERO LENGTH", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case FCLEAR:
|
||||||
|
clri(&idesc, "BAD/DUP", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USTATE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
|
inoinfo(inumber)->ino_state, inumber);
|
||||||
}
|
}
|
||||||
/* fall through */
|
|
||||||
case FCLEAR:
|
|
||||||
clri(&idesc, "BAD/DUP", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USTATE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
|
||||||
statemap[inumber], inumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass5.c,v 1.13 1998/08/04 09:19:03 phk Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -52,7 +49,7 @@ static const char rcsid[] =
|
|||||||
void
|
void
|
||||||
pass5()
|
pass5()
|
||||||
{
|
{
|
||||||
int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
|
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
|
||||||
int inomapsize, blkmapsize;
|
int inomapsize, blkmapsize;
|
||||||
struct fs *fs = &sblock;
|
struct fs *fs = &sblock;
|
||||||
struct cg *cg = &cgrp;
|
struct cg *cg = &cgrp;
|
||||||
@ -66,7 +63,7 @@ pass5()
|
|||||||
register struct cg *newcg = (struct cg *)buf;
|
register struct cg *newcg = (struct cg *)buf;
|
||||||
struct ocg *ocg = (struct ocg *)buf;
|
struct ocg *ocg = (struct ocg *)buf;
|
||||||
|
|
||||||
statemap[WINO] = USTATE;
|
inoinfo(WINO)->ino_state = USTATE;
|
||||||
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
||||||
newcg->cg_niblk = fs->fs_ipg;
|
newcg->cg_niblk = fs->fs_ipg;
|
||||||
if (cvtlevel >= 3) {
|
if (cvtlevel >= 3) {
|
||||||
@ -207,8 +204,8 @@ pass5()
|
|||||||
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
||||||
ocg->cg_magic = CG_MAGIC;
|
ocg->cg_magic = CG_MAGIC;
|
||||||
j = fs->fs_ipg * c;
|
j = fs->fs_ipg * c;
|
||||||
for (i = 0; i < fs->fs_ipg; j++, i++) {
|
for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
|
||||||
switch (statemap[j]) {
|
switch (inoinfo(j)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
break;
|
break;
|
||||||
@ -229,7 +226,7 @@ pass5()
|
|||||||
if (j < ROOTINO)
|
if (j < ROOTINO)
|
||||||
break;
|
break;
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
||||||
statemap[j], j);
|
inoinfo(j)->ino_state, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
@ -325,7 +322,7 @@ pass5()
|
|||||||
if (cg_inosused(cg)[i] & (1 << k))
|
if (cg_inosused(cg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
||||||
c * fs->fs_ipg + i * 8 + k);
|
c * fs->fs_ipg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < blkmapsize; i++) {
|
for (i = 0; i < blkmapsize; i++) {
|
||||||
@ -338,7 +335,7 @@ pass5()
|
|||||||
if (cg_blksfree(newcg)[i] & (1 << k))
|
if (cg_blksfree(newcg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
||||||
c * fs->fs_fpg + i * 8 + k);
|
c * fs->fs_fpg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,24 +352,7 @@ pass5()
|
|||||||
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
||||||
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
||||||
fs->fs_ronly = 0;
|
fs->fs_ronly = 0;
|
||||||
|
fs->fs_fmod = 0;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (fs->fs_fmod != 0) {
|
|
||||||
pwarn("MODIFIED FLAG SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_fmod = 0;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fs->fs_clean == 0) {
|
|
||||||
pwarn("CLEAN FLAG NOT SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_clean = 1;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -46,7 +42,7 @@ static const char rcsid[] =
|
|||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <errno.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -93,7 +89,8 @@ checkfstab(preen, maxrun, docheck, chkit)
|
|||||||
sumstatus = 0;
|
sumstatus = 0;
|
||||||
for (passno = 1; passno <= 2; passno++) {
|
for (passno = 1; passno <= 2; passno++) {
|
||||||
if (setfsent() == 0) {
|
if (setfsent() == 0) {
|
||||||
warnx("can't open checklist file: %s", _PATH_FSTAB);
|
fprintf(stderr, "Can't open checklist file: %s\n",
|
||||||
|
_PATH_FSTAB);
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
while ((fsp = getfsent()) != 0) {
|
while ((fsp = getfsent()) != 0) {
|
||||||
@ -222,11 +219,15 @@ finddisk(name)
|
|||||||
dk->name[len] == 0)
|
dk->name[len] == 0)
|
||||||
return (dk);
|
return (dk);
|
||||||
}
|
}
|
||||||
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL)
|
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
dk = *dkp;
|
dk = *dkp;
|
||||||
if ((dk->name = malloc(len + 1)) == NULL)
|
if ((dk->name = malloc(len + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strncpy(dk->name, name, len);
|
(void)strncpy(dk->name, name, len);
|
||||||
dk->name[len] = '\0';
|
dk->name[len] = '\0';
|
||||||
dk->part = NULL;
|
dk->part = NULL;
|
||||||
@ -249,14 +250,20 @@ addpart(name, fsname, auxdata)
|
|||||||
printf("%s in fstab more than once!\n", name);
|
printf("%s in fstab more than once!\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL)
|
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
pt = *ppt;
|
pt = *ppt;
|
||||||
if ((pt->name = malloc(strlen(name) + 1)) == NULL)
|
if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->name, name);
|
(void)strcpy(pt->name, name);
|
||||||
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL)
|
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->fsname, fsname);
|
(void)strcpy(pt->fsname, fsname);
|
||||||
pt->next = NULL;
|
pt->next = NULL;
|
||||||
pt->auxdata = auxdata;
|
pt->auxdata = auxdata;
|
||||||
@ -271,7 +278,7 @@ startdisk(dk, checkit)
|
|||||||
|
|
||||||
dk->pid = fork();
|
dk->pid = fork();
|
||||||
if (dk->pid < 0) {
|
if (dk->pid < 0) {
|
||||||
warn("fork");
|
perror("fork");
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
if (dk->pid == 0)
|
if (dk->pid == 0)
|
||||||
@ -287,19 +294,17 @@ blockcheck(origname)
|
|||||||
struct stat stslash, stblock, stchar;
|
struct stat stslash, stblock, stchar;
|
||||||
char *newname, *raw;
|
char *newname, *raw;
|
||||||
struct fstab *fsinfo;
|
struct fstab *fsinfo;
|
||||||
int retried = 0, l;
|
int retried = 0, len;
|
||||||
|
|
||||||
hotroot = 0;
|
hotroot = 0;
|
||||||
if (stat("/", &stslash) < 0) {
|
if (stat("/", &stslash) < 0) {
|
||||||
warn("/");
|
printf("Can't stat /: %s\n", strerror(errno));
|
||||||
printf("Can't stat root\n");
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
newname = origname;
|
newname = origname;
|
||||||
retry:
|
retry:
|
||||||
if (stat(newname, &stblock) < 0) {
|
if (stat(newname, &stblock) < 0) {
|
||||||
warn("%s", newname);
|
printf("Can't stat %s: %s\n", newname, strerror(errno));
|
||||||
printf("Can't stat %s\n", newname);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
||||||
@ -307,8 +312,7 @@ blockcheck(origname)
|
|||||||
hotroot++;
|
hotroot++;
|
||||||
raw = rawname(newname);
|
raw = rawname(newname);
|
||||||
if (stat(raw, &stchar) < 0) {
|
if (stat(raw, &stchar) < 0) {
|
||||||
warn("%s", raw);
|
printf("Can't stat %s: %s\n", raw, strerror(errno));
|
||||||
printf("Can't stat %s\n", raw);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
||||||
@ -318,15 +322,15 @@ blockcheck(origname)
|
|||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
||||||
newname = unrawname(origname);
|
newname = unrawname(newname);
|
||||||
retried++;
|
retried++;
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
||||||
l = strlen(origname) - 1;
|
len = strlen(origname) - 1;
|
||||||
if (l > 0 && origname[l] == '/')
|
if (len > 0 && origname[len] == '/')
|
||||||
/* remove trailing slash */
|
/* remove trailing slash */
|
||||||
origname[l] = '\0';
|
origname[len] = '\0';
|
||||||
if(!(fsinfo=getfsfile(origname))) {
|
if ((fsinfo = getfsfile(origname)) == NULL) {
|
||||||
printf("Can't resolve %s to character special device",
|
printf("Can't resolve %s to character special device",
|
||||||
origname);
|
origname);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -32,16 +32,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: setup.c,v 1.11 1998/06/15 07:07:21 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#define DKTYPENAMES
|
#define DKTYPENAMES
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
@ -82,7 +79,7 @@ setup(dev)
|
|||||||
|
|
||||||
havesb = 0;
|
havesb = 0;
|
||||||
fswritefd = -1;
|
fswritefd = -1;
|
||||||
skipclean = preen;
|
skipclean = fflag ? 0 : preen;
|
||||||
if (stat(dev, &statb) < 0) {
|
if (stat(dev, &statb) < 0) {
|
||||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||||
return (0);
|
return (0);
|
||||||
@ -114,8 +111,7 @@ setup(dev)
|
|||||||
asblk.b_un.b_buf = malloc(SBSIZE);
|
asblk.b_un.b_buf = malloc(SBSIZE);
|
||||||
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
||||||
errx(EEXIT, "cannot allocate space for superblock");
|
errx(EEXIT, "cannot allocate space for superblock");
|
||||||
lp = getdisklabel((char *)NULL, fsreadfd);
|
if ((lp = getdisklabel(NULL, fsreadfd)))
|
||||||
if (lp)
|
|
||||||
dev_bsize = secsize = lp->d_secsize;
|
dev_bsize = secsize = lp->d_secsize;
|
||||||
else
|
else
|
||||||
dev_bsize = secsize = DEV_BSIZE;
|
dev_bsize = secsize = DEV_BSIZE;
|
||||||
@ -147,6 +143,10 @@ setup(dev)
|
|||||||
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
||||||
bflag = 0;
|
bflag = 0;
|
||||||
}
|
}
|
||||||
|
if (skipclean && sblock.fs_clean) {
|
||||||
|
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
maxfsblock = sblock.fs_size;
|
maxfsblock = sblock.fs_size;
|
||||||
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
||||||
/*
|
/*
|
||||||
@ -264,12 +264,6 @@ setup(dev)
|
|||||||
asked++;
|
asked++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* If we survive the above basic checks and are preening,
|
|
||||||
* quit here unless forced.
|
|
||||||
*/
|
|
||||||
if (skipclean && sblock.fs_clean && !fflag)
|
|
||||||
return (-1);
|
|
||||||
/*
|
/*
|
||||||
* allocate and initialize the necessary maps
|
* allocate and initialize the necessary maps
|
||||||
*/
|
*/
|
||||||
@ -280,22 +274,11 @@ setup(dev)
|
|||||||
(unsigned)bmapsize);
|
(unsigned)bmapsize);
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
statemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
inostathead = calloc((unsigned)(sblock.fs_ncg),
|
||||||
if (statemap == NULL) {
|
sizeof(struct inostatlist));
|
||||||
printf("cannot alloc %u bytes for statemap\n",
|
if (inostathead == NULL) {
|
||||||
(unsigned)(maxino + 1));
|
printf("cannot alloc %u bytes for inostathead\n",
|
||||||
goto badsb;
|
(unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
|
||||||
}
|
|
||||||
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
|
||||||
if (typemap == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for typemap\n",
|
|
||||||
(unsigned)(maxino + 1));
|
|
||||||
goto badsb;
|
|
||||||
}
|
|
||||||
lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
|
|
||||||
if (lncntp == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for lncntp\n",
|
|
||||||
(unsigned)(maxino + 1) * sizeof(short));
|
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
numdirs = sblock.fs_cstotal.cs_ndir;
|
numdirs = sblock.fs_cstotal.cs_ndir;
|
||||||
@ -474,9 +457,11 @@ calcsb(dev, devfd, fs)
|
|||||||
fstypenames[pp->p_fstype] : "unknown");
|
fstypenames[pp->p_fstype] : "unknown");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (pp->p_fsize == 0 || pp->p_frag == 0) {
|
if (pp->p_fsize == 0 || pp->p_frag == 0 ||
|
||||||
pfatal("%s: LABELED AS A %s FILE SYSTEM, BUT BLOCK SIZE IS 0\n",
|
pp->p_cpg == 0 || pp->p_size == 0) {
|
||||||
dev, fstypenames[pp->p_fstype]);
|
pfatal("%s: %s: type %s fsize %d, frag %d, cpg %d, size %d\n",
|
||||||
|
dev, "INCOMPLETE LABEL", fstypenames[pp->p_fstype],
|
||||||
|
pp->p_fsize, pp->p_frag, pp->p_cpg, pp->p_size);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
memset(fs, 0, sizeof(struct fs));
|
memset(fs, 0, sizeof(struct fs));
|
||||||
|
@ -32,20 +32,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -115,6 +111,26 @@ reply(question)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up state information for an inode.
|
||||||
|
*/
|
||||||
|
struct inostat *
|
||||||
|
inoinfo(inum)
|
||||||
|
ino_t inum;
|
||||||
|
{
|
||||||
|
static struct inostat unallocated = { USTATE, 0, 0 };
|
||||||
|
struct inostatlist *ilp;
|
||||||
|
int iloff;
|
||||||
|
|
||||||
|
if (inum > maxino)
|
||||||
|
errx(EEXIT, "inoinfo: inumber %d out of range", inum);
|
||||||
|
ilp = &inostathead[inum / sblock.fs_ipg];
|
||||||
|
iloff = inum % sblock.fs_ipg;
|
||||||
|
if (iloff >= ilp->il_numalloced)
|
||||||
|
return (&unallocated);
|
||||||
|
return (&ilp->il_stat[iloff]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Malloc buffers and set up cache.
|
* Malloc buffers and set up cache.
|
||||||
*/
|
*/
|
||||||
@ -270,16 +286,23 @@ ckfini(markclean)
|
|||||||
free((char *)bp);
|
free((char *)bp);
|
||||||
}
|
}
|
||||||
if (bufhead.b_size != cnt)
|
if (bufhead.b_size != cnt)
|
||||||
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
errx(EEXIT, "Panic: lost %d buffers", bufhead.b_size - cnt);
|
||||||
pbp = pdirbp = (struct bufarea *)0;
|
pbp = pdirbp = (struct bufarea *)0;
|
||||||
if (markclean && sblock.fs_clean == 0) {
|
if (sblock.fs_clean != markclean) {
|
||||||
sblock.fs_clean = 1;
|
sblock.fs_clean = markclean;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
ofsmodified = fsmodified;
|
ofsmodified = fsmodified;
|
||||||
flush(fswritefd, &sblk);
|
flush(fswritefd, &sblk);
|
||||||
fsmodified = ofsmodified;
|
fsmodified = ofsmodified;
|
||||||
if (!preen)
|
if (!preen) {
|
||||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
printf("\n***** FILE SYSTEM MARKED %s *****\n",
|
||||||
|
markclean ? "CLEAN" : "DIRTY");
|
||||||
|
if (!markclean)
|
||||||
|
rerun = 1;
|
||||||
|
}
|
||||||
|
} else if (!preen && !markclean) {
|
||||||
|
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
||||||
|
rerun = 1;
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug)
|
||||||
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
||||||
@ -324,6 +347,8 @@ bread(fd, buf, blk, size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (errs)
|
||||||
|
resolved = 0;
|
||||||
return (errs);
|
return (errs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +373,7 @@ bwrite(fd, buf, blk, size)
|
|||||||
fsmodified = 1;
|
fsmodified = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
resolved = 0;
|
||||||
rwerror("WRITE", blk);
|
rwerror("WRITE", blk);
|
||||||
if (lseek(fd, offset, 0) < 0)
|
if (lseek(fd, offset, 0) < 0)
|
||||||
rwerror("SEEK", blk);
|
rwerror("SEEK", blk);
|
||||||
@ -438,7 +464,8 @@ getpathname(namebuf, curdir, ino)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (busy ||
|
if (busy ||
|
||||||
(statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) {
|
(inoinfo(curdir)->ino_state != DSTATE &&
|
||||||
|
inoinfo(curdir)->ino_state != DFOUND)) {
|
||||||
(void)strcpy(namebuf, "?");
|
(void)strcpy(namebuf, "?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -497,6 +524,7 @@ void
|
|||||||
catchquit(sig)
|
catchquit(sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("returning to single-user after filesystem check\n");
|
printf("returning to single-user after filesystem check\n");
|
||||||
returntosingle = 1;
|
returntosingle = 1;
|
||||||
(void)signal(SIGQUIT, SIG_DFL);
|
(void)signal(SIGQUIT, SIG_DFL);
|
||||||
@ -589,14 +617,16 @@ pfatal(fmt, va_alist)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (usedsoftdep)
|
if (usedsoftdep)
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\nUNEXPECTED SOFTDEP INCONSISTENCY\n");
|
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cdevname == NULL)
|
||||||
|
cdevname = "fsck";
|
||||||
(void)fprintf(stderr, "%s: ", cdevname);
|
(void)fprintf(stderr, "%s: ", cdevname);
|
||||||
(void)vfprintf(stderr, fmt, ap);
|
(void)vfprintf(stderr, fmt, ap);
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||||
cdevname, usedsoftdep ? " SOFTDEP " : " ");
|
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
|
||||||
ckfini(0);
|
ckfini(0);
|
||||||
exit(EEXIT);
|
exit(EEXIT);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: dir.c,v 1.11 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -88,9 +85,9 @@ propagate()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0)
|
if (inp->i_parent == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE) {
|
inoinfo(inp->i_number)->ino_state == DSTATE) {
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
change++;
|
change++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +120,8 @@ dirscan(idesc)
|
|||||||
idesc->id_loc = 0;
|
idesc->id_loc = 0;
|
||||||
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
||||||
dsize = dp->d_reclen;
|
dsize = dp->d_reclen;
|
||||||
|
if (dsize > sizeof(dbuf))
|
||||||
|
dsize = sizeof(dbuf);
|
||||||
memmove(dbuf, dp, (size_t)dsize);
|
memmove(dbuf, dp, (size_t)dsize);
|
||||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||||
if (!newinofmt) {
|
if (!newinofmt) {
|
||||||
@ -235,8 +234,7 @@ dircheck(idesc, dp)
|
|||||||
int spaceleft;
|
int spaceleft;
|
||||||
|
|
||||||
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||||
if (dp->d_ino >= maxino ||
|
if (dp->d_reclen == 0 ||
|
||||||
dp->d_reclen == 0 ||
|
|
||||||
dp->d_reclen > spaceleft ||
|
dp->d_reclen > spaceleft ||
|
||||||
(dp->d_reclen & 0x3) != 0)
|
(dp->d_reclen & 0x3) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
@ -306,13 +304,40 @@ adjust(idesc, lcnt)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
int lcnt;
|
int lcnt;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
struct dinode *dp;
|
||||||
|
int saveresolved;
|
||||||
|
|
||||||
dp = ginode(idesc->id_number);
|
dp = ginode(idesc->id_number);
|
||||||
if (dp->di_nlink == lcnt) {
|
if (dp->di_nlink == lcnt) {
|
||||||
if (linkup(idesc->id_number, (ino_t)0) == 0)
|
/*
|
||||||
clri(idesc, "UNREF", 0);
|
* If we have not hit any unresolved problems, are running
|
||||||
} else {
|
* in preen mode, and are on a filesystem using soft updates,
|
||||||
|
* then just toss any partially allocated files.
|
||||||
|
*/
|
||||||
|
if (resolved && preen && usedsoftdep) {
|
||||||
|
clri(idesc, "UNREF", 1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The filesystem can be marked clean even if
|
||||||
|
* a file is not linked up, but is cleared.
|
||||||
|
* Hence, resolved should not be cleared when
|
||||||
|
* linkup is answered no, but clri is answered yes.
|
||||||
|
*/
|
||||||
|
saveresolved = resolved;
|
||||||
|
if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) {
|
||||||
|
resolved = saveresolved;
|
||||||
|
clri(idesc, "UNREF", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Account for the new reference created by linkup().
|
||||||
|
*/
|
||||||
|
dp = ginode(idesc->id_number);
|
||||||
|
lcnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lcnt != 0) {
|
||||||
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
||||||
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
||||||
pinode(idesc->id_number);
|
pinode(idesc->id_number);
|
||||||
@ -355,7 +380,7 @@ mkentry(idesc)
|
|||||||
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
||||||
dirp->d_reclen = newent.d_reclen;
|
dirp->d_reclen = newent.d_reclen;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
dirp->d_namlen = newent.d_namlen;
|
dirp->d_namlen = newent.d_namlen;
|
||||||
@ -388,16 +413,17 @@ chgino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dirp->d_ino = idesc->id_parent;
|
dirp->d_ino = idesc->id_parent;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
return (ALTERED|STOP);
|
return (ALTERED|STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
linkup(orphan, parentdir)
|
linkup(orphan, parentdir, name)
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
ino_t parentdir;
|
ino_t parentdir;
|
||||||
|
char *name;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
register struct dinode *dp;
|
||||||
int lostdir;
|
int lostdir;
|
||||||
@ -410,7 +436,7 @@ linkup(orphan, parentdir)
|
|||||||
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
||||||
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
||||||
pinode(orphan);
|
pinode(orphan);
|
||||||
if ((preen || usedsoftdep) && dp->di_size == 0)
|
if (preen && dp->di_size == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (RECONNECTED)\n");
|
printf(" (RECONNECTED)\n");
|
||||||
@ -431,6 +457,7 @@ linkup(orphan, parentdir)
|
|||||||
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
||||||
if (lfdir != 0) {
|
if (lfdir != 0) {
|
||||||
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
||||||
|
numdirs++;
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (CREATED)\n");
|
printf(" (CREATED)\n");
|
||||||
} else {
|
} else {
|
||||||
@ -466,21 +493,21 @@ linkup(orphan, parentdir)
|
|||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
idesc.id_number = oldlfdir;
|
idesc.id_number = oldlfdir;
|
||||||
adjust(&idesc, lncntp[oldlfdir] + 1);
|
adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1);
|
||||||
lncntp[oldlfdir] = 0;
|
inoinfo(oldlfdir)->ino_linkcnt = 0;
|
||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
}
|
}
|
||||||
if (statemap[lfdir] != DFOUND) {
|
if (inoinfo(lfdir)->ino_state != DFOUND) {
|
||||||
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
(void)lftempname(tempname, orphan);
|
(void)lftempname(tempname, orphan);
|
||||||
if (makeentry(lfdir, orphan, tempname) == 0) {
|
if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) {
|
||||||
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
lncntp[orphan]--;
|
inoinfo(orphan)->ino_linkcnt--;
|
||||||
if (lostdir) {
|
if (lostdir) {
|
||||||
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
||||||
parentdir != (ino_t)-1)
|
parentdir != (ino_t)-1)
|
||||||
@ -488,19 +515,11 @@ linkup(orphan, parentdir)
|
|||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
inodirty();
|
inodirty();
|
||||||
lncntp[lfdir]++;
|
inoinfo(lfdir)->ino_linkcnt++;
|
||||||
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
||||||
if (parentdir != (ino_t)-1) {
|
if (parentdir != (ino_t)-1) {
|
||||||
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
||||||
/*
|
inoinfo(parentdir)->ino_linkcnt++;
|
||||||
* The parent directory, because of the ordering
|
|
||||||
* guarantees, has had the link count incremented
|
|
||||||
* for the child, but no entry was made. This
|
|
||||||
* fixes the parent link count so that fsck does
|
|
||||||
* not need to be rerun.
|
|
||||||
*/
|
|
||||||
lncntp[parentdir]++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (preen == 0)
|
if (preen == 0)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -658,19 +677,20 @@ allocdir(parent, request, mode)
|
|||||||
dp->di_nlink = 2;
|
dp->di_nlink = 2;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (ino == ROOTINO) {
|
if (ino == ROOTINO) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
return(ino);
|
return(ino);
|
||||||
}
|
}
|
||||||
if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) {
|
if (inoinfo(parent)->ino_state != DSTATE &&
|
||||||
|
inoinfo(parent)->ino_state != DFOUND) {
|
||||||
freeino(ino);
|
freeino(ino);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
statemap[ino] = statemap[parent];
|
inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
|
||||||
if (statemap[ino] == DSTATE) {
|
if (inoinfo(ino)->ino_state == DSTATE) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
lncntp[parent]++;
|
inoinfo(parent)->ino_linkcnt++;
|
||||||
}
|
}
|
||||||
dp = ginode(parent);
|
dp = ginode(parent);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
|
@ -42,16 +42,35 @@
|
|||||||
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
||||||
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
||||||
|
|
||||||
#ifndef BUFSIZ
|
/*
|
||||||
#define BUFSIZ 1024
|
* Each inode on the filesystem is described by the following structure.
|
||||||
#endif
|
* The linkcnt is initially set to the value in the inode. Each time it
|
||||||
|
* is found during the descent in passes 2, 3, and 4 the count is
|
||||||
|
* decremented. Any inodes whose count is non-zero after pass 4 needs to
|
||||||
|
* have its link count adjusted by the value remaining in ino_linkcnt.
|
||||||
|
*/
|
||||||
|
struct inostat {
|
||||||
|
char ino_state; /* state of inode, see below */
|
||||||
|
char ino_type; /* type of inode */
|
||||||
|
short ino_linkcnt; /* number of links not found */
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Inode states.
|
||||||
|
*/
|
||||||
#define USTATE 01 /* inode not allocated */
|
#define USTATE 01 /* inode not allocated */
|
||||||
#define FSTATE 02 /* inode is file */
|
#define FSTATE 02 /* inode is file */
|
||||||
#define DSTATE 03 /* inode is directory */
|
#define DSTATE 03 /* inode is directory */
|
||||||
#define DFOUND 04 /* directory found during descent */
|
#define DFOUND 04 /* directory found during descent */
|
||||||
#define DCLEAR 05 /* directory is to be cleared */
|
#define DCLEAR 05 /* directory is to be cleared */
|
||||||
#define FCLEAR 06 /* file is to be cleared */
|
#define FCLEAR 06 /* file is to be cleared */
|
||||||
|
/*
|
||||||
|
* Inode state information is contained on per cylinder group lists
|
||||||
|
* which are described by the following structure.
|
||||||
|
*/
|
||||||
|
struct inostatlist {
|
||||||
|
long il_numalloced; /* number of inodes allocated in this cg */
|
||||||
|
struct inostat *il_stat;/* inostat info for this cylinder group */
|
||||||
|
} *inostathead;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* buffer cache structure.
|
* buffer cache structure.
|
||||||
@ -163,11 +182,12 @@ struct inoinfo {
|
|||||||
ufs_daddr_t i_blks[1]; /* actually longer */
|
ufs_daddr_t i_blks[1]; /* actually longer */
|
||||||
} **inphead, **inpsort;
|
} **inphead, **inpsort;
|
||||||
long numdirs, listmax, inplast;
|
long numdirs, listmax, inplast;
|
||||||
|
long countdirs; /* number of directories we actually found */
|
||||||
|
|
||||||
char *cdevname; /* name of device being checked */
|
char *cdevname; /* name of device being checked */
|
||||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||||
long secsize; /* actual disk sector size */
|
long secsize; /* actual disk sector size */
|
||||||
char fflag; /* force fs check (ignore clean flag) */
|
char fflag; /* force check, ignore clean flag */
|
||||||
char nflag; /* assume a no response */
|
char nflag; /* assume a no response */
|
||||||
char yflag; /* assume a yes response */
|
char yflag; /* assume a yes response */
|
||||||
int bflag; /* location of alternate super block */
|
int bflag; /* location of alternate super block */
|
||||||
@ -177,23 +197,19 @@ int doinglevel1; /* converting to new cylinder group format */
|
|||||||
int doinglevel2; /* converting to new inode format */
|
int doinglevel2; /* converting to new inode format */
|
||||||
int newinofmt; /* filesystem has new inode format */
|
int newinofmt; /* filesystem has new inode format */
|
||||||
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
||||||
char resolved; /* cleared if unresolved changes => not clean */
|
|
||||||
char preen; /* just fix normal inconsistencies */
|
char preen; /* just fix normal inconsistencies */
|
||||||
|
char rerun; /* rerun fsck. Only used in non-preen mode */
|
||||||
|
int returntosingle; /* 1 => return to single user mode on exit */
|
||||||
|
char resolved; /* cleared if unresolved changes => not clean */
|
||||||
char hotroot; /* checking root device */
|
char hotroot; /* checking root device */
|
||||||
char havesb; /* superblock has been read */
|
char havesb; /* superblock has been read */
|
||||||
int fsmodified; /* 1 => write done to file system */
|
int fsmodified; /* 1 => write done to file system */
|
||||||
int fsreadfd; /* file descriptor for reading file system */
|
int fsreadfd; /* file descriptor for reading file system */
|
||||||
int fswritefd; /* file descriptor for writing file system */
|
int fswritefd; /* file descriptor for writing file system */
|
||||||
int returntosingle; /* return to single user mode */
|
|
||||||
int rerun; /* rerun fsck. Only used in non-preen mode */
|
|
||||||
|
|
||||||
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
||||||
char *blockmap; /* ptr to primary blk allocation map */
|
char *blockmap; /* ptr to primary blk allocation map */
|
||||||
ino_t maxino; /* number of inodes in file system */
|
ino_t maxino; /* number of inodes in file system */
|
||||||
ino_t lastino; /* last inode in use */
|
|
||||||
char *statemap; /* ptr to inode state table */
|
|
||||||
u_char *typemap; /* ptr to inode type table */
|
|
||||||
short *lncntp; /* ptr to link count table */
|
|
||||||
|
|
||||||
ino_t lfdir; /* lost & found directory inode number */
|
ino_t lfdir; /* lost & found directory inode number */
|
||||||
char *lfname; /* lost & found directory name */
|
char *lfname; /* lost & found directory name */
|
||||||
@ -219,6 +235,7 @@ struct dinode zino;
|
|||||||
|
|
||||||
struct fstab;
|
struct fstab;
|
||||||
|
|
||||||
|
|
||||||
void adjust __P((struct inodesc *, int lcnt));
|
void adjust __P((struct inodesc *, int lcnt));
|
||||||
ufs_daddr_t allocblk __P((long frags));
|
ufs_daddr_t allocblk __P((long frags));
|
||||||
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
||||||
@ -239,6 +256,7 @@ int chkrange __P((ufs_daddr_t blk, int cnt));
|
|||||||
void ckfini __P((int markclean));
|
void ckfini __P((int markclean));
|
||||||
int ckinode __P((struct dinode *dp, struct inodesc *));
|
int ckinode __P((struct dinode *dp, struct inodesc *));
|
||||||
void clri __P((struct inodesc *, char *type, int flag));
|
void clri __P((struct inodesc *, char *type, int flag));
|
||||||
|
int clearentry __P((struct inodesc *));
|
||||||
void direrror __P((ino_t ino, char *errmesg));
|
void direrror __P((ino_t ino, char *errmesg));
|
||||||
int dirscan __P((struct inodesc *));
|
int dirscan __P((struct inodesc *));
|
||||||
int dofix __P((struct inodesc *, char *msg));
|
int dofix __P((struct inodesc *, char *msg));
|
||||||
@ -262,7 +280,8 @@ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
|
|||||||
struct dinode *ginode __P((ino_t inumber));
|
struct dinode *ginode __P((ino_t inumber));
|
||||||
void inocleanup __P((void));
|
void inocleanup __P((void));
|
||||||
void inodirty __P((void));
|
void inodirty __P((void));
|
||||||
int linkup __P((ino_t orphan, ino_t parentdir));
|
struct inostat *inoinfo __P((ino_t inum));
|
||||||
|
int linkup __P((ino_t orphan, ino_t parentdir, char *name));
|
||||||
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
||||||
void panic __P((const char *fmt, ...));
|
void panic __P((const char *fmt, ...));
|
||||||
void pass1 __P((void));
|
void pass1 __P((void));
|
||||||
@ -278,6 +297,6 @@ void pinode __P((ino_t ino));
|
|||||||
void propagate __P((void));
|
void propagate __P((void));
|
||||||
void pwarn __P((const char *fmt, ...));
|
void pwarn __P((const char *fmt, ...));
|
||||||
int reply __P((char *question));
|
int reply __P((char *question));
|
||||||
void resetinodebuf __P((void));
|
void setinodebuf __P((ino_t));
|
||||||
int setup __P((char *dev));
|
int setup __P((char *dev));
|
||||||
void voidquit __P((int));
|
void voidquit __P((int));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
.\"
|
||||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -10,7 +11,7 @@
|
|||||||
.\" notice, this list of conditions and the following disclaimer in the
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
.\" 3. All advertising materials mentioning features or use of this software
|
.\" 3. All advertising materials mentioning features or use of this software
|
||||||
.\" must display the following acknowledgment:
|
.\" must display the following acknowledgement:
|
||||||
.\" This product includes software developed by the University of
|
.\" This product includes software developed by the University of
|
||||||
.\" California, Berkeley and its contributors.
|
.\" California, Berkeley and its contributors.
|
||||||
.\" 4. Neither the name of the University nor the names of its contributors
|
.\" 4. Neither the name of the University nor the names of its contributors
|
||||||
@ -30,9 +31,8 @@
|
|||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
||||||
.\" $Id: fsck.8,v 1.10 1997/03/12 16:35:26 bde Exp $
|
|
||||||
.\"
|
.\"
|
||||||
.Dd May 9, 1995
|
.Dd November 15, 1996
|
||||||
.Dt FSCK 8
|
.Dt FSCK 8
|
||||||
.Os BSD 4
|
.Os BSD 4
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -43,24 +43,25 @@
|
|||||||
.Fl p
|
.Fl p
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
|
.Op Ar filesystem
|
||||||
|
.Ar ...
|
||||||
.Nm fsck
|
.Nm fsck
|
||||||
|
.Op Fl ny
|
||||||
.Op Fl b Ar block#
|
.Op Fl b Ar block#
|
||||||
.Op Fl c Ar level
|
.Op Fl c Ar level
|
||||||
.Op Fl l Ar maxparallel
|
.Op Fl l Ar maxparallel
|
||||||
.Op Fl y
|
|
||||||
.Op Fl n
|
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
.Op Ar filesystem
|
.Op Ar filesystem
|
||||||
.Ar ...
|
.Ar ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The first form of
|
The first form of
|
||||||
.Nm
|
.Nm fsck
|
||||||
preens a standard set of filesystems or the specified filesystems.
|
preens a standard set of filesystems or the specified filesystems.
|
||||||
It is normally used in the script
|
It is normally used in the script
|
||||||
.Pa /etc/rc
|
.Pa /etc/rc
|
||||||
during automatic reboot.
|
during automatic reboot.
|
||||||
Here
|
Here
|
||||||
.Nm
|
.Nm fsck
|
||||||
reads the table
|
reads the table
|
||||||
.Pa /etc/fstab
|
.Pa /etc/fstab
|
||||||
to determine which filesystems to check.
|
to determine which filesystems to check.
|
||||||
@ -73,22 +74,18 @@ running one process per disk drive.
|
|||||||
The disk drive containing each filesystem is inferred from the longest prefix
|
The disk drive containing each filesystem is inferred from the longest prefix
|
||||||
of the device name that ends in a digit; the remaining characters are assumed
|
of the device name that ends in a digit; the remaining characters are assumed
|
||||||
to be the partition designator.
|
to be the partition designator.
|
||||||
.Pp
|
In preening mode,
|
||||||
The clean flag of each filesystem's superblock is examined and only those filesystems that
|
filesystems that are marked clean are skipped.
|
||||||
are not marked clean are checked.
|
|
||||||
Filesystems are marked clean when they are unmounted,
|
Filesystems are marked clean when they are unmounted,
|
||||||
when they have been mounted read-only, or when
|
when they have been mounted read-only, or when
|
||||||
.Nm
|
.Nm fsck
|
||||||
runs on them successfully.
|
runs on them successfully.
|
||||||
If the
|
|
||||||
.Fl f
|
|
||||||
option is specified, the filesystems
|
|
||||||
will be checked regardless of the state of their clean flag.
|
|
||||||
.Pp
|
.Pp
|
||||||
The kernel takes care that only a restricted class of innocuous filesystem
|
The kernel takes care that only a restricted class of innocuous filesystem
|
||||||
inconsistencies can happen unless hardware or software failures intervene.
|
inconsistencies can happen unless hardware or software failures intervene.
|
||||||
These are limited to the following:
|
These are limited to the following:
|
||||||
.Bl -item -compact
|
.Pp
|
||||||
|
.Bl -item -compact -offset indent
|
||||||
.It
|
.It
|
||||||
Unreferenced inodes
|
Unreferenced inodes
|
||||||
.It
|
.It
|
||||||
@ -102,7 +99,7 @@ Counts in the super-block wrong
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
These are the only inconsistencies that
|
These are the only inconsistencies that
|
||||||
.Nm
|
.Nm fsck
|
||||||
with the
|
with the
|
||||||
.Fl p
|
.Fl p
|
||||||
option will correct; if it encounters other inconsistencies, it exits
|
option will correct; if it encounters other inconsistencies, it exits
|
||||||
@ -110,7 +107,7 @@ with an abnormal return status and an automatic reboot will then fail.
|
|||||||
For each corrected inconsistency one or more lines will be printed
|
For each corrected inconsistency one or more lines will be printed
|
||||||
identifying the filesystem on which the correction will take place,
|
identifying the filesystem on which the correction will take place,
|
||||||
and the nature of the correction. After successfully correcting a filesystem,
|
and the nature of the correction. After successfully correcting a filesystem,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will print the number of files on that filesystem,
|
will print the number of files on that filesystem,
|
||||||
the number of used and free blocks,
|
the number of used and free blocks,
|
||||||
and the percentage of fragmentation.
|
and the percentage of fragmentation.
|
||||||
@ -118,7 +115,7 @@ and the percentage of fragmentation.
|
|||||||
If sent a
|
If sent a
|
||||||
.Dv QUIT
|
.Dv QUIT
|
||||||
signal,
|
signal,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will finish the filesystem checks, then exit with an abnormal
|
will finish the filesystem checks, then exit with an abnormal
|
||||||
return status that causes an automatic reboot to fail.
|
return status that causes an automatic reboot to fail.
|
||||||
This is useful when you want to finish the filesystem checks during an
|
This is useful when you want to finish the filesystem checks during an
|
||||||
@ -128,7 +125,7 @@ but do not want the machine to come up multiuser after the checks complete.
|
|||||||
Without the
|
Without the
|
||||||
.Fl p
|
.Fl p
|
||||||
option,
|
option,
|
||||||
.Nm
|
.Nm fsck
|
||||||
audits and interactively repairs inconsistent conditions for filesystems.
|
audits and interactively repairs inconsistent conditions for filesystems.
|
||||||
If the filesystem is inconsistent the operator is prompted for concurrence
|
If the filesystem is inconsistent the operator is prompted for concurrence
|
||||||
before each correction is attempted.
|
before each correction is attempted.
|
||||||
@ -144,7 +141,7 @@ is to wait for the operator to respond
|
|||||||
or
|
or
|
||||||
.Li no .
|
.Li no .
|
||||||
If the operator does not have write permission on the filesystem
|
If the operator does not have write permission on the filesystem
|
||||||
.Nm
|
.Nm fsck
|
||||||
will default to a
|
will default to a
|
||||||
.Fl n
|
.Fl n
|
||||||
action.
|
action.
|
||||||
@ -158,38 +155,12 @@ and
|
|||||||
combined.
|
combined.
|
||||||
.Pp
|
.Pp
|
||||||
The following flags are interpreted by
|
The following flags are interpreted by
|
||||||
.Nm Ns .
|
.Nm fsck .
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl b
|
.It Fl b
|
||||||
Use the block specified immediately after the flag as
|
Use the block specified immediately after the flag as
|
||||||
the super block for the filesystem. Block 32 is usually
|
the super block for the filesystem. Block 32 is usually
|
||||||
an alternate super block.
|
an alternate super block.
|
||||||
.It Fl l
|
|
||||||
Limit the number of parallel checks to the number specified in the following
|
|
||||||
argument.
|
|
||||||
By default, the limit is the number of disks, running one process per disk.
|
|
||||||
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
|
||||||
at a time.
|
|
||||||
.It Fl m
|
|
||||||
Use the mode specified in octal immediately after the flag as the
|
|
||||||
permission bits to use when creating the
|
|
||||||
.Pa lost+found
|
|
||||||
directory rather than the default 1777.
|
|
||||||
In particular, systems that do not wish to have lost files accessible
|
|
||||||
by all users on the system should use a more restrictive
|
|
||||||
set of permissions such as 700.
|
|
||||||
.It Fl y
|
|
||||||
Assume a yes response to all questions asked by
|
|
||||||
.Nm Ns ;
|
|
||||||
this should be used with great caution as this is a free license
|
|
||||||
to continue after essentially unlimited trouble has been encountered.
|
|
||||||
.It Fl n
|
|
||||||
Assume a no response to all questions asked by
|
|
||||||
.Nm
|
|
||||||
except for
|
|
||||||
.Ql CONTINUE? ,
|
|
||||||
which is assumed to be affirmative;
|
|
||||||
do not open the filesystem for writing.
|
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Convert the filesystem to the specified level.
|
Convert the filesystem to the specified level.
|
||||||
Note that the level of a filesystem can only be raised.
|
Note that the level of a filesystem can only be raised.
|
||||||
@ -210,7 +181,7 @@ If maxcontig is equal to one, delete any existing segment maps.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
In interactive mode,
|
In interactive mode,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will list the conversion to be made
|
will list the conversion to be made
|
||||||
and ask whether the conversion should be done.
|
and ask whether the conversion should be done.
|
||||||
If a negative answer is given,
|
If a negative answer is given,
|
||||||
@ -223,10 +194,44 @@ are being converted at once.
|
|||||||
The format of a filesystem can be determined from the
|
The format of a filesystem can be determined from the
|
||||||
first line of output from
|
first line of output from
|
||||||
.Xr dumpfs 8 .
|
.Xr dumpfs 8 .
|
||||||
|
.It Fl f
|
||||||
|
Force
|
||||||
|
.Nm fsck
|
||||||
|
to check
|
||||||
|
.Sq clean
|
||||||
|
filesystems when preening.
|
||||||
|
.It Fl l
|
||||||
|
Limit the number of parallel checks to the number specified in the following
|
||||||
|
argument.
|
||||||
|
By default, the limit is the number of disks, running one process per disk.
|
||||||
|
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
||||||
|
at a time.
|
||||||
|
.It Fl m
|
||||||
|
Use the mode specified in octal immediately after the flag as the
|
||||||
|
permission bits to use when creating the
|
||||||
|
.Pa lost+found
|
||||||
|
directory rather than the default 1777.
|
||||||
|
In particular, systems that do not wish to have lost files accessible
|
||||||
|
by all users on the system should use a more restrictive
|
||||||
|
set of permissions such as 700.
|
||||||
|
.It Fl n
|
||||||
|
Assume a no response to all questions asked by
|
||||||
|
.Nm fsck
|
||||||
|
except for
|
||||||
|
.Ql CONTINUE? ,
|
||||||
|
which is assumed to be affirmative;
|
||||||
|
do not open the filesystem for writing.
|
||||||
|
.It Fl p
|
||||||
|
Preen filesystems (see above).
|
||||||
|
.It Fl y
|
||||||
|
Assume a yes response to all questions asked by
|
||||||
|
.Nm fsck ;
|
||||||
|
this should be used with great caution as this is a free license
|
||||||
|
to continue after essentially unlimited trouble has been encountered.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If no filesystems are given to
|
If no filesystems are given to
|
||||||
.Nm
|
.Nm fsck
|
||||||
then a default list of filesystems is read from
|
then a default list of filesystems is read from
|
||||||
the file
|
the file
|
||||||
.Pa /etc/fstab .
|
.Pa /etc/fstab .
|
||||||
@ -259,7 +264,7 @@ File pointing to unallocated inode.
|
|||||||
.It
|
.It
|
||||||
Inode number out of range.
|
Inode number out of range.
|
||||||
.It
|
.It
|
||||||
Holes in directories.
|
Directories with unallocated blocks (holes).
|
||||||
.It
|
.It
|
||||||
Dot or dot-dot not the first two entries of a directory
|
Dot or dot-dot not the first two entries of a directory
|
||||||
or having the wrong inode number.
|
or having the wrong inode number.
|
||||||
@ -296,14 +301,13 @@ contains default list of filesystems to check.
|
|||||||
.El
|
.El
|
||||||
.Sh DIAGNOSTICS
|
.Sh DIAGNOSTICS
|
||||||
The diagnostics produced by
|
The diagnostics produced by
|
||||||
.Nm
|
.Nm fsck
|
||||||
are fully enumerated and explained in Appendix A of
|
are fully enumerated and explained in Appendix A of
|
||||||
.Rs
|
.Rs
|
||||||
.%T "Fsck \- The UNIX File System Check Program"
|
.%T "Fsck \- The UNIX File System Check Program"
|
||||||
.Re
|
.Re
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr fs 5 ,
|
|
||||||
.Xr fstab 5 ,
|
.Xr fstab 5 ,
|
||||||
.Xr fsdb 8 ,
|
.Xr fs 5 ,
|
||||||
.Xr newfs 8 ,
|
.Xr newfs 8 ,
|
||||||
.Xr reboot 8
|
.Xr reboot 8
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: inode.c,v 1.15 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -62,7 +58,8 @@ ckinode(dp, idesc)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
{
|
{
|
||||||
ufs_daddr_t *ap;
|
ufs_daddr_t *ap;
|
||||||
long ret, n, ndb, offset;
|
int ret;
|
||||||
|
long n, ndb, offset;
|
||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
quad_t remsize, sizepb;
|
quad_t remsize, sizepb;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
@ -74,7 +71,7 @@ ckinode(dp, idesc)
|
|||||||
idesc->id_filesize = dp->di_size;
|
idesc->id_filesize = dp->di_size;
|
||||||
mode = dp->di_mode & IFMT;
|
mode = dp->di_mode & IFMT;
|
||||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
||||||
(dp->di_size < sblock.fs_maxsymlinklen || dp->di_blocks == 0)))
|
dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dino = *dp;
|
dino = *dp;
|
||||||
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
||||||
@ -239,8 +236,16 @@ chkrange(blk, cnt)
|
|||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
if (blk < 0 || blk >= maxfsblock || cnt < 0 || cnt > maxfsblock - blk)
|
if (cnt <= 0 || blk <= 0 || blk > maxfsblock ||
|
||||||
|
cnt - 1 > maxfsblock - blk)
|
||||||
return (1);
|
return (1);
|
||||||
|
if (cnt > sblock.fs_frag ||
|
||||||
|
fragnum(&sblock, blk) + cnt > sblock.fs_frag) {
|
||||||
|
if (debug)
|
||||||
|
printf("bad size: blk %ld, offset %ld, size %ld\n",
|
||||||
|
blk, fragnum(&sblock, blk), cnt);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
c = dtog(&sblock, blk);
|
c = dtog(&sblock, blk);
|
||||||
if (blk < cgdmin(&sblock, c)) {
|
if (blk < cgdmin(&sblock, c)) {
|
||||||
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
||||||
@ -317,20 +322,29 @@ getnextinode(inumber)
|
|||||||
size = inobufsize;
|
size = inobufsize;
|
||||||
lastinum += fullcnt;
|
lastinum += fullcnt;
|
||||||
}
|
}
|
||||||
(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
|
/*
|
||||||
|
* If bread returns an error, it will already have zeroed
|
||||||
|
* out the buffer, so we do not need to do so here.
|
||||||
|
*/
|
||||||
|
(void)bread(fsreadfd, (char *)inodebuf, dblk, size);
|
||||||
dp = inodebuf;
|
dp = inodebuf;
|
||||||
}
|
}
|
||||||
return (dp++);
|
return (dp++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
resetinodebuf()
|
setinodebuf(inum)
|
||||||
|
ino_t inum;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (inum % sblock.fs_ipg != 0)
|
||||||
|
errx(EEXIT, "bad inode number %d to setinodebuf", inum);
|
||||||
startinum = 0;
|
startinum = 0;
|
||||||
nextino = 0;
|
nextino = inum;
|
||||||
lastinum = 0;
|
lastinum = inum;
|
||||||
readcnt = 0;
|
readcnt = 0;
|
||||||
|
if (inodebuf != NULL)
|
||||||
|
return;
|
||||||
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
||||||
fullcnt = inobufsize / sizeof(struct dinode);
|
fullcnt = inobufsize / sizeof(struct dinode);
|
||||||
readpercg = sblock.fs_ipg / fullcnt;
|
readpercg = sblock.fs_ipg / fullcnt;
|
||||||
@ -342,11 +356,8 @@ resetinodebuf()
|
|||||||
partialcnt = fullcnt;
|
partialcnt = fullcnt;
|
||||||
partialsize = inobufsize;
|
partialsize = inobufsize;
|
||||||
}
|
}
|
||||||
if (inodebuf == NULL &&
|
if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
||||||
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
|
||||||
errx(EEXIT, "cannot allocate space for inode buffer");
|
errx(EEXIT, "cannot allocate space for inode buffer");
|
||||||
while (nextino < ROOTINO)
|
|
||||||
(void)getnextinode(nextino);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -380,14 +391,11 @@ cacheino(dp, inumber)
|
|||||||
inp = (struct inoinfo *)
|
inp = (struct inoinfo *)
|
||||||
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
||||||
if (inp == NULL)
|
if (inp == NULL)
|
||||||
return;
|
errx(EEXIT, "cannot increase directory list");
|
||||||
inpp = &inphead[inumber % numdirs];
|
inpp = &inphead[inumber % numdirs];
|
||||||
inp->i_nexthash = *inpp;
|
inp->i_nexthash = *inpp;
|
||||||
*inpp = inp;
|
*inpp = inp;
|
||||||
if (inumber == ROOTINO)
|
inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
|
||||||
inp->i_parent = ROOTINO;
|
|
||||||
else
|
|
||||||
inp->i_parent = (ino_t)0;
|
|
||||||
inp->i_dotdot = (ino_t)0;
|
inp->i_dotdot = (ino_t)0;
|
||||||
inp->i_number = inumber;
|
inp->i_number = inumber;
|
||||||
inp->i_isize = dp->di_size;
|
inp->i_isize = dp->di_size;
|
||||||
@ -465,7 +473,7 @@ clri(idesc, type, flag)
|
|||||||
n_files--;
|
n_files--;
|
||||||
(void)ckinode(dp, idesc);
|
(void)ckinode(dp, idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
statemap[idesc->id_number] = USTATE;
|
inoinfo(idesc->id_number)->ino_state = USTATE;
|
||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,8 +484,10 @@ findname(idesc)
|
|||||||
{
|
{
|
||||||
register struct direct *dirp = idesc->id_dirp;
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
if (dirp->d_ino != idesc->id_parent)
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
|
}
|
||||||
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
||||||
return (STOP|FOUND);
|
return (STOP|FOUND);
|
||||||
}
|
}
|
||||||
@ -498,6 +508,20 @@ findino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
clearentry(idesc)
|
||||||
|
struct inodesc *idesc;
|
||||||
|
{
|
||||||
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
|
return (KEEPON);
|
||||||
|
}
|
||||||
|
dirp->d_ino = 0;
|
||||||
|
return (STOP|FOUND|ALTERED);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pinode(ino)
|
pinode(ino)
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
@ -534,14 +558,14 @@ blkerror(ino, type, blk)
|
|||||||
|
|
||||||
pfatal("%ld %s I=%lu", blk, type, ino);
|
pfatal("%ld %s I=%lu", blk, type, ino);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
switch (statemap[ino]) {
|
switch (inoinfo(ino)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
statemap[ino] = FCLEAR;
|
inoinfo(ino)->ino_state = FCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
statemap[ino] = DCLEAR;
|
inoinfo(ino)->ino_state = DCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
@ -549,7 +573,7 @@ blkerror(ino, type, blk)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
|
errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,10 +593,10 @@ allocino(request, type)
|
|||||||
|
|
||||||
if (request == 0)
|
if (request == 0)
|
||||||
request = ROOTINO;
|
request = ROOTINO;
|
||||||
else if (statemap[request] != USTATE)
|
else if (inoinfo(request)->ino_state != USTATE)
|
||||||
return (0);
|
return (0);
|
||||||
for (ino = request; ino < maxino; ino++)
|
for (ino = request; ino < maxino; ino++)
|
||||||
if (statemap[ino] == USTATE)
|
if (inoinfo(ino)->ino_state == USTATE)
|
||||||
break;
|
break;
|
||||||
if (ino == maxino)
|
if (ino == maxino)
|
||||||
return (0);
|
return (0);
|
||||||
@ -584,12 +608,12 @@ allocino(request, type)
|
|||||||
cgp->cg_cs.cs_nifree--;
|
cgp->cg_cs.cs_nifree--;
|
||||||
switch (type & IFMT) {
|
switch (type & IFMT) {
|
||||||
case IFDIR:
|
case IFDIR:
|
||||||
statemap[ino] = DSTATE;
|
inoinfo(ino)->ino_state = DSTATE;
|
||||||
cgp->cg_cs.cs_ndir++;
|
cgp->cg_cs.cs_ndir++;
|
||||||
break;
|
break;
|
||||||
case IFREG:
|
case IFREG:
|
||||||
case IFLNK:
|
case IFLNK:
|
||||||
statemap[ino] = FSTATE;
|
inoinfo(ino)->ino_state = FSTATE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (0);
|
return (0);
|
||||||
@ -598,11 +622,11 @@ allocino(request, type)
|
|||||||
dp = ginode(ino);
|
dp = ginode(ino);
|
||||||
dp->di_db[0] = allocblk((long)1);
|
dp->di_db[0] = allocblk((long)1);
|
||||||
if (dp->di_db[0] == 0) {
|
if (dp->di_db[0] == 0) {
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
dp->di_flags = 0;
|
|
||||||
dp->di_mode = type;
|
dp->di_mode = type;
|
||||||
|
dp->di_flags = 0;
|
||||||
dp->di_atime = time(NULL);
|
dp->di_atime = time(NULL);
|
||||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||||
dp->di_size = sblock.fs_fsize;
|
dp->di_size = sblock.fs_fsize;
|
||||||
@ -610,7 +634,7 @@ allocino(request, type)
|
|||||||
n_files++;
|
n_files++;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
typemap[ino] = IFTODT(type);
|
inoinfo(ino)->ino_type = IFTODT(type);
|
||||||
return (ino);
|
return (ino);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,6 +656,6 @@ freeino(ino)
|
|||||||
(void)ckinode(dp, &idesc);
|
(void)ckinode(dp, &idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
n_files--;
|
n_files--;
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,7 @@ static const char copyright[] =
|
|||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
||||||
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: main.c,v 1.14 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -56,11 +52,10 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
int returntosingle;
|
|
||||||
|
|
||||||
static int argtoi __P((int flag, char *req, char *str, int base));
|
static int argtoi __P((int flag, char *req, char *str, int base));
|
||||||
static int docheck __P((struct fstab *fsp));
|
static int docheck __P((struct fstab *fsp));
|
||||||
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
||||||
@ -74,12 +69,8 @@ main(argc, argv)
|
|||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
int ret, maxrun = 0;
|
int ret, maxrun = 0;
|
||||||
struct rlimit rlim;
|
struct rlimit rlimit;
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_DATA, &rlim) == 0) {
|
|
||||||
rlim.rlim_cur = rlim.rlim_max;
|
|
||||||
(void) setrlimit(RLIMIT_DATA, &rlim);
|
|
||||||
}
|
|
||||||
sync();
|
sync();
|
||||||
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@ -137,9 +128,24 @@ main(argc, argv)
|
|||||||
(void)signal(SIGINT, catch);
|
(void)signal(SIGINT, catch);
|
||||||
if (preen)
|
if (preen)
|
||||||
(void)signal(SIGQUIT, catchquit);
|
(void)signal(SIGQUIT, catchquit);
|
||||||
|
/*
|
||||||
|
* Push up our allowed memory limit so we can cope
|
||||||
|
* with huge filesystems.
|
||||||
|
*/
|
||||||
|
if (getrlimit(RLIMIT_DATA, &rlimit) == 0) {
|
||||||
|
rlimit.rlim_cur = rlimit.rlim_max;
|
||||||
|
(void)setrlimit(RLIMIT_DATA, &rlimit);
|
||||||
|
}
|
||||||
if (argc) {
|
if (argc) {
|
||||||
while (argc-- > 0)
|
while (argc-- > 0) {
|
||||||
(void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
|
char *path = blockcheck(*argv);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
pfatal("Can't check %s\n", *argv);
|
||||||
|
else
|
||||||
|
(void)checkfilesys(path, 0, 0L, 0);
|
||||||
|
++argv;
|
||||||
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
||||||
@ -203,16 +209,10 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
case 0:
|
case 0:
|
||||||
if (preen)
|
if (preen)
|
||||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||||
return (0);
|
/* fall through */
|
||||||
case -1:
|
case -1:
|
||||||
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
|
||||||
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
|
||||||
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
|
|
||||||
sblock.fs_cstotal.cs_nffree, sblock.fs_cstotal.cs_nbfree,
|
|
||||||
sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleared if any questions answered no. Used to decide if
|
* Cleared if any questions answered no. Used to decide if
|
||||||
* the superblock should be marked clean.
|
* the superblock should be marked clean.
|
||||||
@ -304,7 +304,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
muldup = (struct dups *)0;
|
muldup = (struct dups *)0;
|
||||||
inocleanup();
|
inocleanup();
|
||||||
if (fsmodified) {
|
if (fsmodified) {
|
||||||
(void)time(&sblock.fs_time);
|
sblock.fs_time = time(NULL);
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (cvtlevel && sblk.b_dirty) {
|
if (cvtlevel && sblk.b_dirty) {
|
||||||
@ -329,12 +329,13 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
resolved = 0;
|
resolved = 0;
|
||||||
}
|
}
|
||||||
ckfini(resolved);
|
ckfini(resolved);
|
||||||
free(blockmap);
|
|
||||||
free(statemap);
|
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
|
||||||
free((char *)lncntp);
|
if (inostathead[cylno].il_stat != NULL)
|
||||||
if (!fsmodified)
|
free((char *)inostathead[cylno].il_stat);
|
||||||
return (0);
|
free((char *)inostathead);
|
||||||
if (!preen)
|
inostathead = NULL;
|
||||||
|
if (fsmodified && !preen)
|
||||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
||||||
if (rerun)
|
if (rerun)
|
||||||
printf("\n***** PLEASE RERUN FSCK *****\n");
|
printf("\n***** PLEASE RERUN FSCK *****\n");
|
||||||
@ -354,6 +355,8 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
if (!fsmodified)
|
||||||
|
return (0);
|
||||||
if (!preen)
|
if (!preen)
|
||||||
printf("\n***** REBOOT NOW *****\n");
|
printf("\n***** REBOOT NOW *****\n");
|
||||||
sync();
|
sync();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass1.c,v 1.11 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -52,14 +49,17 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
static ufs_daddr_t badblk;
|
static ufs_daddr_t badblk;
|
||||||
static ufs_daddr_t dupblk;
|
static ufs_daddr_t dupblk;
|
||||||
|
static ino_t lastino; /* last inode in use */
|
||||||
|
|
||||||
static void checkinode __P((ino_t inumber, struct inodesc *));
|
static void checkinode __P((ino_t inumber, struct inodesc *));
|
||||||
|
|
||||||
void
|
void
|
||||||
pass1()
|
pass1()
|
||||||
{
|
{
|
||||||
|
u_int8_t *cp;
|
||||||
ino_t inumber;
|
ino_t inumber;
|
||||||
int c, i, cgd;
|
int c, i, cgd, inosused;
|
||||||
|
struct inostat *info;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,15 +81,84 @@ pass1()
|
|||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass1check;
|
idesc.id_func = pass1check;
|
||||||
inumber = 0;
|
|
||||||
n_files = n_blks = 0;
|
n_files = n_blks = 0;
|
||||||
resetinodebuf();
|
|
||||||
for (c = 0; c < sblock.fs_ncg; c++) {
|
for (c = 0; c < sblock.fs_ncg; c++) {
|
||||||
for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
|
inumber = c * sblock.fs_ipg;
|
||||||
if (inumber < ROOTINO)
|
setinodebuf(inumber);
|
||||||
|
inosused = sblock.fs_ipg;
|
||||||
|
/*
|
||||||
|
* If we are using soft updates, then we can trust the
|
||||||
|
* cylinder group inode allocation maps to tell us which
|
||||||
|
* inodes are allocated. We will scan the used inode map
|
||||||
|
* to find the inodes that are really in use, and then
|
||||||
|
* read only those inodes in from disk.
|
||||||
|
*/
|
||||||
|
if (preen && usedsoftdep) {
|
||||||
|
getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
|
||||||
|
if (!cg_chkmagic(&cgrp))
|
||||||
|
pfatal("CG %d: BAD MAGIC NUMBER\n", c);
|
||||||
|
cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY];
|
||||||
|
for ( ; inosused > 0; inosused -= NBBY, cp--) {
|
||||||
|
if (*cp == 0)
|
||||||
|
continue;
|
||||||
|
for (i = 1 << (NBBY - 1); i > 0; i >>= 1) {
|
||||||
|
if (*cp & i)
|
||||||
|
break;
|
||||||
|
inosused--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Allocate inoinfo structures for the allocated inodes.
|
||||||
|
*/
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
|
/*
|
||||||
|
* Scan the allocated inodes.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < inosused; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO) {
|
||||||
|
(void)getnextinode(inumber);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
checkinode(inumber, &idesc);
|
checkinode(inumber, &idesc);
|
||||||
}
|
}
|
||||||
|
lastino += 1;
|
||||||
|
if (inosused < sblock.fs_ipg || inumber == lastino)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* If we were not able to determine in advance which inodes
|
||||||
|
* were in use, then reduce the size of the inoinfo structure
|
||||||
|
* to the size necessary to describe the inodes that we
|
||||||
|
* really found.
|
||||||
|
*/
|
||||||
|
inosused = lastino - (c * sblock.fs_ipg);
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
}
|
}
|
||||||
freeinodebuf();
|
freeinodebuf();
|
||||||
}
|
}
|
||||||
@ -120,7 +189,7 @@ checkinode(inumber, idesc)
|
|||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastino = inumber;
|
lastino = inumber;
|
||||||
@ -158,8 +227,7 @@ checkinode(inumber, idesc)
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
symbuf[dp->di_size] = 0;
|
symbuf[dp->di_size] = 0;
|
||||||
printf("convert symlink %lu(%s) of size %ld\n",
|
printf("convert symlink %lu(%s) of size %ld\n",
|
||||||
(u_long)inumber, symbuf,
|
(u_long)inumber, symbuf, (long)dp->di_size);
|
||||||
(long)dp->di_size);
|
|
||||||
}
|
}
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
||||||
@ -170,8 +238,7 @@ checkinode(inumber, idesc)
|
|||||||
* Fake ndb value so direct/indirect block checks below
|
* Fake ndb value so direct/indirect block checks below
|
||||||
* will detect any garbage after symlink string.
|
* will detect any garbage after symlink string.
|
||||||
*/
|
*/
|
||||||
if (dp->di_size < sblock.fs_maxsymlinklen ||
|
if (dp->di_size < sblock.fs_maxsymlinklen) {
|
||||||
dp->di_blocks == 0) {
|
|
||||||
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
||||||
if (ndb > NDADDR) {
|
if (ndb > NDADDR) {
|
||||||
j = ndb - NDADDR;
|
j = ndb - NDADDR;
|
||||||
@ -200,7 +267,7 @@ checkinode(inumber, idesc)
|
|||||||
if (ftypeok(dp) == 0)
|
if (ftypeok(dp) == 0)
|
||||||
goto unknown;
|
goto unknown;
|
||||||
n_files++;
|
n_files++;
|
||||||
lncntp[inumber] = dp->di_nlink;
|
inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
|
||||||
if (dp->di_nlink <= 0) {
|
if (dp->di_nlink <= 0) {
|
||||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||||
if (zlnp == NULL) {
|
if (zlnp == NULL) {
|
||||||
@ -217,13 +284,14 @@ checkinode(inumber, idesc)
|
|||||||
}
|
}
|
||||||
if (mode == IFDIR) {
|
if (mode == IFDIR) {
|
||||||
if (dp->di_size == 0)
|
if (dp->di_size == 0)
|
||||||
statemap[inumber] = DCLEAR;
|
inoinfo(inumber)->ino_state = DCLEAR;
|
||||||
else
|
else
|
||||||
statemap[inumber] = DSTATE;
|
inoinfo(inumber)->ino_state = DSTATE;
|
||||||
cacheino(dp, inumber);
|
cacheino(dp, inumber);
|
||||||
|
countdirs++;
|
||||||
} else
|
} else
|
||||||
statemap[inumber] = FSTATE;
|
inoinfo(inumber)->ino_state = FSTATE;
|
||||||
typemap[inumber] = IFTODT(mode);
|
inoinfo(inumber)->ino_type = IFTODT(mode);
|
||||||
if (doinglevel2 &&
|
if (doinglevel2 &&
|
||||||
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
@ -251,9 +319,9 @@ checkinode(inumber, idesc)
|
|||||||
return;
|
return;
|
||||||
unknown:
|
unknown:
|
||||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||||
statemap[inumber] = FCLEAR;
|
inoinfo(inumber)->ino_state = FCLEAR;
|
||||||
if (reply("CLEAR") == 1) {
|
if (reply("CLEAR") == 1) {
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -72,7 +69,7 @@ pass1b()
|
|||||||
if (dp == NULL)
|
if (dp == NULL)
|
||||||
continue;
|
continue;
|
||||||
idesc.id_number = inumber;
|
idesc.id_number = inumber;
|
||||||
if (statemap[inumber] != USTATE &&
|
if (inoinfo(inumber)->ino_state != USTATE &&
|
||||||
(ckinode(dp, &idesc) & STOP))
|
(ckinode(dp, &idesc) & STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -64,7 +62,7 @@ pass2()
|
|||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
char pathbuf[MAXPATHLEN + 1];
|
char pathbuf[MAXPATHLEN + 1];
|
||||||
|
|
||||||
switch (statemap[ROOTINO]) {
|
switch (inoinfo(ROOTINO)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
pfatal("ROOT INODE UNALLOCATED");
|
pfatal("ROOT INODE UNALLOCATED");
|
||||||
@ -113,12 +111,13 @@ pass2()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
|
errx(EEXIT, "BAD STATE %d FOR ROOT INODE",
|
||||||
|
inoinfo(ROOTINO)->ino_state);
|
||||||
}
|
}
|
||||||
statemap[ROOTINO] = DFOUND;
|
inoinfo(ROOTINO)->ino_state = DFOUND;
|
||||||
if (newinofmt) {
|
if (newinofmt) {
|
||||||
statemap[WINO] = FSTATE;
|
inoinfo(WINO)->ino_state = FSTATE;
|
||||||
typemap[WINO] = DT_WHT;
|
inoinfo(WINO)->ino_type = DT_WHT;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Sort the directory list into disk block order.
|
* Sort the directory list into disk block order.
|
||||||
@ -181,9 +180,9 @@ pass2()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0 || inp->i_isize == 0)
|
if (inp->i_parent == 0 || inp->i_isize == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE)
|
inoinfo(inp->i_number)->ino_state == DSTATE)
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
if (inp->i_dotdot == inp->i_parent ||
|
if (inp->i_dotdot == inp->i_parent ||
|
||||||
inp->i_dotdot == (ino_t)-1)
|
inp->i_dotdot == (ino_t)-1)
|
||||||
continue;
|
continue;
|
||||||
@ -193,15 +192,15 @@ pass2()
|
|||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fileerror(inp->i_parent, inp->i_number,
|
fileerror(inp->i_parent, inp->i_number,
|
||||||
"BAD INODE NUMBER FOR '..'");
|
"BAD INODE NUMBER FOR '..'");
|
||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
lncntp[inp->i_dotdot]++;
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
inp->i_dotdot = inp->i_parent;
|
inp->i_dotdot = inp->i_parent;
|
||||||
(void)changeino(inp->i_number, "..", inp->i_parent);
|
(void)changeino(inp->i_number, "..", inp->i_parent);
|
||||||
}
|
}
|
||||||
@ -228,7 +227,7 @@ pass2check(idesc)
|
|||||||
* If converting, set directory entry type.
|
* If converting, set directory entry type.
|
||||||
*/
|
*/
|
||||||
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -284,7 +283,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = entrysize;
|
proto.d_reclen = entrysize;
|
||||||
memmove(dirp, &proto, (size_t)entrysize);
|
memmove(dirp, &proto, (size_t)entrysize);
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
||||||
memset(dirp, 0, (size_t)n);
|
memset(dirp, 0, (size_t)n);
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
@ -319,7 +318,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = dirp->d_reclen - n;
|
proto.d_reclen = dirp->d_reclen - n;
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + n);
|
dirp = (struct direct *)((char *)(dirp) + n);
|
||||||
memset(dirp, 0, (size_t)proto.d_reclen);
|
memset(dirp, 0, (size_t)proto.d_reclen);
|
||||||
dirp->d_reclen = proto.d_reclen;
|
dirp->d_reclen = proto.d_reclen;
|
||||||
@ -356,7 +355,7 @@ pass2check(idesc)
|
|||||||
}
|
}
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
if (dirp->d_ino != 0)
|
if (dirp->d_ino != 0)
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
return (ret|KEEPON);
|
return (ret|KEEPON);
|
||||||
chk2:
|
chk2:
|
||||||
if (dirp->d_ino == 0)
|
if (dirp->d_ino == 0)
|
||||||
@ -394,7 +393,7 @@ pass2check(idesc)
|
|||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
} else {
|
} else {
|
||||||
again:
|
again:
|
||||||
switch (statemap[dirp->d_ino]) {
|
switch (inoinfo(dirp->d_ino)->ino_state) {
|
||||||
case USTATE:
|
case USTATE:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
@ -406,7 +405,7 @@ pass2check(idesc)
|
|||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
if (statemap[dirp->d_ino] == FCLEAR)
|
if (inoinfo(dirp->d_ino)->ino_state == FCLEAR)
|
||||||
errmsg = "DUP/BAD";
|
errmsg = "DUP/BAD";
|
||||||
else if (!preen && !usedsoftdep)
|
else if (!preen && !usedsoftdep)
|
||||||
errmsg = "ZERO LENGTH DIRECTORY";
|
errmsg = "ZERO LENGTH DIRECTORY";
|
||||||
@ -418,14 +417,14 @@ pass2check(idesc)
|
|||||||
if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
dp = ginode(dirp->d_ino);
|
dp = ginode(dirp->d_ino);
|
||||||
statemap[dirp->d_ino] =
|
inoinfo(dirp->d_ino)->ino_state =
|
||||||
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
||||||
lncntp[dirp->d_ino] = dp->di_nlink;
|
inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink;
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
if (statemap[idesc->id_number] == DFOUND)
|
if (inoinfo(idesc->id_number)->ino_state == DFOUND)
|
||||||
statemap[dirp->d_ino] = DFOUND;
|
inoinfo(dirp->d_ino)->ino_state = DFOUND;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
@ -439,10 +438,10 @@ pass2check(idesc)
|
|||||||
namebuf);
|
namebuf);
|
||||||
if (preen) {
|
if (preen) {
|
||||||
printf(" (REMOVED)\n");
|
printf(" (REMOVED)\n");
|
||||||
n = 1;
|
n = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idesc->id_entryno > 2)
|
if (idesc->id_entryno > 2)
|
||||||
@ -450,19 +449,20 @@ pass2check(idesc)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) {
|
if (newinofmt &&
|
||||||
|
dirp->d_type != inoinfo(dirp->d_ino)->ino_type) {
|
||||||
fileerror(idesc->id_number, dirp->d_ino,
|
fileerror(idesc->id_number, dirp->d_ino,
|
||||||
"BAD TYPE VALUE");
|
"BAD TYPE VALUE");
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
if (reply("FIX") == 1)
|
if (reply("FIX") == 1)
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
statemap[dirp->d_ino], dirp->d_ino);
|
inoinfo(dirp->d_ino)->ino_state, dirp->d_ino);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
@ -32,45 +32,84 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
pass3()
|
pass3()
|
||||||
{
|
{
|
||||||
register struct inoinfo **inpp, *inp;
|
struct inoinfo *inp;
|
||||||
|
int loopcnt, inpindex, state;
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
int loopcnt;
|
struct inodesc idesc;
|
||||||
|
char namebuf[MAXNAMLEN+1];
|
||||||
|
|
||||||
for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) {
|
for (inpindex = inplast - 1; inpindex >= 0; inpindex--) {
|
||||||
inp = *inpp;
|
inp = inpsort[inpindex];
|
||||||
|
state = inoinfo(inp->i_number)->ino_state;
|
||||||
if (inp->i_number == ROOTINO ||
|
if (inp->i_number == ROOTINO ||
|
||||||
!(inp->i_parent == 0 || statemap[inp->i_number] == DSTATE))
|
(inp->i_parent != 0 && state != DSTATE))
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_number] == DCLEAR)
|
if (state == DCLEAR)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
|
* If we are running with soft updates and we come
|
||||||
|
* across unreferenced directories, we just leave
|
||||||
|
* them in DSTATE which will cause them to be pitched
|
||||||
|
* in pass 4.
|
||||||
|
*/
|
||||||
|
if (preen && resolved && usedsoftdep && state == DSTATE) {
|
||||||
|
if (inp->i_dotdot >= ROOTINO)
|
||||||
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (loopcnt = 0; ; loopcnt++) {
|
for (loopcnt = 0; ; loopcnt++) {
|
||||||
orphan = inp->i_number;
|
orphan = inp->i_number;
|
||||||
if (inp->i_parent == 0 ||
|
if (inp->i_parent == 0 ||
|
||||||
statemap[inp->i_parent] != DSTATE ||
|
inoinfo(inp->i_parent)->ino_state != DSTATE ||
|
||||||
loopcnt > numdirs)
|
loopcnt > countdirs)
|
||||||
break;
|
break;
|
||||||
inp = getinoinfo(inp->i_parent);
|
inp = getinoinfo(inp->i_parent);
|
||||||
}
|
}
|
||||||
(void)linkup(orphan, inp->i_dotdot);
|
if (loopcnt <= countdirs) {
|
||||||
inp->i_parent = inp->i_dotdot = lfdir;
|
if (linkup(orphan, inp->i_dotdot, NULL)) {
|
||||||
lncntp[lfdir]--;
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
statemap[orphan] = DFOUND;
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
|
propagate();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", orphan);
|
||||||
|
if (reply("RECONNECT") == 0)
|
||||||
|
continue;
|
||||||
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
|
idesc.id_type = DATA;
|
||||||
|
idesc.id_number = inp->i_parent;
|
||||||
|
idesc.id_parent = orphan;
|
||||||
|
idesc.id_func = findname;
|
||||||
|
idesc.id_name = namebuf;
|
||||||
|
if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0)
|
||||||
|
pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY");
|
||||||
|
if (linkup(orphan, inp->i_parent, namebuf)) {
|
||||||
|
idesc.id_func = clearentry;
|
||||||
|
if (ckinode(ginode(inp->i_parent), &idesc) & FOUND)
|
||||||
|
inoinfo(orphan)->ino_linkcnt++;
|
||||||
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
propagate();
|
propagate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -55,22 +53,27 @@ pass4()
|
|||||||
register struct zlncnt *zlnp;
|
register struct zlncnt *zlnp;
|
||||||
struct dinode *dp;
|
struct dinode *dp;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
int n;
|
int i, n, cg;
|
||||||
|
|
||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
for (inumber = ROOTINO; inumber <= lastino; inumber++) {
|
for (cg = 0; cg < sblock.fs_ncg; cg++) {
|
||||||
idesc.id_number = inumber;
|
inumber = cg * sblock.fs_ipg;
|
||||||
switch (statemap[inumber]) {
|
for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO)
|
||||||
|
continue;
|
||||||
|
idesc.id_number = inumber;
|
||||||
|
switch (inoinfo(inumber)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
n = lncntp[inumber];
|
n = inoinfo(inumber)->ino_linkcnt;
|
||||||
if (n)
|
if (n) {
|
||||||
adjust(&idesc, (short)n);
|
adjust(&idesc, (short)n);
|
||||||
else {
|
break;
|
||||||
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
|
}
|
||||||
|
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) {
|
||||||
if (zlnp->zlncnt == inumber) {
|
if (zlnp->zlncnt == inumber) {
|
||||||
zlnp->zlncnt = zlnhead->zlncnt;
|
zlnp->zlncnt = zlnhead->zlncnt;
|
||||||
zlnp = zlnhead;
|
zlnp = zlnhead;
|
||||||
@ -79,30 +82,31 @@ pass4()
|
|||||||
clri(&idesc, "UNREF", 1);
|
clri(&idesc, "UNREF", 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case DSTATE:
|
|
||||||
clri(&idesc, "UNREF", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DCLEAR:
|
|
||||||
dp = ginode(inumber);
|
|
||||||
if (dp->di_size == 0) {
|
|
||||||
clri(&idesc, "ZERO LENGTH", 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DSTATE:
|
||||||
|
clri(&idesc, "UNREF", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DCLEAR:
|
||||||
|
dp = ginode(inumber);
|
||||||
|
if (dp->di_size == 0) {
|
||||||
|
clri(&idesc, "ZERO LENGTH", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case FCLEAR:
|
||||||
|
clri(&idesc, "BAD/DUP", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USTATE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
|
inoinfo(inumber)->ino_state, inumber);
|
||||||
}
|
}
|
||||||
/* fall through */
|
|
||||||
case FCLEAR:
|
|
||||||
clri(&idesc, "BAD/DUP", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USTATE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
|
||||||
statemap[inumber], inumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass5.c,v 1.13 1998/08/04 09:19:03 phk Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -52,7 +49,7 @@ static const char rcsid[] =
|
|||||||
void
|
void
|
||||||
pass5()
|
pass5()
|
||||||
{
|
{
|
||||||
int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
|
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
|
||||||
int inomapsize, blkmapsize;
|
int inomapsize, blkmapsize;
|
||||||
struct fs *fs = &sblock;
|
struct fs *fs = &sblock;
|
||||||
struct cg *cg = &cgrp;
|
struct cg *cg = &cgrp;
|
||||||
@ -66,7 +63,7 @@ pass5()
|
|||||||
register struct cg *newcg = (struct cg *)buf;
|
register struct cg *newcg = (struct cg *)buf;
|
||||||
struct ocg *ocg = (struct ocg *)buf;
|
struct ocg *ocg = (struct ocg *)buf;
|
||||||
|
|
||||||
statemap[WINO] = USTATE;
|
inoinfo(WINO)->ino_state = USTATE;
|
||||||
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
||||||
newcg->cg_niblk = fs->fs_ipg;
|
newcg->cg_niblk = fs->fs_ipg;
|
||||||
if (cvtlevel >= 3) {
|
if (cvtlevel >= 3) {
|
||||||
@ -207,8 +204,8 @@ pass5()
|
|||||||
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
||||||
ocg->cg_magic = CG_MAGIC;
|
ocg->cg_magic = CG_MAGIC;
|
||||||
j = fs->fs_ipg * c;
|
j = fs->fs_ipg * c;
|
||||||
for (i = 0; i < fs->fs_ipg; j++, i++) {
|
for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
|
||||||
switch (statemap[j]) {
|
switch (inoinfo(j)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
break;
|
break;
|
||||||
@ -229,7 +226,7 @@ pass5()
|
|||||||
if (j < ROOTINO)
|
if (j < ROOTINO)
|
||||||
break;
|
break;
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
||||||
statemap[j], j);
|
inoinfo(j)->ino_state, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
@ -325,7 +322,7 @@ pass5()
|
|||||||
if (cg_inosused(cg)[i] & (1 << k))
|
if (cg_inosused(cg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
||||||
c * fs->fs_ipg + i * 8 + k);
|
c * fs->fs_ipg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < blkmapsize; i++) {
|
for (i = 0; i < blkmapsize; i++) {
|
||||||
@ -338,7 +335,7 @@ pass5()
|
|||||||
if (cg_blksfree(newcg)[i] & (1 << k))
|
if (cg_blksfree(newcg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
||||||
c * fs->fs_fpg + i * 8 + k);
|
c * fs->fs_fpg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,24 +352,7 @@ pass5()
|
|||||||
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
||||||
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
||||||
fs->fs_ronly = 0;
|
fs->fs_ronly = 0;
|
||||||
|
fs->fs_fmod = 0;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (fs->fs_fmod != 0) {
|
|
||||||
pwarn("MODIFIED FLAG SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_fmod = 0;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fs->fs_clean == 0) {
|
|
||||||
pwarn("CLEAN FLAG NOT SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_clean = 1;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -46,7 +42,7 @@ static const char rcsid[] =
|
|||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <errno.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -93,7 +89,8 @@ checkfstab(preen, maxrun, docheck, chkit)
|
|||||||
sumstatus = 0;
|
sumstatus = 0;
|
||||||
for (passno = 1; passno <= 2; passno++) {
|
for (passno = 1; passno <= 2; passno++) {
|
||||||
if (setfsent() == 0) {
|
if (setfsent() == 0) {
|
||||||
warnx("can't open checklist file: %s", _PATH_FSTAB);
|
fprintf(stderr, "Can't open checklist file: %s\n",
|
||||||
|
_PATH_FSTAB);
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
while ((fsp = getfsent()) != 0) {
|
while ((fsp = getfsent()) != 0) {
|
||||||
@ -222,11 +219,15 @@ finddisk(name)
|
|||||||
dk->name[len] == 0)
|
dk->name[len] == 0)
|
||||||
return (dk);
|
return (dk);
|
||||||
}
|
}
|
||||||
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL)
|
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
dk = *dkp;
|
dk = *dkp;
|
||||||
if ((dk->name = malloc(len + 1)) == NULL)
|
if ((dk->name = malloc(len + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strncpy(dk->name, name, len);
|
(void)strncpy(dk->name, name, len);
|
||||||
dk->name[len] = '\0';
|
dk->name[len] = '\0';
|
||||||
dk->part = NULL;
|
dk->part = NULL;
|
||||||
@ -249,14 +250,20 @@ addpart(name, fsname, auxdata)
|
|||||||
printf("%s in fstab more than once!\n", name);
|
printf("%s in fstab more than once!\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL)
|
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
pt = *ppt;
|
pt = *ppt;
|
||||||
if ((pt->name = malloc(strlen(name) + 1)) == NULL)
|
if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->name, name);
|
(void)strcpy(pt->name, name);
|
||||||
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL)
|
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->fsname, fsname);
|
(void)strcpy(pt->fsname, fsname);
|
||||||
pt->next = NULL;
|
pt->next = NULL;
|
||||||
pt->auxdata = auxdata;
|
pt->auxdata = auxdata;
|
||||||
@ -271,7 +278,7 @@ startdisk(dk, checkit)
|
|||||||
|
|
||||||
dk->pid = fork();
|
dk->pid = fork();
|
||||||
if (dk->pid < 0) {
|
if (dk->pid < 0) {
|
||||||
warn("fork");
|
perror("fork");
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
if (dk->pid == 0)
|
if (dk->pid == 0)
|
||||||
@ -287,19 +294,17 @@ blockcheck(origname)
|
|||||||
struct stat stslash, stblock, stchar;
|
struct stat stslash, stblock, stchar;
|
||||||
char *newname, *raw;
|
char *newname, *raw;
|
||||||
struct fstab *fsinfo;
|
struct fstab *fsinfo;
|
||||||
int retried = 0, l;
|
int retried = 0, len;
|
||||||
|
|
||||||
hotroot = 0;
|
hotroot = 0;
|
||||||
if (stat("/", &stslash) < 0) {
|
if (stat("/", &stslash) < 0) {
|
||||||
warn("/");
|
printf("Can't stat /: %s\n", strerror(errno));
|
||||||
printf("Can't stat root\n");
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
newname = origname;
|
newname = origname;
|
||||||
retry:
|
retry:
|
||||||
if (stat(newname, &stblock) < 0) {
|
if (stat(newname, &stblock) < 0) {
|
||||||
warn("%s", newname);
|
printf("Can't stat %s: %s\n", newname, strerror(errno));
|
||||||
printf("Can't stat %s\n", newname);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
||||||
@ -307,8 +312,7 @@ blockcheck(origname)
|
|||||||
hotroot++;
|
hotroot++;
|
||||||
raw = rawname(newname);
|
raw = rawname(newname);
|
||||||
if (stat(raw, &stchar) < 0) {
|
if (stat(raw, &stchar) < 0) {
|
||||||
warn("%s", raw);
|
printf("Can't stat %s: %s\n", raw, strerror(errno));
|
||||||
printf("Can't stat %s\n", raw);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
||||||
@ -318,15 +322,15 @@ blockcheck(origname)
|
|||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
||||||
newname = unrawname(origname);
|
newname = unrawname(newname);
|
||||||
retried++;
|
retried++;
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
||||||
l = strlen(origname) - 1;
|
len = strlen(origname) - 1;
|
||||||
if (l > 0 && origname[l] == '/')
|
if (len > 0 && origname[len] == '/')
|
||||||
/* remove trailing slash */
|
/* remove trailing slash */
|
||||||
origname[l] = '\0';
|
origname[len] = '\0';
|
||||||
if(!(fsinfo=getfsfile(origname))) {
|
if ((fsinfo = getfsfile(origname)) == NULL) {
|
||||||
printf("Can't resolve %s to character special device",
|
printf("Can't resolve %s to character special device",
|
||||||
origname);
|
origname);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -32,16 +32,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: setup.c,v 1.11 1998/06/15 07:07:21 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#define DKTYPENAMES
|
#define DKTYPENAMES
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
@ -82,7 +79,7 @@ setup(dev)
|
|||||||
|
|
||||||
havesb = 0;
|
havesb = 0;
|
||||||
fswritefd = -1;
|
fswritefd = -1;
|
||||||
skipclean = preen;
|
skipclean = fflag ? 0 : preen;
|
||||||
if (stat(dev, &statb) < 0) {
|
if (stat(dev, &statb) < 0) {
|
||||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||||
return (0);
|
return (0);
|
||||||
@ -114,8 +111,7 @@ setup(dev)
|
|||||||
asblk.b_un.b_buf = malloc(SBSIZE);
|
asblk.b_un.b_buf = malloc(SBSIZE);
|
||||||
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
||||||
errx(EEXIT, "cannot allocate space for superblock");
|
errx(EEXIT, "cannot allocate space for superblock");
|
||||||
lp = getdisklabel((char *)NULL, fsreadfd);
|
if ((lp = getdisklabel(NULL, fsreadfd)))
|
||||||
if (lp)
|
|
||||||
dev_bsize = secsize = lp->d_secsize;
|
dev_bsize = secsize = lp->d_secsize;
|
||||||
else
|
else
|
||||||
dev_bsize = secsize = DEV_BSIZE;
|
dev_bsize = secsize = DEV_BSIZE;
|
||||||
@ -147,6 +143,10 @@ setup(dev)
|
|||||||
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
||||||
bflag = 0;
|
bflag = 0;
|
||||||
}
|
}
|
||||||
|
if (skipclean && sblock.fs_clean) {
|
||||||
|
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
maxfsblock = sblock.fs_size;
|
maxfsblock = sblock.fs_size;
|
||||||
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
||||||
/*
|
/*
|
||||||
@ -264,12 +264,6 @@ setup(dev)
|
|||||||
asked++;
|
asked++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* If we survive the above basic checks and are preening,
|
|
||||||
* quit here unless forced.
|
|
||||||
*/
|
|
||||||
if (skipclean && sblock.fs_clean && !fflag)
|
|
||||||
return (-1);
|
|
||||||
/*
|
/*
|
||||||
* allocate and initialize the necessary maps
|
* allocate and initialize the necessary maps
|
||||||
*/
|
*/
|
||||||
@ -280,22 +274,11 @@ setup(dev)
|
|||||||
(unsigned)bmapsize);
|
(unsigned)bmapsize);
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
statemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
inostathead = calloc((unsigned)(sblock.fs_ncg),
|
||||||
if (statemap == NULL) {
|
sizeof(struct inostatlist));
|
||||||
printf("cannot alloc %u bytes for statemap\n",
|
if (inostathead == NULL) {
|
||||||
(unsigned)(maxino + 1));
|
printf("cannot alloc %u bytes for inostathead\n",
|
||||||
goto badsb;
|
(unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
|
||||||
}
|
|
||||||
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
|
||||||
if (typemap == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for typemap\n",
|
|
||||||
(unsigned)(maxino + 1));
|
|
||||||
goto badsb;
|
|
||||||
}
|
|
||||||
lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
|
|
||||||
if (lncntp == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for lncntp\n",
|
|
||||||
(unsigned)(maxino + 1) * sizeof(short));
|
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
numdirs = sblock.fs_cstotal.cs_ndir;
|
numdirs = sblock.fs_cstotal.cs_ndir;
|
||||||
@ -474,9 +457,11 @@ calcsb(dev, devfd, fs)
|
|||||||
fstypenames[pp->p_fstype] : "unknown");
|
fstypenames[pp->p_fstype] : "unknown");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (pp->p_fsize == 0 || pp->p_frag == 0) {
|
if (pp->p_fsize == 0 || pp->p_frag == 0 ||
|
||||||
pfatal("%s: LABELED AS A %s FILE SYSTEM, BUT BLOCK SIZE IS 0\n",
|
pp->p_cpg == 0 || pp->p_size == 0) {
|
||||||
dev, fstypenames[pp->p_fstype]);
|
pfatal("%s: %s: type %s fsize %d, frag %d, cpg %d, size %d\n",
|
||||||
|
dev, "INCOMPLETE LABEL", fstypenames[pp->p_fstype],
|
||||||
|
pp->p_fsize, pp->p_frag, pp->p_cpg, pp->p_size);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
memset(fs, 0, sizeof(struct fs));
|
memset(fs, 0, sizeof(struct fs));
|
||||||
|
@ -32,20 +32,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -115,6 +111,26 @@ reply(question)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up state information for an inode.
|
||||||
|
*/
|
||||||
|
struct inostat *
|
||||||
|
inoinfo(inum)
|
||||||
|
ino_t inum;
|
||||||
|
{
|
||||||
|
static struct inostat unallocated = { USTATE, 0, 0 };
|
||||||
|
struct inostatlist *ilp;
|
||||||
|
int iloff;
|
||||||
|
|
||||||
|
if (inum > maxino)
|
||||||
|
errx(EEXIT, "inoinfo: inumber %d out of range", inum);
|
||||||
|
ilp = &inostathead[inum / sblock.fs_ipg];
|
||||||
|
iloff = inum % sblock.fs_ipg;
|
||||||
|
if (iloff >= ilp->il_numalloced)
|
||||||
|
return (&unallocated);
|
||||||
|
return (&ilp->il_stat[iloff]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Malloc buffers and set up cache.
|
* Malloc buffers and set up cache.
|
||||||
*/
|
*/
|
||||||
@ -270,16 +286,23 @@ ckfini(markclean)
|
|||||||
free((char *)bp);
|
free((char *)bp);
|
||||||
}
|
}
|
||||||
if (bufhead.b_size != cnt)
|
if (bufhead.b_size != cnt)
|
||||||
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
errx(EEXIT, "Panic: lost %d buffers", bufhead.b_size - cnt);
|
||||||
pbp = pdirbp = (struct bufarea *)0;
|
pbp = pdirbp = (struct bufarea *)0;
|
||||||
if (markclean && sblock.fs_clean == 0) {
|
if (sblock.fs_clean != markclean) {
|
||||||
sblock.fs_clean = 1;
|
sblock.fs_clean = markclean;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
ofsmodified = fsmodified;
|
ofsmodified = fsmodified;
|
||||||
flush(fswritefd, &sblk);
|
flush(fswritefd, &sblk);
|
||||||
fsmodified = ofsmodified;
|
fsmodified = ofsmodified;
|
||||||
if (!preen)
|
if (!preen) {
|
||||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
printf("\n***** FILE SYSTEM MARKED %s *****\n",
|
||||||
|
markclean ? "CLEAN" : "DIRTY");
|
||||||
|
if (!markclean)
|
||||||
|
rerun = 1;
|
||||||
|
}
|
||||||
|
} else if (!preen && !markclean) {
|
||||||
|
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
||||||
|
rerun = 1;
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug)
|
||||||
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
||||||
@ -324,6 +347,8 @@ bread(fd, buf, blk, size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (errs)
|
||||||
|
resolved = 0;
|
||||||
return (errs);
|
return (errs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +373,7 @@ bwrite(fd, buf, blk, size)
|
|||||||
fsmodified = 1;
|
fsmodified = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
resolved = 0;
|
||||||
rwerror("WRITE", blk);
|
rwerror("WRITE", blk);
|
||||||
if (lseek(fd, offset, 0) < 0)
|
if (lseek(fd, offset, 0) < 0)
|
||||||
rwerror("SEEK", blk);
|
rwerror("SEEK", blk);
|
||||||
@ -438,7 +464,8 @@ getpathname(namebuf, curdir, ino)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (busy ||
|
if (busy ||
|
||||||
(statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) {
|
(inoinfo(curdir)->ino_state != DSTATE &&
|
||||||
|
inoinfo(curdir)->ino_state != DFOUND)) {
|
||||||
(void)strcpy(namebuf, "?");
|
(void)strcpy(namebuf, "?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -497,6 +524,7 @@ void
|
|||||||
catchquit(sig)
|
catchquit(sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("returning to single-user after filesystem check\n");
|
printf("returning to single-user after filesystem check\n");
|
||||||
returntosingle = 1;
|
returntosingle = 1;
|
||||||
(void)signal(SIGQUIT, SIG_DFL);
|
(void)signal(SIGQUIT, SIG_DFL);
|
||||||
@ -589,14 +617,16 @@ pfatal(fmt, va_alist)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (usedsoftdep)
|
if (usedsoftdep)
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\nUNEXPECTED SOFTDEP INCONSISTENCY\n");
|
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cdevname == NULL)
|
||||||
|
cdevname = "fsck";
|
||||||
(void)fprintf(stderr, "%s: ", cdevname);
|
(void)fprintf(stderr, "%s: ", cdevname);
|
||||||
(void)vfprintf(stderr, fmt, ap);
|
(void)vfprintf(stderr, fmt, ap);
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||||
cdevname, usedsoftdep ? " SOFTDEP " : " ");
|
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
|
||||||
ckfini(0);
|
ckfini(0);
|
||||||
exit(EEXIT);
|
exit(EEXIT);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: dir.c,v 1.11 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -88,9 +85,9 @@ propagate()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0)
|
if (inp->i_parent == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE) {
|
inoinfo(inp->i_number)->ino_state == DSTATE) {
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
change++;
|
change++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,6 +120,8 @@ dirscan(idesc)
|
|||||||
idesc->id_loc = 0;
|
idesc->id_loc = 0;
|
||||||
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
||||||
dsize = dp->d_reclen;
|
dsize = dp->d_reclen;
|
||||||
|
if (dsize > sizeof(dbuf))
|
||||||
|
dsize = sizeof(dbuf);
|
||||||
memmove(dbuf, dp, (size_t)dsize);
|
memmove(dbuf, dp, (size_t)dsize);
|
||||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||||
if (!newinofmt) {
|
if (!newinofmt) {
|
||||||
@ -235,8 +234,7 @@ dircheck(idesc, dp)
|
|||||||
int spaceleft;
|
int spaceleft;
|
||||||
|
|
||||||
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||||
if (dp->d_ino >= maxino ||
|
if (dp->d_reclen == 0 ||
|
||||||
dp->d_reclen == 0 ||
|
|
||||||
dp->d_reclen > spaceleft ||
|
dp->d_reclen > spaceleft ||
|
||||||
(dp->d_reclen & 0x3) != 0)
|
(dp->d_reclen & 0x3) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
@ -306,13 +304,40 @@ adjust(idesc, lcnt)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
int lcnt;
|
int lcnt;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
struct dinode *dp;
|
||||||
|
int saveresolved;
|
||||||
|
|
||||||
dp = ginode(idesc->id_number);
|
dp = ginode(idesc->id_number);
|
||||||
if (dp->di_nlink == lcnt) {
|
if (dp->di_nlink == lcnt) {
|
||||||
if (linkup(idesc->id_number, (ino_t)0) == 0)
|
/*
|
||||||
clri(idesc, "UNREF", 0);
|
* If we have not hit any unresolved problems, are running
|
||||||
} else {
|
* in preen mode, and are on a filesystem using soft updates,
|
||||||
|
* then just toss any partially allocated files.
|
||||||
|
*/
|
||||||
|
if (resolved && preen && usedsoftdep) {
|
||||||
|
clri(idesc, "UNREF", 1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The filesystem can be marked clean even if
|
||||||
|
* a file is not linked up, but is cleared.
|
||||||
|
* Hence, resolved should not be cleared when
|
||||||
|
* linkup is answered no, but clri is answered yes.
|
||||||
|
*/
|
||||||
|
saveresolved = resolved;
|
||||||
|
if (linkup(idesc->id_number, (ino_t)0, NULL) == 0) {
|
||||||
|
resolved = saveresolved;
|
||||||
|
clri(idesc, "UNREF", 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Account for the new reference created by linkup().
|
||||||
|
*/
|
||||||
|
dp = ginode(idesc->id_number);
|
||||||
|
lcnt--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lcnt != 0) {
|
||||||
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
|
||||||
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
|
||||||
pinode(idesc->id_number);
|
pinode(idesc->id_number);
|
||||||
@ -355,7 +380,7 @@ mkentry(idesc)
|
|||||||
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
||||||
dirp->d_reclen = newent.d_reclen;
|
dirp->d_reclen = newent.d_reclen;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
dirp->d_namlen = newent.d_namlen;
|
dirp->d_namlen = newent.d_namlen;
|
||||||
@ -388,16 +413,17 @@ chgino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dirp->d_ino = idesc->id_parent;
|
dirp->d_ino = idesc->id_parent;
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
dirp->d_type = typemap[idesc->id_parent];
|
dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
|
||||||
else
|
else
|
||||||
dirp->d_type = 0;
|
dirp->d_type = 0;
|
||||||
return (ALTERED|STOP);
|
return (ALTERED|STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
linkup(orphan, parentdir)
|
linkup(orphan, parentdir, name)
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
ino_t parentdir;
|
ino_t parentdir;
|
||||||
|
char *name;
|
||||||
{
|
{
|
||||||
register struct dinode *dp;
|
register struct dinode *dp;
|
||||||
int lostdir;
|
int lostdir;
|
||||||
@ -410,7 +436,7 @@ linkup(orphan, parentdir)
|
|||||||
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
lostdir = (dp->di_mode & IFMT) == IFDIR;
|
||||||
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
|
||||||
pinode(orphan);
|
pinode(orphan);
|
||||||
if ((preen || usedsoftdep) && dp->di_size == 0)
|
if (preen && dp->di_size == 0)
|
||||||
return (0);
|
return (0);
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (RECONNECTED)\n");
|
printf(" (RECONNECTED)\n");
|
||||||
@ -431,6 +457,7 @@ linkup(orphan, parentdir)
|
|||||||
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
|
||||||
if (lfdir != 0) {
|
if (lfdir != 0) {
|
||||||
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
if (makeentry(ROOTINO, lfdir, lfname) != 0) {
|
||||||
|
numdirs++;
|
||||||
if (preen)
|
if (preen)
|
||||||
printf(" (CREATED)\n");
|
printf(" (CREATED)\n");
|
||||||
} else {
|
} else {
|
||||||
@ -466,21 +493,21 @@ linkup(orphan, parentdir)
|
|||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
idesc.id_number = oldlfdir;
|
idesc.id_number = oldlfdir;
|
||||||
adjust(&idesc, lncntp[oldlfdir] + 1);
|
adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1);
|
||||||
lncntp[oldlfdir] = 0;
|
inoinfo(oldlfdir)->ino_linkcnt = 0;
|
||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
}
|
}
|
||||||
if (statemap[lfdir] != DFOUND) {
|
if (inoinfo(lfdir)->ino_state != DFOUND) {
|
||||||
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
pfatal("SORRY. NO lost+found DIRECTORY\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
(void)lftempname(tempname, orphan);
|
(void)lftempname(tempname, orphan);
|
||||||
if (makeentry(lfdir, orphan, tempname) == 0) {
|
if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) {
|
||||||
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
lncntp[orphan]--;
|
inoinfo(orphan)->ino_linkcnt--;
|
||||||
if (lostdir) {
|
if (lostdir) {
|
||||||
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
|
||||||
parentdir != (ino_t)-1)
|
parentdir != (ino_t)-1)
|
||||||
@ -488,19 +515,11 @@ linkup(orphan, parentdir)
|
|||||||
dp = ginode(lfdir);
|
dp = ginode(lfdir);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
inodirty();
|
inodirty();
|
||||||
lncntp[lfdir]++;
|
inoinfo(lfdir)->ino_linkcnt++;
|
||||||
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
pwarn("DIR I=%lu CONNECTED. ", orphan);
|
||||||
if (parentdir != (ino_t)-1) {
|
if (parentdir != (ino_t)-1) {
|
||||||
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
printf("PARENT WAS I=%lu\n", (u_long)parentdir);
|
||||||
/*
|
inoinfo(parentdir)->ino_linkcnt++;
|
||||||
* The parent directory, because of the ordering
|
|
||||||
* guarantees, has had the link count incremented
|
|
||||||
* for the child, but no entry was made. This
|
|
||||||
* fixes the parent link count so that fsck does
|
|
||||||
* not need to be rerun.
|
|
||||||
*/
|
|
||||||
lncntp[parentdir]++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (preen == 0)
|
if (preen == 0)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -658,19 +677,20 @@ allocdir(parent, request, mode)
|
|||||||
dp->di_nlink = 2;
|
dp->di_nlink = 2;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (ino == ROOTINO) {
|
if (ino == ROOTINO) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
return(ino);
|
return(ino);
|
||||||
}
|
}
|
||||||
if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) {
|
if (inoinfo(parent)->ino_state != DSTATE &&
|
||||||
|
inoinfo(parent)->ino_state != DFOUND) {
|
||||||
freeino(ino);
|
freeino(ino);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
cacheino(dp, ino);
|
cacheino(dp, ino);
|
||||||
statemap[ino] = statemap[parent];
|
inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
|
||||||
if (statemap[ino] == DSTATE) {
|
if (inoinfo(ino)->ino_state == DSTATE) {
|
||||||
lncntp[ino] = dp->di_nlink;
|
inoinfo(ino)->ino_linkcnt = dp->di_nlink;
|
||||||
lncntp[parent]++;
|
inoinfo(parent)->ino_linkcnt++;
|
||||||
}
|
}
|
||||||
dp = ginode(parent);
|
dp = ginode(parent);
|
||||||
dp->di_nlink++;
|
dp->di_nlink++;
|
||||||
|
@ -42,16 +42,35 @@
|
|||||||
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
|
||||||
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
|
||||||
|
|
||||||
#ifndef BUFSIZ
|
/*
|
||||||
#define BUFSIZ 1024
|
* Each inode on the filesystem is described by the following structure.
|
||||||
#endif
|
* The linkcnt is initially set to the value in the inode. Each time it
|
||||||
|
* is found during the descent in passes 2, 3, and 4 the count is
|
||||||
|
* decremented. Any inodes whose count is non-zero after pass 4 needs to
|
||||||
|
* have its link count adjusted by the value remaining in ino_linkcnt.
|
||||||
|
*/
|
||||||
|
struct inostat {
|
||||||
|
char ino_state; /* state of inode, see below */
|
||||||
|
char ino_type; /* type of inode */
|
||||||
|
short ino_linkcnt; /* number of links not found */
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* Inode states.
|
||||||
|
*/
|
||||||
#define USTATE 01 /* inode not allocated */
|
#define USTATE 01 /* inode not allocated */
|
||||||
#define FSTATE 02 /* inode is file */
|
#define FSTATE 02 /* inode is file */
|
||||||
#define DSTATE 03 /* inode is directory */
|
#define DSTATE 03 /* inode is directory */
|
||||||
#define DFOUND 04 /* directory found during descent */
|
#define DFOUND 04 /* directory found during descent */
|
||||||
#define DCLEAR 05 /* directory is to be cleared */
|
#define DCLEAR 05 /* directory is to be cleared */
|
||||||
#define FCLEAR 06 /* file is to be cleared */
|
#define FCLEAR 06 /* file is to be cleared */
|
||||||
|
/*
|
||||||
|
* Inode state information is contained on per cylinder group lists
|
||||||
|
* which are described by the following structure.
|
||||||
|
*/
|
||||||
|
struct inostatlist {
|
||||||
|
long il_numalloced; /* number of inodes allocated in this cg */
|
||||||
|
struct inostat *il_stat;/* inostat info for this cylinder group */
|
||||||
|
} *inostathead;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* buffer cache structure.
|
* buffer cache structure.
|
||||||
@ -163,11 +182,12 @@ struct inoinfo {
|
|||||||
ufs_daddr_t i_blks[1]; /* actually longer */
|
ufs_daddr_t i_blks[1]; /* actually longer */
|
||||||
} **inphead, **inpsort;
|
} **inphead, **inpsort;
|
||||||
long numdirs, listmax, inplast;
|
long numdirs, listmax, inplast;
|
||||||
|
long countdirs; /* number of directories we actually found */
|
||||||
|
|
||||||
char *cdevname; /* name of device being checked */
|
char *cdevname; /* name of device being checked */
|
||||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||||
long secsize; /* actual disk sector size */
|
long secsize; /* actual disk sector size */
|
||||||
char fflag; /* force fs check (ignore clean flag) */
|
char fflag; /* force check, ignore clean flag */
|
||||||
char nflag; /* assume a no response */
|
char nflag; /* assume a no response */
|
||||||
char yflag; /* assume a yes response */
|
char yflag; /* assume a yes response */
|
||||||
int bflag; /* location of alternate super block */
|
int bflag; /* location of alternate super block */
|
||||||
@ -177,23 +197,19 @@ int doinglevel1; /* converting to new cylinder group format */
|
|||||||
int doinglevel2; /* converting to new inode format */
|
int doinglevel2; /* converting to new inode format */
|
||||||
int newinofmt; /* filesystem has new inode format */
|
int newinofmt; /* filesystem has new inode format */
|
||||||
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
char usedsoftdep; /* just fix soft dependency inconsistencies */
|
||||||
char resolved; /* cleared if unresolved changes => not clean */
|
|
||||||
char preen; /* just fix normal inconsistencies */
|
char preen; /* just fix normal inconsistencies */
|
||||||
|
char rerun; /* rerun fsck. Only used in non-preen mode */
|
||||||
|
int returntosingle; /* 1 => return to single user mode on exit */
|
||||||
|
char resolved; /* cleared if unresolved changes => not clean */
|
||||||
char hotroot; /* checking root device */
|
char hotroot; /* checking root device */
|
||||||
char havesb; /* superblock has been read */
|
char havesb; /* superblock has been read */
|
||||||
int fsmodified; /* 1 => write done to file system */
|
int fsmodified; /* 1 => write done to file system */
|
||||||
int fsreadfd; /* file descriptor for reading file system */
|
int fsreadfd; /* file descriptor for reading file system */
|
||||||
int fswritefd; /* file descriptor for writing file system */
|
int fswritefd; /* file descriptor for writing file system */
|
||||||
int returntosingle; /* return to single user mode */
|
|
||||||
int rerun; /* rerun fsck. Only used in non-preen mode */
|
|
||||||
|
|
||||||
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
|
||||||
char *blockmap; /* ptr to primary blk allocation map */
|
char *blockmap; /* ptr to primary blk allocation map */
|
||||||
ino_t maxino; /* number of inodes in file system */
|
ino_t maxino; /* number of inodes in file system */
|
||||||
ino_t lastino; /* last inode in use */
|
|
||||||
char *statemap; /* ptr to inode state table */
|
|
||||||
u_char *typemap; /* ptr to inode type table */
|
|
||||||
short *lncntp; /* ptr to link count table */
|
|
||||||
|
|
||||||
ino_t lfdir; /* lost & found directory inode number */
|
ino_t lfdir; /* lost & found directory inode number */
|
||||||
char *lfname; /* lost & found directory name */
|
char *lfname; /* lost & found directory name */
|
||||||
@ -219,6 +235,7 @@ struct dinode zino;
|
|||||||
|
|
||||||
struct fstab;
|
struct fstab;
|
||||||
|
|
||||||
|
|
||||||
void adjust __P((struct inodesc *, int lcnt));
|
void adjust __P((struct inodesc *, int lcnt));
|
||||||
ufs_daddr_t allocblk __P((long frags));
|
ufs_daddr_t allocblk __P((long frags));
|
||||||
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
ino_t allocdir __P((ino_t parent, ino_t request, int mode));
|
||||||
@ -239,6 +256,7 @@ int chkrange __P((ufs_daddr_t blk, int cnt));
|
|||||||
void ckfini __P((int markclean));
|
void ckfini __P((int markclean));
|
||||||
int ckinode __P((struct dinode *dp, struct inodesc *));
|
int ckinode __P((struct dinode *dp, struct inodesc *));
|
||||||
void clri __P((struct inodesc *, char *type, int flag));
|
void clri __P((struct inodesc *, char *type, int flag));
|
||||||
|
int clearentry __P((struct inodesc *));
|
||||||
void direrror __P((ino_t ino, char *errmesg));
|
void direrror __P((ino_t ino, char *errmesg));
|
||||||
int dirscan __P((struct inodesc *));
|
int dirscan __P((struct inodesc *));
|
||||||
int dofix __P((struct inodesc *, char *msg));
|
int dofix __P((struct inodesc *, char *msg));
|
||||||
@ -262,7 +280,8 @@ void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
|
|||||||
struct dinode *ginode __P((ino_t inumber));
|
struct dinode *ginode __P((ino_t inumber));
|
||||||
void inocleanup __P((void));
|
void inocleanup __P((void));
|
||||||
void inodirty __P((void));
|
void inodirty __P((void));
|
||||||
int linkup __P((ino_t orphan, ino_t parentdir));
|
struct inostat *inoinfo __P((ino_t inum));
|
||||||
|
int linkup __P((ino_t orphan, ino_t parentdir, char *name));
|
||||||
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
int makeentry __P((ino_t parent, ino_t ino, char *name));
|
||||||
void panic __P((const char *fmt, ...));
|
void panic __P((const char *fmt, ...));
|
||||||
void pass1 __P((void));
|
void pass1 __P((void));
|
||||||
@ -278,6 +297,6 @@ void pinode __P((ino_t ino));
|
|||||||
void propagate __P((void));
|
void propagate __P((void));
|
||||||
void pwarn __P((const char *fmt, ...));
|
void pwarn __P((const char *fmt, ...));
|
||||||
int reply __P((char *question));
|
int reply __P((char *question));
|
||||||
void resetinodebuf __P((void));
|
void setinodebuf __P((ino_t));
|
||||||
int setup __P((char *dev));
|
int setup __P((char *dev));
|
||||||
void voidquit __P((int));
|
void voidquit __P((int));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
.\"
|
||||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -10,7 +11,7 @@
|
|||||||
.\" notice, this list of conditions and the following disclaimer in the
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
.\" 3. All advertising materials mentioning features or use of this software
|
.\" 3. All advertising materials mentioning features or use of this software
|
||||||
.\" must display the following acknowledgment:
|
.\" must display the following acknowledgement:
|
||||||
.\" This product includes software developed by the University of
|
.\" This product includes software developed by the University of
|
||||||
.\" California, Berkeley and its contributors.
|
.\" California, Berkeley and its contributors.
|
||||||
.\" 4. Neither the name of the University nor the names of its contributors
|
.\" 4. Neither the name of the University nor the names of its contributors
|
||||||
@ -30,9 +31,8 @@
|
|||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
|
||||||
.\" $Id: fsck.8,v 1.10 1997/03/12 16:35:26 bde Exp $
|
|
||||||
.\"
|
.\"
|
||||||
.Dd May 9, 1995
|
.Dd November 15, 1996
|
||||||
.Dt FSCK 8
|
.Dt FSCK 8
|
||||||
.Os BSD 4
|
.Os BSD 4
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -43,24 +43,25 @@
|
|||||||
.Fl p
|
.Fl p
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
|
.Op Ar filesystem
|
||||||
|
.Ar ...
|
||||||
.Nm fsck
|
.Nm fsck
|
||||||
|
.Op Fl ny
|
||||||
.Op Fl b Ar block#
|
.Op Fl b Ar block#
|
||||||
.Op Fl c Ar level
|
.Op Fl c Ar level
|
||||||
.Op Fl l Ar maxparallel
|
.Op Fl l Ar maxparallel
|
||||||
.Op Fl y
|
|
||||||
.Op Fl n
|
|
||||||
.Op Fl m Ar mode
|
.Op Fl m Ar mode
|
||||||
.Op Ar filesystem
|
.Op Ar filesystem
|
||||||
.Ar ...
|
.Ar ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The first form of
|
The first form of
|
||||||
.Nm
|
.Nm fsck
|
||||||
preens a standard set of filesystems or the specified filesystems.
|
preens a standard set of filesystems or the specified filesystems.
|
||||||
It is normally used in the script
|
It is normally used in the script
|
||||||
.Pa /etc/rc
|
.Pa /etc/rc
|
||||||
during automatic reboot.
|
during automatic reboot.
|
||||||
Here
|
Here
|
||||||
.Nm
|
.Nm fsck
|
||||||
reads the table
|
reads the table
|
||||||
.Pa /etc/fstab
|
.Pa /etc/fstab
|
||||||
to determine which filesystems to check.
|
to determine which filesystems to check.
|
||||||
@ -73,22 +74,18 @@ running one process per disk drive.
|
|||||||
The disk drive containing each filesystem is inferred from the longest prefix
|
The disk drive containing each filesystem is inferred from the longest prefix
|
||||||
of the device name that ends in a digit; the remaining characters are assumed
|
of the device name that ends in a digit; the remaining characters are assumed
|
||||||
to be the partition designator.
|
to be the partition designator.
|
||||||
.Pp
|
In preening mode,
|
||||||
The clean flag of each filesystem's superblock is examined and only those filesystems that
|
filesystems that are marked clean are skipped.
|
||||||
are not marked clean are checked.
|
|
||||||
Filesystems are marked clean when they are unmounted,
|
Filesystems are marked clean when they are unmounted,
|
||||||
when they have been mounted read-only, or when
|
when they have been mounted read-only, or when
|
||||||
.Nm
|
.Nm fsck
|
||||||
runs on them successfully.
|
runs on them successfully.
|
||||||
If the
|
|
||||||
.Fl f
|
|
||||||
option is specified, the filesystems
|
|
||||||
will be checked regardless of the state of their clean flag.
|
|
||||||
.Pp
|
.Pp
|
||||||
The kernel takes care that only a restricted class of innocuous filesystem
|
The kernel takes care that only a restricted class of innocuous filesystem
|
||||||
inconsistencies can happen unless hardware or software failures intervene.
|
inconsistencies can happen unless hardware or software failures intervene.
|
||||||
These are limited to the following:
|
These are limited to the following:
|
||||||
.Bl -item -compact
|
.Pp
|
||||||
|
.Bl -item -compact -offset indent
|
||||||
.It
|
.It
|
||||||
Unreferenced inodes
|
Unreferenced inodes
|
||||||
.It
|
.It
|
||||||
@ -102,7 +99,7 @@ Counts in the super-block wrong
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
These are the only inconsistencies that
|
These are the only inconsistencies that
|
||||||
.Nm
|
.Nm fsck
|
||||||
with the
|
with the
|
||||||
.Fl p
|
.Fl p
|
||||||
option will correct; if it encounters other inconsistencies, it exits
|
option will correct; if it encounters other inconsistencies, it exits
|
||||||
@ -110,7 +107,7 @@ with an abnormal return status and an automatic reboot will then fail.
|
|||||||
For each corrected inconsistency one or more lines will be printed
|
For each corrected inconsistency one or more lines will be printed
|
||||||
identifying the filesystem on which the correction will take place,
|
identifying the filesystem on which the correction will take place,
|
||||||
and the nature of the correction. After successfully correcting a filesystem,
|
and the nature of the correction. After successfully correcting a filesystem,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will print the number of files on that filesystem,
|
will print the number of files on that filesystem,
|
||||||
the number of used and free blocks,
|
the number of used and free blocks,
|
||||||
and the percentage of fragmentation.
|
and the percentage of fragmentation.
|
||||||
@ -118,7 +115,7 @@ and the percentage of fragmentation.
|
|||||||
If sent a
|
If sent a
|
||||||
.Dv QUIT
|
.Dv QUIT
|
||||||
signal,
|
signal,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will finish the filesystem checks, then exit with an abnormal
|
will finish the filesystem checks, then exit with an abnormal
|
||||||
return status that causes an automatic reboot to fail.
|
return status that causes an automatic reboot to fail.
|
||||||
This is useful when you want to finish the filesystem checks during an
|
This is useful when you want to finish the filesystem checks during an
|
||||||
@ -128,7 +125,7 @@ but do not want the machine to come up multiuser after the checks complete.
|
|||||||
Without the
|
Without the
|
||||||
.Fl p
|
.Fl p
|
||||||
option,
|
option,
|
||||||
.Nm
|
.Nm fsck
|
||||||
audits and interactively repairs inconsistent conditions for filesystems.
|
audits and interactively repairs inconsistent conditions for filesystems.
|
||||||
If the filesystem is inconsistent the operator is prompted for concurrence
|
If the filesystem is inconsistent the operator is prompted for concurrence
|
||||||
before each correction is attempted.
|
before each correction is attempted.
|
||||||
@ -144,7 +141,7 @@ is to wait for the operator to respond
|
|||||||
or
|
or
|
||||||
.Li no .
|
.Li no .
|
||||||
If the operator does not have write permission on the filesystem
|
If the operator does not have write permission on the filesystem
|
||||||
.Nm
|
.Nm fsck
|
||||||
will default to a
|
will default to a
|
||||||
.Fl n
|
.Fl n
|
||||||
action.
|
action.
|
||||||
@ -158,38 +155,12 @@ and
|
|||||||
combined.
|
combined.
|
||||||
.Pp
|
.Pp
|
||||||
The following flags are interpreted by
|
The following flags are interpreted by
|
||||||
.Nm Ns .
|
.Nm fsck .
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl b
|
.It Fl b
|
||||||
Use the block specified immediately after the flag as
|
Use the block specified immediately after the flag as
|
||||||
the super block for the filesystem. Block 32 is usually
|
the super block for the filesystem. Block 32 is usually
|
||||||
an alternate super block.
|
an alternate super block.
|
||||||
.It Fl l
|
|
||||||
Limit the number of parallel checks to the number specified in the following
|
|
||||||
argument.
|
|
||||||
By default, the limit is the number of disks, running one process per disk.
|
|
||||||
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
|
||||||
at a time.
|
|
||||||
.It Fl m
|
|
||||||
Use the mode specified in octal immediately after the flag as the
|
|
||||||
permission bits to use when creating the
|
|
||||||
.Pa lost+found
|
|
||||||
directory rather than the default 1777.
|
|
||||||
In particular, systems that do not wish to have lost files accessible
|
|
||||||
by all users on the system should use a more restrictive
|
|
||||||
set of permissions such as 700.
|
|
||||||
.It Fl y
|
|
||||||
Assume a yes response to all questions asked by
|
|
||||||
.Nm Ns ;
|
|
||||||
this should be used with great caution as this is a free license
|
|
||||||
to continue after essentially unlimited trouble has been encountered.
|
|
||||||
.It Fl n
|
|
||||||
Assume a no response to all questions asked by
|
|
||||||
.Nm
|
|
||||||
except for
|
|
||||||
.Ql CONTINUE? ,
|
|
||||||
which is assumed to be affirmative;
|
|
||||||
do not open the filesystem for writing.
|
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Convert the filesystem to the specified level.
|
Convert the filesystem to the specified level.
|
||||||
Note that the level of a filesystem can only be raised.
|
Note that the level of a filesystem can only be raised.
|
||||||
@ -210,7 +181,7 @@ If maxcontig is equal to one, delete any existing segment maps.
|
|||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
In interactive mode,
|
In interactive mode,
|
||||||
.Nm
|
.Nm fsck
|
||||||
will list the conversion to be made
|
will list the conversion to be made
|
||||||
and ask whether the conversion should be done.
|
and ask whether the conversion should be done.
|
||||||
If a negative answer is given,
|
If a negative answer is given,
|
||||||
@ -223,10 +194,44 @@ are being converted at once.
|
|||||||
The format of a filesystem can be determined from the
|
The format of a filesystem can be determined from the
|
||||||
first line of output from
|
first line of output from
|
||||||
.Xr dumpfs 8 .
|
.Xr dumpfs 8 .
|
||||||
|
.It Fl f
|
||||||
|
Force
|
||||||
|
.Nm fsck
|
||||||
|
to check
|
||||||
|
.Sq clean
|
||||||
|
filesystems when preening.
|
||||||
|
.It Fl l
|
||||||
|
Limit the number of parallel checks to the number specified in the following
|
||||||
|
argument.
|
||||||
|
By default, the limit is the number of disks, running one process per disk.
|
||||||
|
If a smaller limit is given, the disks are checked round-robin, one filesystem
|
||||||
|
at a time.
|
||||||
|
.It Fl m
|
||||||
|
Use the mode specified in octal immediately after the flag as the
|
||||||
|
permission bits to use when creating the
|
||||||
|
.Pa lost+found
|
||||||
|
directory rather than the default 1777.
|
||||||
|
In particular, systems that do not wish to have lost files accessible
|
||||||
|
by all users on the system should use a more restrictive
|
||||||
|
set of permissions such as 700.
|
||||||
|
.It Fl n
|
||||||
|
Assume a no response to all questions asked by
|
||||||
|
.Nm fsck
|
||||||
|
except for
|
||||||
|
.Ql CONTINUE? ,
|
||||||
|
which is assumed to be affirmative;
|
||||||
|
do not open the filesystem for writing.
|
||||||
|
.It Fl p
|
||||||
|
Preen filesystems (see above).
|
||||||
|
.It Fl y
|
||||||
|
Assume a yes response to all questions asked by
|
||||||
|
.Nm fsck ;
|
||||||
|
this should be used with great caution as this is a free license
|
||||||
|
to continue after essentially unlimited trouble has been encountered.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
If no filesystems are given to
|
If no filesystems are given to
|
||||||
.Nm
|
.Nm fsck
|
||||||
then a default list of filesystems is read from
|
then a default list of filesystems is read from
|
||||||
the file
|
the file
|
||||||
.Pa /etc/fstab .
|
.Pa /etc/fstab .
|
||||||
@ -259,7 +264,7 @@ File pointing to unallocated inode.
|
|||||||
.It
|
.It
|
||||||
Inode number out of range.
|
Inode number out of range.
|
||||||
.It
|
.It
|
||||||
Holes in directories.
|
Directories with unallocated blocks (holes).
|
||||||
.It
|
.It
|
||||||
Dot or dot-dot not the first two entries of a directory
|
Dot or dot-dot not the first two entries of a directory
|
||||||
or having the wrong inode number.
|
or having the wrong inode number.
|
||||||
@ -296,14 +301,13 @@ contains default list of filesystems to check.
|
|||||||
.El
|
.El
|
||||||
.Sh DIAGNOSTICS
|
.Sh DIAGNOSTICS
|
||||||
The diagnostics produced by
|
The diagnostics produced by
|
||||||
.Nm
|
.Nm fsck
|
||||||
are fully enumerated and explained in Appendix A of
|
are fully enumerated and explained in Appendix A of
|
||||||
.Rs
|
.Rs
|
||||||
.%T "Fsck \- The UNIX File System Check Program"
|
.%T "Fsck \- The UNIX File System Check Program"
|
||||||
.Re
|
.Re
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr fs 5 ,
|
|
||||||
.Xr fstab 5 ,
|
.Xr fstab 5 ,
|
||||||
.Xr fsdb 8 ,
|
.Xr fs 5 ,
|
||||||
.Xr newfs 8 ,
|
.Xr newfs 8 ,
|
||||||
.Xr reboot 8
|
.Xr reboot 8
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: inode.c,v 1.15 1998/06/28 19:23:02 bde Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -62,7 +58,8 @@ ckinode(dp, idesc)
|
|||||||
register struct inodesc *idesc;
|
register struct inodesc *idesc;
|
||||||
{
|
{
|
||||||
ufs_daddr_t *ap;
|
ufs_daddr_t *ap;
|
||||||
long ret, n, ndb, offset;
|
int ret;
|
||||||
|
long n, ndb, offset;
|
||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
quad_t remsize, sizepb;
|
quad_t remsize, sizepb;
|
||||||
mode_t mode;
|
mode_t mode;
|
||||||
@ -74,7 +71,7 @@ ckinode(dp, idesc)
|
|||||||
idesc->id_filesize = dp->di_size;
|
idesc->id_filesize = dp->di_size;
|
||||||
mode = dp->di_mode & IFMT;
|
mode = dp->di_mode & IFMT;
|
||||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
||||||
(dp->di_size < sblock.fs_maxsymlinklen || dp->di_blocks == 0)))
|
dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
dino = *dp;
|
dino = *dp;
|
||||||
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
||||||
@ -239,8 +236,16 @@ chkrange(blk, cnt)
|
|||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
if (blk < 0 || blk >= maxfsblock || cnt < 0 || cnt > maxfsblock - blk)
|
if (cnt <= 0 || blk <= 0 || blk > maxfsblock ||
|
||||||
|
cnt - 1 > maxfsblock - blk)
|
||||||
return (1);
|
return (1);
|
||||||
|
if (cnt > sblock.fs_frag ||
|
||||||
|
fragnum(&sblock, blk) + cnt > sblock.fs_frag) {
|
||||||
|
if (debug)
|
||||||
|
printf("bad size: blk %ld, offset %ld, size %ld\n",
|
||||||
|
blk, fragnum(&sblock, blk), cnt);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
c = dtog(&sblock, blk);
|
c = dtog(&sblock, blk);
|
||||||
if (blk < cgdmin(&sblock, c)) {
|
if (blk < cgdmin(&sblock, c)) {
|
||||||
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
if ((blk + cnt) > cgsblock(&sblock, c)) {
|
||||||
@ -317,20 +322,29 @@ getnextinode(inumber)
|
|||||||
size = inobufsize;
|
size = inobufsize;
|
||||||
lastinum += fullcnt;
|
lastinum += fullcnt;
|
||||||
}
|
}
|
||||||
(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
|
/*
|
||||||
|
* If bread returns an error, it will already have zeroed
|
||||||
|
* out the buffer, so we do not need to do so here.
|
||||||
|
*/
|
||||||
|
(void)bread(fsreadfd, (char *)inodebuf, dblk, size);
|
||||||
dp = inodebuf;
|
dp = inodebuf;
|
||||||
}
|
}
|
||||||
return (dp++);
|
return (dp++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
resetinodebuf()
|
setinodebuf(inum)
|
||||||
|
ino_t inum;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (inum % sblock.fs_ipg != 0)
|
||||||
|
errx(EEXIT, "bad inode number %d to setinodebuf", inum);
|
||||||
startinum = 0;
|
startinum = 0;
|
||||||
nextino = 0;
|
nextino = inum;
|
||||||
lastinum = 0;
|
lastinum = inum;
|
||||||
readcnt = 0;
|
readcnt = 0;
|
||||||
|
if (inodebuf != NULL)
|
||||||
|
return;
|
||||||
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
inobufsize = blkroundup(&sblock, INOBUFSIZE);
|
||||||
fullcnt = inobufsize / sizeof(struct dinode);
|
fullcnt = inobufsize / sizeof(struct dinode);
|
||||||
readpercg = sblock.fs_ipg / fullcnt;
|
readpercg = sblock.fs_ipg / fullcnt;
|
||||||
@ -342,11 +356,8 @@ resetinodebuf()
|
|||||||
partialcnt = fullcnt;
|
partialcnt = fullcnt;
|
||||||
partialsize = inobufsize;
|
partialsize = inobufsize;
|
||||||
}
|
}
|
||||||
if (inodebuf == NULL &&
|
if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
||||||
(inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
|
|
||||||
errx(EEXIT, "cannot allocate space for inode buffer");
|
errx(EEXIT, "cannot allocate space for inode buffer");
|
||||||
while (nextino < ROOTINO)
|
|
||||||
(void)getnextinode(nextino);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -380,14 +391,11 @@ cacheino(dp, inumber)
|
|||||||
inp = (struct inoinfo *)
|
inp = (struct inoinfo *)
|
||||||
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
|
||||||
if (inp == NULL)
|
if (inp == NULL)
|
||||||
return;
|
errx(EEXIT, "cannot increase directory list");
|
||||||
inpp = &inphead[inumber % numdirs];
|
inpp = &inphead[inumber % numdirs];
|
||||||
inp->i_nexthash = *inpp;
|
inp->i_nexthash = *inpp;
|
||||||
*inpp = inp;
|
*inpp = inp;
|
||||||
if (inumber == ROOTINO)
|
inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
|
||||||
inp->i_parent = ROOTINO;
|
|
||||||
else
|
|
||||||
inp->i_parent = (ino_t)0;
|
|
||||||
inp->i_dotdot = (ino_t)0;
|
inp->i_dotdot = (ino_t)0;
|
||||||
inp->i_number = inumber;
|
inp->i_number = inumber;
|
||||||
inp->i_isize = dp->di_size;
|
inp->i_isize = dp->di_size;
|
||||||
@ -465,7 +473,7 @@ clri(idesc, type, flag)
|
|||||||
n_files--;
|
n_files--;
|
||||||
(void)ckinode(dp, idesc);
|
(void)ckinode(dp, idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
statemap[idesc->id_number] = USTATE;
|
inoinfo(idesc->id_number)->ino_state = USTATE;
|
||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,8 +484,10 @@ findname(idesc)
|
|||||||
{
|
{
|
||||||
register struct direct *dirp = idesc->id_dirp;
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
if (dirp->d_ino != idesc->id_parent)
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
|
}
|
||||||
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
||||||
return (STOP|FOUND);
|
return (STOP|FOUND);
|
||||||
}
|
}
|
||||||
@ -498,6 +508,20 @@ findino(idesc)
|
|||||||
return (KEEPON);
|
return (KEEPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
clearentry(idesc)
|
||||||
|
struct inodesc *idesc;
|
||||||
|
{
|
||||||
|
register struct direct *dirp = idesc->id_dirp;
|
||||||
|
|
||||||
|
if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
|
||||||
|
idesc->id_entryno++;
|
||||||
|
return (KEEPON);
|
||||||
|
}
|
||||||
|
dirp->d_ino = 0;
|
||||||
|
return (STOP|FOUND|ALTERED);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pinode(ino)
|
pinode(ino)
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
@ -534,14 +558,14 @@ blkerror(ino, type, blk)
|
|||||||
|
|
||||||
pfatal("%ld %s I=%lu", blk, type, ino);
|
pfatal("%ld %s I=%lu", blk, type, ino);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
switch (statemap[ino]) {
|
switch (inoinfo(ino)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
statemap[ino] = FCLEAR;
|
inoinfo(ino)->ino_state = FCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
statemap[ino] = DCLEAR;
|
inoinfo(ino)->ino_state = DCLEAR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
@ -549,7 +573,7 @@ blkerror(ino, type, blk)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
|
errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,10 +593,10 @@ allocino(request, type)
|
|||||||
|
|
||||||
if (request == 0)
|
if (request == 0)
|
||||||
request = ROOTINO;
|
request = ROOTINO;
|
||||||
else if (statemap[request] != USTATE)
|
else if (inoinfo(request)->ino_state != USTATE)
|
||||||
return (0);
|
return (0);
|
||||||
for (ino = request; ino < maxino; ino++)
|
for (ino = request; ino < maxino; ino++)
|
||||||
if (statemap[ino] == USTATE)
|
if (inoinfo(ino)->ino_state == USTATE)
|
||||||
break;
|
break;
|
||||||
if (ino == maxino)
|
if (ino == maxino)
|
||||||
return (0);
|
return (0);
|
||||||
@ -584,12 +608,12 @@ allocino(request, type)
|
|||||||
cgp->cg_cs.cs_nifree--;
|
cgp->cg_cs.cs_nifree--;
|
||||||
switch (type & IFMT) {
|
switch (type & IFMT) {
|
||||||
case IFDIR:
|
case IFDIR:
|
||||||
statemap[ino] = DSTATE;
|
inoinfo(ino)->ino_state = DSTATE;
|
||||||
cgp->cg_cs.cs_ndir++;
|
cgp->cg_cs.cs_ndir++;
|
||||||
break;
|
break;
|
||||||
case IFREG:
|
case IFREG:
|
||||||
case IFLNK:
|
case IFLNK:
|
||||||
statemap[ino] = FSTATE;
|
inoinfo(ino)->ino_state = FSTATE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (0);
|
return (0);
|
||||||
@ -598,11 +622,11 @@ allocino(request, type)
|
|||||||
dp = ginode(ino);
|
dp = ginode(ino);
|
||||||
dp->di_db[0] = allocblk((long)1);
|
dp->di_db[0] = allocblk((long)1);
|
||||||
if (dp->di_db[0] == 0) {
|
if (dp->di_db[0] == 0) {
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
dp->di_flags = 0;
|
|
||||||
dp->di_mode = type;
|
dp->di_mode = type;
|
||||||
|
dp->di_flags = 0;
|
||||||
dp->di_atime = time(NULL);
|
dp->di_atime = time(NULL);
|
||||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||||
dp->di_size = sblock.fs_fsize;
|
dp->di_size = sblock.fs_fsize;
|
||||||
@ -610,7 +634,7 @@ allocino(request, type)
|
|||||||
n_files++;
|
n_files++;
|
||||||
inodirty();
|
inodirty();
|
||||||
if (newinofmt)
|
if (newinofmt)
|
||||||
typemap[ino] = IFTODT(type);
|
inoinfo(ino)->ino_type = IFTODT(type);
|
||||||
return (ino);
|
return (ino);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,6 +656,6 @@ freeino(ino)
|
|||||||
(void)ckinode(dp, &idesc);
|
(void)ckinode(dp, &idesc);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
statemap[ino] = USTATE;
|
inoinfo(ino)->ino_state = USTATE;
|
||||||
n_files--;
|
n_files--;
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,7 @@ static const char copyright[] =
|
|||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
static const char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
||||||
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
|
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: main.c,v 1.14 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -56,11 +52,10 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
int returntosingle;
|
|
||||||
|
|
||||||
static int argtoi __P((int flag, char *req, char *str, int base));
|
static int argtoi __P((int flag, char *req, char *str, int base));
|
||||||
static int docheck __P((struct fstab *fsp));
|
static int docheck __P((struct fstab *fsp));
|
||||||
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
|
||||||
@ -74,12 +69,8 @@ main(argc, argv)
|
|||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
int ret, maxrun = 0;
|
int ret, maxrun = 0;
|
||||||
struct rlimit rlim;
|
struct rlimit rlimit;
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_DATA, &rlim) == 0) {
|
|
||||||
rlim.rlim_cur = rlim.rlim_max;
|
|
||||||
(void) setrlimit(RLIMIT_DATA, &rlim);
|
|
||||||
}
|
|
||||||
sync();
|
sync();
|
||||||
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@ -137,9 +128,24 @@ main(argc, argv)
|
|||||||
(void)signal(SIGINT, catch);
|
(void)signal(SIGINT, catch);
|
||||||
if (preen)
|
if (preen)
|
||||||
(void)signal(SIGQUIT, catchquit);
|
(void)signal(SIGQUIT, catchquit);
|
||||||
|
/*
|
||||||
|
* Push up our allowed memory limit so we can cope
|
||||||
|
* with huge filesystems.
|
||||||
|
*/
|
||||||
|
if (getrlimit(RLIMIT_DATA, &rlimit) == 0) {
|
||||||
|
rlimit.rlim_cur = rlimit.rlim_max;
|
||||||
|
(void)setrlimit(RLIMIT_DATA, &rlimit);
|
||||||
|
}
|
||||||
if (argc) {
|
if (argc) {
|
||||||
while (argc-- > 0)
|
while (argc-- > 0) {
|
||||||
(void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
|
char *path = blockcheck(*argv);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
pfatal("Can't check %s\n", *argv);
|
||||||
|
else
|
||||||
|
(void)checkfilesys(path, 0, 0L, 0);
|
||||||
|
++argv;
|
||||||
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
||||||
@ -203,16 +209,10 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
case 0:
|
case 0:
|
||||||
if (preen)
|
if (preen)
|
||||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||||
return (0);
|
/* fall through */
|
||||||
case -1:
|
case -1:
|
||||||
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
|
|
||||||
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
|
|
||||||
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
|
|
||||||
sblock.fs_cstotal.cs_nffree, sblock.fs_cstotal.cs_nbfree,
|
|
||||||
sblock.fs_cstotal.cs_nffree * 100.0 / sblock.fs_dsize);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleared if any questions answered no. Used to decide if
|
* Cleared if any questions answered no. Used to decide if
|
||||||
* the superblock should be marked clean.
|
* the superblock should be marked clean.
|
||||||
@ -304,7 +304,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
muldup = (struct dups *)0;
|
muldup = (struct dups *)0;
|
||||||
inocleanup();
|
inocleanup();
|
||||||
if (fsmodified) {
|
if (fsmodified) {
|
||||||
(void)time(&sblock.fs_time);
|
sblock.fs_time = time(NULL);
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (cvtlevel && sblk.b_dirty) {
|
if (cvtlevel && sblk.b_dirty) {
|
||||||
@ -329,12 +329,13 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
resolved = 0;
|
resolved = 0;
|
||||||
}
|
}
|
||||||
ckfini(resolved);
|
ckfini(resolved);
|
||||||
free(blockmap);
|
|
||||||
free(statemap);
|
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
|
||||||
free((char *)lncntp);
|
if (inostathead[cylno].il_stat != NULL)
|
||||||
if (!fsmodified)
|
free((char *)inostathead[cylno].il_stat);
|
||||||
return (0);
|
free((char *)inostathead);
|
||||||
if (!preen)
|
inostathead = NULL;
|
||||||
|
if (fsmodified && !preen)
|
||||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
||||||
if (rerun)
|
if (rerun)
|
||||||
printf("\n***** PLEASE RERUN FSCK *****\n");
|
printf("\n***** PLEASE RERUN FSCK *****\n");
|
||||||
@ -354,6 +355,8 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
|||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
if (!fsmodified)
|
||||||
|
return (0);
|
||||||
if (!preen)
|
if (!preen)
|
||||||
printf("\n***** REBOOT NOW *****\n");
|
printf("\n***** REBOOT NOW *****\n");
|
||||||
sync();
|
sync();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass1.c,v 1.11 1998/06/15 07:07:16 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
@ -52,14 +49,17 @@ static const char rcsid[] =
|
|||||||
|
|
||||||
static ufs_daddr_t badblk;
|
static ufs_daddr_t badblk;
|
||||||
static ufs_daddr_t dupblk;
|
static ufs_daddr_t dupblk;
|
||||||
|
static ino_t lastino; /* last inode in use */
|
||||||
|
|
||||||
static void checkinode __P((ino_t inumber, struct inodesc *));
|
static void checkinode __P((ino_t inumber, struct inodesc *));
|
||||||
|
|
||||||
void
|
void
|
||||||
pass1()
|
pass1()
|
||||||
{
|
{
|
||||||
|
u_int8_t *cp;
|
||||||
ino_t inumber;
|
ino_t inumber;
|
||||||
int c, i, cgd;
|
int c, i, cgd, inosused;
|
||||||
|
struct inostat *info;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,15 +81,84 @@ pass1()
|
|||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass1check;
|
idesc.id_func = pass1check;
|
||||||
inumber = 0;
|
|
||||||
n_files = n_blks = 0;
|
n_files = n_blks = 0;
|
||||||
resetinodebuf();
|
|
||||||
for (c = 0; c < sblock.fs_ncg; c++) {
|
for (c = 0; c < sblock.fs_ncg; c++) {
|
||||||
for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
|
inumber = c * sblock.fs_ipg;
|
||||||
if (inumber < ROOTINO)
|
setinodebuf(inumber);
|
||||||
|
inosused = sblock.fs_ipg;
|
||||||
|
/*
|
||||||
|
* If we are using soft updates, then we can trust the
|
||||||
|
* cylinder group inode allocation maps to tell us which
|
||||||
|
* inodes are allocated. We will scan the used inode map
|
||||||
|
* to find the inodes that are really in use, and then
|
||||||
|
* read only those inodes in from disk.
|
||||||
|
*/
|
||||||
|
if (preen && usedsoftdep) {
|
||||||
|
getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
|
||||||
|
if (!cg_chkmagic(&cgrp))
|
||||||
|
pfatal("CG %d: BAD MAGIC NUMBER\n", c);
|
||||||
|
cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY];
|
||||||
|
for ( ; inosused > 0; inosused -= NBBY, cp--) {
|
||||||
|
if (*cp == 0)
|
||||||
|
continue;
|
||||||
|
for (i = 1 << (NBBY - 1); i > 0; i >>= 1) {
|
||||||
|
if (*cp & i)
|
||||||
|
break;
|
||||||
|
inosused--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Allocate inoinfo structures for the allocated inodes.
|
||||||
|
*/
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
|
/*
|
||||||
|
* Scan the allocated inodes.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < inosused; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO) {
|
||||||
|
(void)getnextinode(inumber);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
checkinode(inumber, &idesc);
|
checkinode(inumber, &idesc);
|
||||||
}
|
}
|
||||||
|
lastino += 1;
|
||||||
|
if (inosused < sblock.fs_ipg || inumber == lastino)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* If we were not able to determine in advance which inodes
|
||||||
|
* were in use, then reduce the size of the inoinfo structure
|
||||||
|
* to the size necessary to describe the inodes that we
|
||||||
|
* really found.
|
||||||
|
*/
|
||||||
|
inosused = lastino - (c * sblock.fs_ipg);
|
||||||
|
if (inosused < 0)
|
||||||
|
inosused = 0;
|
||||||
|
inostathead[c].il_numalloced = inosused;
|
||||||
|
if (inosused == 0) {
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = calloc((unsigned)inosused, sizeof(struct inostat));
|
||||||
|
if (info == NULL)
|
||||||
|
pfatal("cannot alloc %u bytes for inoinfo\n",
|
||||||
|
(unsigned)(sizeof(struct inostat) * inosused));
|
||||||
|
memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
|
||||||
|
free(inostathead[c].il_stat);
|
||||||
|
inostathead[c].il_stat = info;
|
||||||
}
|
}
|
||||||
freeinodebuf();
|
freeinodebuf();
|
||||||
}
|
}
|
||||||
@ -120,7 +189,7 @@ checkinode(inumber, idesc)
|
|||||||
inodirty();
|
inodirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastino = inumber;
|
lastino = inumber;
|
||||||
@ -158,8 +227,7 @@ checkinode(inumber, idesc)
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
symbuf[dp->di_size] = 0;
|
symbuf[dp->di_size] = 0;
|
||||||
printf("convert symlink %lu(%s) of size %ld\n",
|
printf("convert symlink %lu(%s) of size %ld\n",
|
||||||
(u_long)inumber, symbuf,
|
(u_long)inumber, symbuf, (long)dp->di_size);
|
||||||
(long)dp->di_size);
|
|
||||||
}
|
}
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
|
||||||
@ -170,8 +238,7 @@ checkinode(inumber, idesc)
|
|||||||
* Fake ndb value so direct/indirect block checks below
|
* Fake ndb value so direct/indirect block checks below
|
||||||
* will detect any garbage after symlink string.
|
* will detect any garbage after symlink string.
|
||||||
*/
|
*/
|
||||||
if (dp->di_size < sblock.fs_maxsymlinklen ||
|
if (dp->di_size < sblock.fs_maxsymlinklen) {
|
||||||
dp->di_blocks == 0) {
|
|
||||||
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
|
||||||
if (ndb > NDADDR) {
|
if (ndb > NDADDR) {
|
||||||
j = ndb - NDADDR;
|
j = ndb - NDADDR;
|
||||||
@ -200,7 +267,7 @@ checkinode(inumber, idesc)
|
|||||||
if (ftypeok(dp) == 0)
|
if (ftypeok(dp) == 0)
|
||||||
goto unknown;
|
goto unknown;
|
||||||
n_files++;
|
n_files++;
|
||||||
lncntp[inumber] = dp->di_nlink;
|
inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
|
||||||
if (dp->di_nlink <= 0) {
|
if (dp->di_nlink <= 0) {
|
||||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||||
if (zlnp == NULL) {
|
if (zlnp == NULL) {
|
||||||
@ -217,13 +284,14 @@ checkinode(inumber, idesc)
|
|||||||
}
|
}
|
||||||
if (mode == IFDIR) {
|
if (mode == IFDIR) {
|
||||||
if (dp->di_size == 0)
|
if (dp->di_size == 0)
|
||||||
statemap[inumber] = DCLEAR;
|
inoinfo(inumber)->ino_state = DCLEAR;
|
||||||
else
|
else
|
||||||
statemap[inumber] = DSTATE;
|
inoinfo(inumber)->ino_state = DSTATE;
|
||||||
cacheino(dp, inumber);
|
cacheino(dp, inumber);
|
||||||
|
countdirs++;
|
||||||
} else
|
} else
|
||||||
statemap[inumber] = FSTATE;
|
inoinfo(inumber)->ino_state = FSTATE;
|
||||||
typemap[inumber] = IFTODT(mode);
|
inoinfo(inumber)->ino_type = IFTODT(mode);
|
||||||
if (doinglevel2 &&
|
if (doinglevel2 &&
|
||||||
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
@ -251,9 +319,9 @@ checkinode(inumber, idesc)
|
|||||||
return;
|
return;
|
||||||
unknown:
|
unknown:
|
||||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||||
statemap[inumber] = FCLEAR;
|
inoinfo(inumber)->ino_state = FCLEAR;
|
||||||
if (reply("CLEAR") == 1) {
|
if (reply("CLEAR") == 1) {
|
||||||
statemap[inumber] = USTATE;
|
inoinfo(inumber)->ino_state = USTATE;
|
||||||
dp = ginode(inumber);
|
dp = ginode(inumber);
|
||||||
clearinode(dp);
|
clearinode(dp);
|
||||||
inodirty();
|
inodirty();
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -72,7 +69,7 @@ pass1b()
|
|||||||
if (dp == NULL)
|
if (dp == NULL)
|
||||||
continue;
|
continue;
|
||||||
idesc.id_number = inumber;
|
idesc.id_number = inumber;
|
||||||
if (statemap[inumber] != USTATE &&
|
if (inoinfo(inumber)->ino_state != USTATE &&
|
||||||
(ckinode(dp, &idesc) & STOP))
|
(ckinode(dp, &idesc) & STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -64,7 +62,7 @@ pass2()
|
|||||||
struct dinode dino;
|
struct dinode dino;
|
||||||
char pathbuf[MAXPATHLEN + 1];
|
char pathbuf[MAXPATHLEN + 1];
|
||||||
|
|
||||||
switch (statemap[ROOTINO]) {
|
switch (inoinfo(ROOTINO)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
pfatal("ROOT INODE UNALLOCATED");
|
pfatal("ROOT INODE UNALLOCATED");
|
||||||
@ -113,12 +111,13 @@ pass2()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
|
errx(EEXIT, "BAD STATE %d FOR ROOT INODE",
|
||||||
|
inoinfo(ROOTINO)->ino_state);
|
||||||
}
|
}
|
||||||
statemap[ROOTINO] = DFOUND;
|
inoinfo(ROOTINO)->ino_state = DFOUND;
|
||||||
if (newinofmt) {
|
if (newinofmt) {
|
||||||
statemap[WINO] = FSTATE;
|
inoinfo(WINO)->ino_state = FSTATE;
|
||||||
typemap[WINO] = DT_WHT;
|
inoinfo(WINO)->ino_type = DT_WHT;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Sort the directory list into disk block order.
|
* Sort the directory list into disk block order.
|
||||||
@ -181,9 +180,9 @@ pass2()
|
|||||||
inp = *inpp;
|
inp = *inpp;
|
||||||
if (inp->i_parent == 0 || inp->i_isize == 0)
|
if (inp->i_parent == 0 || inp->i_isize == 0)
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_parent] == DFOUND &&
|
if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
|
||||||
statemap[inp->i_number] == DSTATE)
|
inoinfo(inp->i_number)->ino_state == DSTATE)
|
||||||
statemap[inp->i_number] = DFOUND;
|
inoinfo(inp->i_number)->ino_state = DFOUND;
|
||||||
if (inp->i_dotdot == inp->i_parent ||
|
if (inp->i_dotdot == inp->i_parent ||
|
||||||
inp->i_dotdot == (ino_t)-1)
|
inp->i_dotdot == (ino_t)-1)
|
||||||
continue;
|
continue;
|
||||||
@ -193,15 +192,15 @@ pass2()
|
|||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
(void)makeentry(inp->i_number, inp->i_parent, "..");
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fileerror(inp->i_parent, inp->i_number,
|
fileerror(inp->i_parent, inp->i_number,
|
||||||
"BAD INODE NUMBER FOR '..'");
|
"BAD INODE NUMBER FOR '..'");
|
||||||
if (reply("FIX") == 0)
|
if (reply("FIX") == 0)
|
||||||
continue;
|
continue;
|
||||||
lncntp[inp->i_dotdot]++;
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
lncntp[inp->i_parent]--;
|
inoinfo(inp->i_parent)->ino_linkcnt--;
|
||||||
inp->i_dotdot = inp->i_parent;
|
inp->i_dotdot = inp->i_parent;
|
||||||
(void)changeino(inp->i_number, "..", inp->i_parent);
|
(void)changeino(inp->i_number, "..", inp->i_parent);
|
||||||
}
|
}
|
||||||
@ -228,7 +227,7 @@ pass2check(idesc)
|
|||||||
* If converting, set directory entry type.
|
* If converting, set directory entry type.
|
||||||
*/
|
*/
|
||||||
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -284,7 +283,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = entrysize;
|
proto.d_reclen = entrysize;
|
||||||
memmove(dirp, &proto, (size_t)entrysize);
|
memmove(dirp, &proto, (size_t)entrysize);
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
dirp = (struct direct *)((char *)(dirp) + entrysize);
|
||||||
memset(dirp, 0, (size_t)n);
|
memset(dirp, 0, (size_t)n);
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
@ -319,7 +318,7 @@ pass2check(idesc)
|
|||||||
proto.d_reclen = dirp->d_reclen - n;
|
proto.d_reclen = dirp->d_reclen - n;
|
||||||
dirp->d_reclen = n;
|
dirp->d_reclen = n;
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
dirp = (struct direct *)((char *)(dirp) + n);
|
dirp = (struct direct *)((char *)(dirp) + n);
|
||||||
memset(dirp, 0, (size_t)proto.d_reclen);
|
memset(dirp, 0, (size_t)proto.d_reclen);
|
||||||
dirp->d_reclen = proto.d_reclen;
|
dirp->d_reclen = proto.d_reclen;
|
||||||
@ -356,7 +355,7 @@ pass2check(idesc)
|
|||||||
}
|
}
|
||||||
idesc->id_entryno++;
|
idesc->id_entryno++;
|
||||||
if (dirp->d_ino != 0)
|
if (dirp->d_ino != 0)
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
return (ret|KEEPON);
|
return (ret|KEEPON);
|
||||||
chk2:
|
chk2:
|
||||||
if (dirp->d_ino == 0)
|
if (dirp->d_ino == 0)
|
||||||
@ -394,7 +393,7 @@ pass2check(idesc)
|
|||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
} else {
|
} else {
|
||||||
again:
|
again:
|
||||||
switch (statemap[dirp->d_ino]) {
|
switch (inoinfo(dirp->d_ino)->ino_state) {
|
||||||
case USTATE:
|
case USTATE:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
@ -406,7 +405,7 @@ pass2check(idesc)
|
|||||||
case FCLEAR:
|
case FCLEAR:
|
||||||
if (idesc->id_entryno <= 2)
|
if (idesc->id_entryno <= 2)
|
||||||
break;
|
break;
|
||||||
if (statemap[dirp->d_ino] == FCLEAR)
|
if (inoinfo(dirp->d_ino)->ino_state == FCLEAR)
|
||||||
errmsg = "DUP/BAD";
|
errmsg = "DUP/BAD";
|
||||||
else if (!preen && !usedsoftdep)
|
else if (!preen && !usedsoftdep)
|
||||||
errmsg = "ZERO LENGTH DIRECTORY";
|
errmsg = "ZERO LENGTH DIRECTORY";
|
||||||
@ -418,14 +417,14 @@ pass2check(idesc)
|
|||||||
if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
dp = ginode(dirp->d_ino);
|
dp = ginode(dirp->d_ino);
|
||||||
statemap[dirp->d_ino] =
|
inoinfo(dirp->d_ino)->ino_state =
|
||||||
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
(dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
|
||||||
lncntp[dirp->d_ino] = dp->di_nlink;
|
inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink;
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
case DSTATE:
|
case DSTATE:
|
||||||
if (statemap[idesc->id_number] == DFOUND)
|
if (inoinfo(idesc->id_number)->ino_state == DFOUND)
|
||||||
statemap[dirp->d_ino] = DFOUND;
|
inoinfo(dirp->d_ino)->ino_state = DFOUND;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
@ -439,10 +438,10 @@ pass2check(idesc)
|
|||||||
namebuf);
|
namebuf);
|
||||||
if (preen) {
|
if (preen) {
|
||||||
printf(" (REMOVED)\n");
|
printf(" (REMOVED)\n");
|
||||||
n = 1;
|
n = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if ((n = reply("REMOVE")) == 1)
|
if ((n = reply("REMOVE")) == 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (idesc->id_entryno > 2)
|
if (idesc->id_entryno > 2)
|
||||||
@ -450,19 +449,20 @@ pass2check(idesc)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) {
|
if (newinofmt &&
|
||||||
|
dirp->d_type != inoinfo(dirp->d_ino)->ino_type) {
|
||||||
fileerror(idesc->id_number, dirp->d_ino,
|
fileerror(idesc->id_number, dirp->d_ino,
|
||||||
"BAD TYPE VALUE");
|
"BAD TYPE VALUE");
|
||||||
dirp->d_type = typemap[dirp->d_ino];
|
dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
|
||||||
if (reply("FIX") == 1)
|
if (reply("FIX") == 1)
|
||||||
ret |= ALTERED;
|
ret |= ALTERED;
|
||||||
}
|
}
|
||||||
lncntp[dirp->d_ino]--;
|
inoinfo(dirp->d_ino)->ino_linkcnt--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
statemap[dirp->d_ino], dirp->d_ino);
|
inoinfo(dirp->d_ino)->ino_state, dirp->d_ino);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
@ -32,45 +32,84 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ufs/dir.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "fsck.h"
|
#include "fsck.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
pass3()
|
pass3()
|
||||||
{
|
{
|
||||||
register struct inoinfo **inpp, *inp;
|
struct inoinfo *inp;
|
||||||
|
int loopcnt, inpindex, state;
|
||||||
ino_t orphan;
|
ino_t orphan;
|
||||||
int loopcnt;
|
struct inodesc idesc;
|
||||||
|
char namebuf[MAXNAMLEN+1];
|
||||||
|
|
||||||
for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--) {
|
for (inpindex = inplast - 1; inpindex >= 0; inpindex--) {
|
||||||
inp = *inpp;
|
inp = inpsort[inpindex];
|
||||||
|
state = inoinfo(inp->i_number)->ino_state;
|
||||||
if (inp->i_number == ROOTINO ||
|
if (inp->i_number == ROOTINO ||
|
||||||
!(inp->i_parent == 0 || statemap[inp->i_number] == DSTATE))
|
(inp->i_parent != 0 && state != DSTATE))
|
||||||
continue;
|
continue;
|
||||||
if (statemap[inp->i_number] == DCLEAR)
|
if (state == DCLEAR)
|
||||||
continue;
|
continue;
|
||||||
|
/*
|
||||||
|
* If we are running with soft updates and we come
|
||||||
|
* across unreferenced directories, we just leave
|
||||||
|
* them in DSTATE which will cause them to be pitched
|
||||||
|
* in pass 4.
|
||||||
|
*/
|
||||||
|
if (preen && resolved && usedsoftdep && state == DSTATE) {
|
||||||
|
if (inp->i_dotdot >= ROOTINO)
|
||||||
|
inoinfo(inp->i_dotdot)->ino_linkcnt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (loopcnt = 0; ; loopcnt++) {
|
for (loopcnt = 0; ; loopcnt++) {
|
||||||
orphan = inp->i_number;
|
orphan = inp->i_number;
|
||||||
if (inp->i_parent == 0 ||
|
if (inp->i_parent == 0 ||
|
||||||
statemap[inp->i_parent] != DSTATE ||
|
inoinfo(inp->i_parent)->ino_state != DSTATE ||
|
||||||
loopcnt > numdirs)
|
loopcnt > countdirs)
|
||||||
break;
|
break;
|
||||||
inp = getinoinfo(inp->i_parent);
|
inp = getinoinfo(inp->i_parent);
|
||||||
}
|
}
|
||||||
(void)linkup(orphan, inp->i_dotdot);
|
if (loopcnt <= countdirs) {
|
||||||
inp->i_parent = inp->i_dotdot = lfdir;
|
if (linkup(orphan, inp->i_dotdot, NULL)) {
|
||||||
lncntp[lfdir]--;
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
statemap[orphan] = DFOUND;
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
|
propagate();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pfatal("ORPHANED DIRECTORY LOOP DETECTED I=%lu", orphan);
|
||||||
|
if (reply("RECONNECT") == 0)
|
||||||
|
continue;
|
||||||
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
|
idesc.id_type = DATA;
|
||||||
|
idesc.id_number = inp->i_parent;
|
||||||
|
idesc.id_parent = orphan;
|
||||||
|
idesc.id_func = findname;
|
||||||
|
idesc.id_name = namebuf;
|
||||||
|
if ((ckinode(ginode(inp->i_parent), &idesc) & FOUND) == 0)
|
||||||
|
pfatal("COULD NOT FIND NAME IN PARENT DIRECTORY");
|
||||||
|
if (linkup(orphan, inp->i_parent, namebuf)) {
|
||||||
|
idesc.id_func = clearentry;
|
||||||
|
if (ckinode(ginode(inp->i_parent), &idesc) & FOUND)
|
||||||
|
inoinfo(orphan)->ino_linkcnt++;
|
||||||
|
inp->i_parent = inp->i_dotdot = lfdir;
|
||||||
|
inoinfo(lfdir)->ino_linkcnt--;
|
||||||
|
}
|
||||||
|
inoinfo(orphan)->ino_state = DFOUND;
|
||||||
propagate();
|
propagate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -55,22 +53,27 @@ pass4()
|
|||||||
register struct zlncnt *zlnp;
|
register struct zlncnt *zlnp;
|
||||||
struct dinode *dp;
|
struct dinode *dp;
|
||||||
struct inodesc idesc;
|
struct inodesc idesc;
|
||||||
int n;
|
int i, n, cg;
|
||||||
|
|
||||||
memset(&idesc, 0, sizeof(struct inodesc));
|
memset(&idesc, 0, sizeof(struct inodesc));
|
||||||
idesc.id_type = ADDR;
|
idesc.id_type = ADDR;
|
||||||
idesc.id_func = pass4check;
|
idesc.id_func = pass4check;
|
||||||
for (inumber = ROOTINO; inumber <= lastino; inumber++) {
|
for (cg = 0; cg < sblock.fs_ncg; cg++) {
|
||||||
idesc.id_number = inumber;
|
inumber = cg * sblock.fs_ipg;
|
||||||
switch (statemap[inumber]) {
|
for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) {
|
||||||
|
if (inumber < ROOTINO)
|
||||||
|
continue;
|
||||||
|
idesc.id_number = inumber;
|
||||||
|
switch (inoinfo(inumber)->ino_state) {
|
||||||
|
|
||||||
case FSTATE:
|
case FSTATE:
|
||||||
case DFOUND:
|
case DFOUND:
|
||||||
n = lncntp[inumber];
|
n = inoinfo(inumber)->ino_linkcnt;
|
||||||
if (n)
|
if (n) {
|
||||||
adjust(&idesc, (short)n);
|
adjust(&idesc, (short)n);
|
||||||
else {
|
break;
|
||||||
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
|
}
|
||||||
|
for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) {
|
||||||
if (zlnp->zlncnt == inumber) {
|
if (zlnp->zlncnt == inumber) {
|
||||||
zlnp->zlncnt = zlnhead->zlncnt;
|
zlnp->zlncnt = zlnhead->zlncnt;
|
||||||
zlnp = zlnhead;
|
zlnp = zlnhead;
|
||||||
@ -79,30 +82,31 @@ pass4()
|
|||||||
clri(&idesc, "UNREF", 1);
|
clri(&idesc, "UNREF", 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case DSTATE:
|
|
||||||
clri(&idesc, "UNREF", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DCLEAR:
|
|
||||||
dp = ginode(inumber);
|
|
||||||
if (dp->di_size == 0) {
|
|
||||||
clri(&idesc, "ZERO LENGTH", 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DSTATE:
|
||||||
|
clri(&idesc, "UNREF", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DCLEAR:
|
||||||
|
dp = ginode(inumber);
|
||||||
|
if (dp->di_size == 0) {
|
||||||
|
clri(&idesc, "ZERO LENGTH", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case FCLEAR:
|
||||||
|
clri(&idesc, "BAD/DUP", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USTATE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
||||||
|
inoinfo(inumber)->ino_state, inumber);
|
||||||
}
|
}
|
||||||
/* fall through */
|
|
||||||
case FCLEAR:
|
|
||||||
clri(&idesc, "BAD/DUP", 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USTATE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
|
|
||||||
statemap[inumber], inumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: pass5.c,v 1.13 1998/08/04 09:19:03 phk Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
@ -52,7 +49,7 @@ static const char rcsid[] =
|
|||||||
void
|
void
|
||||||
pass5()
|
pass5()
|
||||||
{
|
{
|
||||||
int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
|
int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
|
||||||
int inomapsize, blkmapsize;
|
int inomapsize, blkmapsize;
|
||||||
struct fs *fs = &sblock;
|
struct fs *fs = &sblock;
|
||||||
struct cg *cg = &cgrp;
|
struct cg *cg = &cgrp;
|
||||||
@ -66,7 +63,7 @@ pass5()
|
|||||||
register struct cg *newcg = (struct cg *)buf;
|
register struct cg *newcg = (struct cg *)buf;
|
||||||
struct ocg *ocg = (struct ocg *)buf;
|
struct ocg *ocg = (struct ocg *)buf;
|
||||||
|
|
||||||
statemap[WINO] = USTATE;
|
inoinfo(WINO)->ino_state = USTATE;
|
||||||
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
memset(newcg, 0, (size_t)fs->fs_cgsize);
|
||||||
newcg->cg_niblk = fs->fs_ipg;
|
newcg->cg_niblk = fs->fs_ipg;
|
||||||
if (cvtlevel >= 3) {
|
if (cvtlevel >= 3) {
|
||||||
@ -207,8 +204,8 @@ pass5()
|
|||||||
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
if (fs->fs_postblformat == FS_42POSTBLFMT)
|
||||||
ocg->cg_magic = CG_MAGIC;
|
ocg->cg_magic = CG_MAGIC;
|
||||||
j = fs->fs_ipg * c;
|
j = fs->fs_ipg * c;
|
||||||
for (i = 0; i < fs->fs_ipg; j++, i++) {
|
for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
|
||||||
switch (statemap[j]) {
|
switch (inoinfo(j)->ino_state) {
|
||||||
|
|
||||||
case USTATE:
|
case USTATE:
|
||||||
break;
|
break;
|
||||||
@ -229,7 +226,7 @@ pass5()
|
|||||||
if (j < ROOTINO)
|
if (j < ROOTINO)
|
||||||
break;
|
break;
|
||||||
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
|
||||||
statemap[j], j);
|
inoinfo(j)->ino_state, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
@ -325,7 +322,7 @@ pass5()
|
|||||||
if (cg_inosused(cg)[i] & (1 << k))
|
if (cg_inosused(cg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
pwarn("ALLOCATED INODE %d MARKED FREE\n",
|
||||||
c * fs->fs_ipg + i * 8 + k);
|
c * fs->fs_ipg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < blkmapsize; i++) {
|
for (i = 0; i < blkmapsize; i++) {
|
||||||
@ -338,7 +335,7 @@ pass5()
|
|||||||
if (cg_blksfree(newcg)[i] & (1 << k))
|
if (cg_blksfree(newcg)[i] & (1 << k))
|
||||||
continue;
|
continue;
|
||||||
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
pwarn("ALLOCATED FRAG %d MARKED FREE\n",
|
||||||
c * fs->fs_fpg + i * 8 + k);
|
c * fs->fs_fpg + i * NBBY + k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,24 +352,7 @@ pass5()
|
|||||||
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
&& dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
|
||||||
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
|
||||||
fs->fs_ronly = 0;
|
fs->fs_ronly = 0;
|
||||||
|
fs->fs_fmod = 0;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
}
|
}
|
||||||
if (fs->fs_fmod != 0) {
|
|
||||||
pwarn("MODIFIED FLAG SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_fmod = 0;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fs->fs_clean == 0) {
|
|
||||||
pwarn("CLEAN FLAG NOT SET IN SUPERBLOCK");
|
|
||||||
if (preen)
|
|
||||||
printf(" (FIXED)\n");
|
|
||||||
if (preen || reply("FIX") == 1) {
|
|
||||||
fs->fs_clean = 1;
|
|
||||||
sbdirty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -46,7 +42,7 @@ static const char rcsid[] =
|
|||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <errno.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -93,7 +89,8 @@ checkfstab(preen, maxrun, docheck, chkit)
|
|||||||
sumstatus = 0;
|
sumstatus = 0;
|
||||||
for (passno = 1; passno <= 2; passno++) {
|
for (passno = 1; passno <= 2; passno++) {
|
||||||
if (setfsent() == 0) {
|
if (setfsent() == 0) {
|
||||||
warnx("can't open checklist file: %s", _PATH_FSTAB);
|
fprintf(stderr, "Can't open checklist file: %s\n",
|
||||||
|
_PATH_FSTAB);
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
while ((fsp = getfsent()) != 0) {
|
while ((fsp = getfsent()) != 0) {
|
||||||
@ -222,11 +219,15 @@ finddisk(name)
|
|||||||
dk->name[len] == 0)
|
dk->name[len] == 0)
|
||||||
return (dk);
|
return (dk);
|
||||||
}
|
}
|
||||||
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL)
|
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
dk = *dkp;
|
dk = *dkp;
|
||||||
if ((dk->name = malloc(len + 1)) == NULL)
|
if ((dk->name = malloc(len + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strncpy(dk->name, name, len);
|
(void)strncpy(dk->name, name, len);
|
||||||
dk->name[len] = '\0';
|
dk->name[len] = '\0';
|
||||||
dk->part = NULL;
|
dk->part = NULL;
|
||||||
@ -249,14 +250,20 @@ addpart(name, fsname, auxdata)
|
|||||||
printf("%s in fstab more than once!\n", name);
|
printf("%s in fstab more than once!\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL)
|
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
pt = *ppt;
|
pt = *ppt;
|
||||||
if ((pt->name = malloc(strlen(name) + 1)) == NULL)
|
if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->name, name);
|
(void)strcpy(pt->name, name);
|
||||||
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL)
|
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->fsname, fsname);
|
(void)strcpy(pt->fsname, fsname);
|
||||||
pt->next = NULL;
|
pt->next = NULL;
|
||||||
pt->auxdata = auxdata;
|
pt->auxdata = auxdata;
|
||||||
@ -271,7 +278,7 @@ startdisk(dk, checkit)
|
|||||||
|
|
||||||
dk->pid = fork();
|
dk->pid = fork();
|
||||||
if (dk->pid < 0) {
|
if (dk->pid < 0) {
|
||||||
warn("fork");
|
perror("fork");
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
if (dk->pid == 0)
|
if (dk->pid == 0)
|
||||||
@ -287,19 +294,17 @@ blockcheck(origname)
|
|||||||
struct stat stslash, stblock, stchar;
|
struct stat stslash, stblock, stchar;
|
||||||
char *newname, *raw;
|
char *newname, *raw;
|
||||||
struct fstab *fsinfo;
|
struct fstab *fsinfo;
|
||||||
int retried = 0, l;
|
int retried = 0, len;
|
||||||
|
|
||||||
hotroot = 0;
|
hotroot = 0;
|
||||||
if (stat("/", &stslash) < 0) {
|
if (stat("/", &stslash) < 0) {
|
||||||
warn("/");
|
printf("Can't stat /: %s\n", strerror(errno));
|
||||||
printf("Can't stat root\n");
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
newname = origname;
|
newname = origname;
|
||||||
retry:
|
retry:
|
||||||
if (stat(newname, &stblock) < 0) {
|
if (stat(newname, &stblock) < 0) {
|
||||||
warn("%s", newname);
|
printf("Can't stat %s: %s\n", newname, strerror(errno));
|
||||||
printf("Can't stat %s\n", newname);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
||||||
@ -307,8 +312,7 @@ blockcheck(origname)
|
|||||||
hotroot++;
|
hotroot++;
|
||||||
raw = rawname(newname);
|
raw = rawname(newname);
|
||||||
if (stat(raw, &stchar) < 0) {
|
if (stat(raw, &stchar) < 0) {
|
||||||
warn("%s", raw);
|
printf("Can't stat %s: %s\n", raw, strerror(errno));
|
||||||
printf("Can't stat %s\n", raw);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
||||||
@ -318,15 +322,15 @@ blockcheck(origname)
|
|||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
||||||
newname = unrawname(origname);
|
newname = unrawname(newname);
|
||||||
retried++;
|
retried++;
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
||||||
l = strlen(origname) - 1;
|
len = strlen(origname) - 1;
|
||||||
if (l > 0 && origname[l] == '/')
|
if (len > 0 && origname[len] == '/')
|
||||||
/* remove trailing slash */
|
/* remove trailing slash */
|
||||||
origname[l] = '\0';
|
origname[len] = '\0';
|
||||||
if(!(fsinfo=getfsfile(origname))) {
|
if ((fsinfo = getfsfile(origname)) == NULL) {
|
||||||
printf("Can't resolve %s to character special device",
|
printf("Can't resolve %s to character special device",
|
||||||
origname);
|
origname);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -32,16 +32,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id: setup.c,v 1.11 1998/06/15 07:07:21 charnier Exp $";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#define DKTYPENAMES
|
#define DKTYPENAMES
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/disklabel.h>
|
#include <sys/disklabel.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
@ -82,7 +79,7 @@ setup(dev)
|
|||||||
|
|
||||||
havesb = 0;
|
havesb = 0;
|
||||||
fswritefd = -1;
|
fswritefd = -1;
|
||||||
skipclean = preen;
|
skipclean = fflag ? 0 : preen;
|
||||||
if (stat(dev, &statb) < 0) {
|
if (stat(dev, &statb) < 0) {
|
||||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||||
return (0);
|
return (0);
|
||||||
@ -114,8 +111,7 @@ setup(dev)
|
|||||||
asblk.b_un.b_buf = malloc(SBSIZE);
|
asblk.b_un.b_buf = malloc(SBSIZE);
|
||||||
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
|
||||||
errx(EEXIT, "cannot allocate space for superblock");
|
errx(EEXIT, "cannot allocate space for superblock");
|
||||||
lp = getdisklabel((char *)NULL, fsreadfd);
|
if ((lp = getdisklabel(NULL, fsreadfd)))
|
||||||
if (lp)
|
|
||||||
dev_bsize = secsize = lp->d_secsize;
|
dev_bsize = secsize = lp->d_secsize;
|
||||||
else
|
else
|
||||||
dev_bsize = secsize = DEV_BSIZE;
|
dev_bsize = secsize = DEV_BSIZE;
|
||||||
@ -147,6 +143,10 @@ setup(dev)
|
|||||||
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
|
||||||
bflag = 0;
|
bflag = 0;
|
||||||
}
|
}
|
||||||
|
if (skipclean && sblock.fs_clean) {
|
||||||
|
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
maxfsblock = sblock.fs_size;
|
maxfsblock = sblock.fs_size;
|
||||||
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
maxino = sblock.fs_ncg * sblock.fs_ipg;
|
||||||
/*
|
/*
|
||||||
@ -264,12 +264,6 @@ setup(dev)
|
|||||||
asked++;
|
asked++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* If we survive the above basic checks and are preening,
|
|
||||||
* quit here unless forced.
|
|
||||||
*/
|
|
||||||
if (skipclean && sblock.fs_clean && !fflag)
|
|
||||||
return (-1);
|
|
||||||
/*
|
/*
|
||||||
* allocate and initialize the necessary maps
|
* allocate and initialize the necessary maps
|
||||||
*/
|
*/
|
||||||
@ -280,22 +274,11 @@ setup(dev)
|
|||||||
(unsigned)bmapsize);
|
(unsigned)bmapsize);
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
statemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
inostathead = calloc((unsigned)(sblock.fs_ncg),
|
||||||
if (statemap == NULL) {
|
sizeof(struct inostatlist));
|
||||||
printf("cannot alloc %u bytes for statemap\n",
|
if (inostathead == NULL) {
|
||||||
(unsigned)(maxino + 1));
|
printf("cannot alloc %u bytes for inostathead\n",
|
||||||
goto badsb;
|
(unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
|
||||||
}
|
|
||||||
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
|
||||||
if (typemap == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for typemap\n",
|
|
||||||
(unsigned)(maxino + 1));
|
|
||||||
goto badsb;
|
|
||||||
}
|
|
||||||
lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
|
|
||||||
if (lncntp == NULL) {
|
|
||||||
printf("cannot alloc %u bytes for lncntp\n",
|
|
||||||
(unsigned)(maxino + 1) * sizeof(short));
|
|
||||||
goto badsb;
|
goto badsb;
|
||||||
}
|
}
|
||||||
numdirs = sblock.fs_cstotal.cs_ndir;
|
numdirs = sblock.fs_cstotal.cs_ndir;
|
||||||
@ -474,9 +457,11 @@ calcsb(dev, devfd, fs)
|
|||||||
fstypenames[pp->p_fstype] : "unknown");
|
fstypenames[pp->p_fstype] : "unknown");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (pp->p_fsize == 0 || pp->p_frag == 0) {
|
if (pp->p_fsize == 0 || pp->p_frag == 0 ||
|
||||||
pfatal("%s: LABELED AS A %s FILE SYSTEM, BUT BLOCK SIZE IS 0\n",
|
pp->p_cpg == 0 || pp->p_size == 0) {
|
||||||
dev, fstypenames[pp->p_fstype]);
|
pfatal("%s: %s: type %s fsize %d, frag %d, cpg %d, size %d\n",
|
||||||
|
dev, "INCOMPLETE LABEL", fstypenames[pp->p_fstype],
|
||||||
|
pp->p_fsize, pp->p_frag, pp->p_cpg, pp->p_size);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
memset(fs, 0, sizeof(struct fs));
|
memset(fs, 0, sizeof(struct fs));
|
||||||
|
@ -32,20 +32,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
#include <ufs/ufs/dir.h>
|
#include <ufs/ufs/dir.h>
|
||||||
#include <ufs/ffs/fs.h>
|
#include <ufs/ffs/fs.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -115,6 +111,26 @@ reply(question)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up state information for an inode.
|
||||||
|
*/
|
||||||
|
struct inostat *
|
||||||
|
inoinfo(inum)
|
||||||
|
ino_t inum;
|
||||||
|
{
|
||||||
|
static struct inostat unallocated = { USTATE, 0, 0 };
|
||||||
|
struct inostatlist *ilp;
|
||||||
|
int iloff;
|
||||||
|
|
||||||
|
if (inum > maxino)
|
||||||
|
errx(EEXIT, "inoinfo: inumber %d out of range", inum);
|
||||||
|
ilp = &inostathead[inum / sblock.fs_ipg];
|
||||||
|
iloff = inum % sblock.fs_ipg;
|
||||||
|
if (iloff >= ilp->il_numalloced)
|
||||||
|
return (&unallocated);
|
||||||
|
return (&ilp->il_stat[iloff]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Malloc buffers and set up cache.
|
* Malloc buffers and set up cache.
|
||||||
*/
|
*/
|
||||||
@ -270,16 +286,23 @@ ckfini(markclean)
|
|||||||
free((char *)bp);
|
free((char *)bp);
|
||||||
}
|
}
|
||||||
if (bufhead.b_size != cnt)
|
if (bufhead.b_size != cnt)
|
||||||
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
|
errx(EEXIT, "Panic: lost %d buffers", bufhead.b_size - cnt);
|
||||||
pbp = pdirbp = (struct bufarea *)0;
|
pbp = pdirbp = (struct bufarea *)0;
|
||||||
if (markclean && sblock.fs_clean == 0) {
|
if (sblock.fs_clean != markclean) {
|
||||||
sblock.fs_clean = 1;
|
sblock.fs_clean = markclean;
|
||||||
sbdirty();
|
sbdirty();
|
||||||
ofsmodified = fsmodified;
|
ofsmodified = fsmodified;
|
||||||
flush(fswritefd, &sblk);
|
flush(fswritefd, &sblk);
|
||||||
fsmodified = ofsmodified;
|
fsmodified = ofsmodified;
|
||||||
if (!preen)
|
if (!preen) {
|
||||||
printf("\n***** FILE SYSTEM MARKED CLEAN *****\n");
|
printf("\n***** FILE SYSTEM MARKED %s *****\n",
|
||||||
|
markclean ? "CLEAN" : "DIRTY");
|
||||||
|
if (!markclean)
|
||||||
|
rerun = 1;
|
||||||
|
}
|
||||||
|
} else if (!preen && !markclean) {
|
||||||
|
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
|
||||||
|
rerun = 1;
|
||||||
}
|
}
|
||||||
if (debug)
|
if (debug)
|
||||||
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
|
||||||
@ -324,6 +347,8 @@ bread(fd, buf, blk, size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (errs)
|
||||||
|
resolved = 0;
|
||||||
return (errs);
|
return (errs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +373,7 @@ bwrite(fd, buf, blk, size)
|
|||||||
fsmodified = 1;
|
fsmodified = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
resolved = 0;
|
||||||
rwerror("WRITE", blk);
|
rwerror("WRITE", blk);
|
||||||
if (lseek(fd, offset, 0) < 0)
|
if (lseek(fd, offset, 0) < 0)
|
||||||
rwerror("SEEK", blk);
|
rwerror("SEEK", blk);
|
||||||
@ -438,7 +464,8 @@ getpathname(namebuf, curdir, ino)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (busy ||
|
if (busy ||
|
||||||
(statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) {
|
(inoinfo(curdir)->ino_state != DSTATE &&
|
||||||
|
inoinfo(curdir)->ino_state != DFOUND)) {
|
||||||
(void)strcpy(namebuf, "?");
|
(void)strcpy(namebuf, "?");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -497,6 +524,7 @@ void
|
|||||||
catchquit(sig)
|
catchquit(sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("returning to single-user after filesystem check\n");
|
printf("returning to single-user after filesystem check\n");
|
||||||
returntosingle = 1;
|
returntosingle = 1;
|
||||||
(void)signal(SIGQUIT, SIG_DFL);
|
(void)signal(SIGQUIT, SIG_DFL);
|
||||||
@ -589,14 +617,16 @@ pfatal(fmt, va_alist)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (usedsoftdep)
|
if (usedsoftdep)
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\nUNEXPECTED SOFTDEP INCONSISTENCY\n");
|
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cdevname == NULL)
|
||||||
|
cdevname = "fsck";
|
||||||
(void)fprintf(stderr, "%s: ", cdevname);
|
(void)fprintf(stderr, "%s: ", cdevname);
|
||||||
(void)vfprintf(stderr, fmt, ap);
|
(void)vfprintf(stderr, fmt, ap);
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||||
cdevname, usedsoftdep ? " SOFTDEP " : " ");
|
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
|
||||||
ckfini(0);
|
ckfini(0);
|
||||||
exit(EEXIT);
|
exit(EEXIT);
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
#if 0
|
|
||||||
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
|
||||||
#endif
|
|
||||||
static const char rcsid[] =
|
|
||||||
"$Id$";
|
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -46,7 +42,7 @@ static const char rcsid[] =
|
|||||||
#include <ufs/ufs/dinode.h>
|
#include <ufs/ufs/dinode.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <errno.h>
|
||||||
#include <fstab.h>
|
#include <fstab.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -93,7 +89,8 @@ checkfstab(preen, maxrun, docheck, chkit)
|
|||||||
sumstatus = 0;
|
sumstatus = 0;
|
||||||
for (passno = 1; passno <= 2; passno++) {
|
for (passno = 1; passno <= 2; passno++) {
|
||||||
if (setfsent() == 0) {
|
if (setfsent() == 0) {
|
||||||
warnx("can't open checklist file: %s", _PATH_FSTAB);
|
fprintf(stderr, "Can't open checklist file: %s\n",
|
||||||
|
_PATH_FSTAB);
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
while ((fsp = getfsent()) != 0) {
|
while ((fsp = getfsent()) != 0) {
|
||||||
@ -222,11 +219,15 @@ finddisk(name)
|
|||||||
dk->name[len] == 0)
|
dk->name[len] == 0)
|
||||||
return (dk);
|
return (dk);
|
||||||
}
|
}
|
||||||
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL)
|
if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
dk = *dkp;
|
dk = *dkp;
|
||||||
if ((dk->name = malloc(len + 1)) == NULL)
|
if ((dk->name = malloc(len + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strncpy(dk->name, name, len);
|
(void)strncpy(dk->name, name, len);
|
||||||
dk->name[len] = '\0';
|
dk->name[len] = '\0';
|
||||||
dk->part = NULL;
|
dk->part = NULL;
|
||||||
@ -249,14 +250,20 @@ addpart(name, fsname, auxdata)
|
|||||||
printf("%s in fstab more than once!\n", name);
|
printf("%s in fstab more than once!\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL)
|
if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
pt = *ppt;
|
pt = *ppt;
|
||||||
if ((pt->name = malloc(strlen(name) + 1)) == NULL)
|
if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->name, name);
|
(void)strcpy(pt->name, name);
|
||||||
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL)
|
if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
|
||||||
errx(8, "out of memory");
|
fprintf(stderr, "out of memory");
|
||||||
|
exit (8);
|
||||||
|
}
|
||||||
(void)strcpy(pt->fsname, fsname);
|
(void)strcpy(pt->fsname, fsname);
|
||||||
pt->next = NULL;
|
pt->next = NULL;
|
||||||
pt->auxdata = auxdata;
|
pt->auxdata = auxdata;
|
||||||
@ -271,7 +278,7 @@ startdisk(dk, checkit)
|
|||||||
|
|
||||||
dk->pid = fork();
|
dk->pid = fork();
|
||||||
if (dk->pid < 0) {
|
if (dk->pid < 0) {
|
||||||
warn("fork");
|
perror("fork");
|
||||||
return (8);
|
return (8);
|
||||||
}
|
}
|
||||||
if (dk->pid == 0)
|
if (dk->pid == 0)
|
||||||
@ -287,19 +294,17 @@ blockcheck(origname)
|
|||||||
struct stat stslash, stblock, stchar;
|
struct stat stslash, stblock, stchar;
|
||||||
char *newname, *raw;
|
char *newname, *raw;
|
||||||
struct fstab *fsinfo;
|
struct fstab *fsinfo;
|
||||||
int retried = 0, l;
|
int retried = 0, len;
|
||||||
|
|
||||||
hotroot = 0;
|
hotroot = 0;
|
||||||
if (stat("/", &stslash) < 0) {
|
if (stat("/", &stslash) < 0) {
|
||||||
warn("/");
|
printf("Can't stat /: %s\n", strerror(errno));
|
||||||
printf("Can't stat root\n");
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
newname = origname;
|
newname = origname;
|
||||||
retry:
|
retry:
|
||||||
if (stat(newname, &stblock) < 0) {
|
if (stat(newname, &stblock) < 0) {
|
||||||
warn("%s", newname);
|
printf("Can't stat %s: %s\n", newname, strerror(errno));
|
||||||
printf("Can't stat %s\n", newname);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
|
||||||
@ -307,8 +312,7 @@ blockcheck(origname)
|
|||||||
hotroot++;
|
hotroot++;
|
||||||
raw = rawname(newname);
|
raw = rawname(newname);
|
||||||
if (stat(raw, &stchar) < 0) {
|
if (stat(raw, &stchar) < 0) {
|
||||||
warn("%s", raw);
|
printf("Can't stat %s: %s\n", raw, strerror(errno));
|
||||||
printf("Can't stat %s\n", raw);
|
|
||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
|
||||||
@ -318,15 +322,15 @@ blockcheck(origname)
|
|||||||
return (origname);
|
return (origname);
|
||||||
}
|
}
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
|
||||||
newname = unrawname(origname);
|
newname = unrawname(newname);
|
||||||
retried++;
|
retried++;
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
} else if ((stblock.st_mode & S_IFMT) == S_IFDIR && !retried) {
|
||||||
l = strlen(origname) - 1;
|
len = strlen(origname) - 1;
|
||||||
if (l > 0 && origname[l] == '/')
|
if (len > 0 && origname[len] == '/')
|
||||||
/* remove trailing slash */
|
/* remove trailing slash */
|
||||||
origname[l] = '\0';
|
origname[len] = '\0';
|
||||||
if(!(fsinfo=getfsfile(origname))) {
|
if ((fsinfo = getfsfile(origname)) == NULL) {
|
||||||
printf("Can't resolve %s to character special device",
|
printf("Can't resolve %s to character special device",
|
||||||
origname);
|
origname);
|
||||||
return (0);
|
return (0);
|
||||||
|
Loading…
Reference in New Issue
Block a user