summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fsck/Makefile9
-rw-r--r--sbin/fsck/SMM.doc/0.t150
-rw-r--r--sbin/fsck/SMM.doc/1.t83
-rw-r--r--sbin/fsck/SMM.doc/2.t265
-rw-r--r--sbin/fsck/SMM.doc/3.t452
-rw-r--r--sbin/fsck/SMM.doc/4.t1424
-rw-r--r--sbin/fsck/SMM.doc/Makefile7
-rw-r--r--sbin/fsck/dir.c779
-rw-r--r--sbin/fsck/fsck.8321
-rw-r--r--sbin/fsck/fsck.c540
-rw-r--r--sbin/fsck/fsck.h305
-rw-r--r--sbin/fsck/fsutil.c363
-rw-r--r--sbin/fsck/fsutil.h62
-rw-r--r--sbin/fsck/inode.c672
-rw-r--r--sbin/fsck/main.c417
-rw-r--r--sbin/fsck/pass1.c431
-rw-r--r--sbin/fsck/pass1b.c107
-rw-r--r--sbin/fsck/pass2.c486
-rw-r--r--sbin/fsck/pass3.c118
-rw-r--r--sbin/fsck/pass4.c145
-rw-r--r--sbin/fsck/pass5.c427
-rw-r--r--sbin/fsck/pathnames.h35
-rw-r--r--sbin/fsck/preen.c332
-rw-r--r--sbin/fsck/setup.c520
-rw-r--r--sbin/fsck/utilities.c683
-rw-r--r--sbin/fsdb/Makefile6
-rw-r--r--sbin/quotacheck/Makefile5
27 files changed, 1010 insertions, 8134 deletions
diff --git a/sbin/fsck/Makefile b/sbin/fsck/Makefile
index 3155b1a..025f7bb 100644
--- a/sbin/fsck/Makefile
+++ b/sbin/fsck/Makefile
@@ -1,10 +1,9 @@
-# @(#)Makefile 8.2 (Berkeley) 4/27/95
+# $FreeBSD$
+# $NetBSD: Makefile,v 1.14 1996/09/27 22:38:37 christos Exp $
PROG= fsck
+SRCS= fsck.c fsutil.c preen.c
MAN8= fsck.8
-SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
- pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
-CFLAGS+=-W
-.PATH: ${.CURDIR}/../../sys/ufs/ffs
+CFLAGS=
.include <bsd.prog.mk>
diff --git a/sbin/fsck/SMM.doc/0.t b/sbin/fsck/SMM.doc/0.t
deleted file mode 100644
index 528dd96..0000000
--- a/sbin/fsck/SMM.doc/0.t
+++ /dev/null
@@ -1,150 +0,0 @@
-.\" Copyright (c) 1986, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)0.t 8.1 (Berkeley) 6/8/93
-.\"
-.if n .ND
-.TL
-Fsck \- The UNIX\(dg File System Check Program
-.EH 'SMM:3-%''The \s-2UNIX\s+2 File System Check Program'
-.OH 'The \s-2UNIX\s+2 File System Check Program''SMM:3-%'
-.AU
-Marshall Kirk McKusick
-.AI
-Computer Systems Research Group
-Computer Science Division
-Department of Electrical Engineering and Computer Science
-University of California, Berkeley
-Berkeley, CA 94720
-.AU
-T. J. Kowalski
-.AI
-Bell Laboratories
-Murray Hill, New Jersey 07974
-.AB
-.FS
-\(dgUNIX is a trademark of Bell Laboratories.
-.FE
-.FS
-This work was done under grants from
-the National Science Foundation under grant MCS80-05144,
-and the Defense Advance Research Projects Agency (DoD) under
-Arpa Order No. 4031 monitored by Naval Electronic System Command under
-Contract No. N00039-82-C-0235.
-.FE
-This document reflects the use of
-.I fsck
-with the 4.2BSD and 4.3BSD file system organization. This
-is a revision of the
-original paper written by
-T. J. Kowalski.
-.PP
-File System Check Program (\fIfsck\fR)
-is an interactive file system check and repair program.
-.I Fsck
-uses the redundant structural information in the
-UNIX file system to perform several consistency checks.
-If an inconsistency is detected, it is reported
-to the operator, who may elect to fix or ignore
-each inconsistency.
-These inconsistencies result from the permanent interruption
-of the file system updates, which are performed every
-time a file is modified.
-Unless there has been a hardware failure,
-.I fsck
-is able to repair corrupted file systems
-using procedures based upon the order in which UNIX honors
-these file system update requests.
-.PP
-The purpose of this document is to describe the normal updating
-of the file system,
-to discuss the possible causes of file system corruption,
-and to present the corrective actions implemented
-by
-.I fsck.
-Both the program and the interaction between the
-program and the operator are described.
-.sp 2
-.LP
-Revised October 7, 1996
-.AE
-.LP
-.bp
-.ce
-.B "TABLE OF CONTENTS"
-.LP
-.sp 1
-.nf
-.B "1. Introduction"
-.LP
-.sp .5v
-.nf
-.B "2. Overview of the file system
-2.1. Superblock
-2.2. Summary Information
-2.3. Cylinder groups
-2.4. Fragments
-2.5. Updates to the file system
-.LP
-.sp .5v
-.nf
-.B "3. Fixing corrupted file systems
-3.1. Detecting and correcting corruption
-3.2. Super block checking
-3.3. Free block checking
-3.4. Checking the inode state
-3.5. Inode links
-3.6. Inode data size
-3.7. Checking the data associated with an inode
-3.8. File system connectivity
-.LP
-.sp .5v
-.nf
-.B Acknowledgements
-.LP
-.sp .5v
-.nf
-.B References
-.LP
-.sp .5v
-.nf
-.B "4. Appendix A
-4.1. Conventions
-4.2. Initialization
-4.3. Phase 1 - Check Blocks and Sizes
-4.4. Phase 1b - Rescan for more Dups
-4.5. Phase 2 - Check Pathnames
-4.6. Phase 3 - Check Connectivity
-4.7. Phase 4 - Check Reference Counts
-4.8. Phase 5 - Check Cyl groups
-4.9. Cleanup
-.ds RH Introduction
-.bp
diff --git a/sbin/fsck/SMM.doc/1.t b/sbin/fsck/SMM.doc/1.t
deleted file mode 100644
index 4d2f535..0000000
--- a/sbin/fsck/SMM.doc/1.t
+++ /dev/null
@@ -1,83 +0,0 @@
-.\" Copyright (c) 1982, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)1.t 8.1 (Berkeley) 6/5/93
-.\"
-.ds RH Introduction
-.NH
-Introduction
-.PP
-This document reflects the use of
-.I fsck
-with the 4.2BSD and 4.3BSD file system organization. This
-is a revision of the
-original paper written by
-T. J. Kowalski.
-.PP
-When a UNIX
-operating system is brought up, a consistency
-check of the file systems should always be performed.
-This precautionary measure helps to insure
-a reliable environment for file storage on disk.
-If an inconsistency is discovered,
-corrective action must be taken.
-.I Fsck
-runs in two modes.
-Normally it is run non-interactively by the system after
-a normal boot.
-When running in this mode,
-it will only make changes to the file system that are known
-to always be correct.
-If an unexpected inconsistency is found
-.I fsck
-will exit with a non-zero exit status,
-leaving the system running single-user.
-Typically the operator then runs
-.I fsck
-interactively.
-When running in this mode,
-each problem is listed followed by a suggested corrective action.
-The operator must decide whether or not the suggested correction
-should be made.
-.PP
-The purpose of this memo is to dispel the
-mystique surrounding
-file system inconsistencies.
-It first describes the updating of the file system
-(the calm before the storm) and
-then describes file system corruption (the storm).
-Finally,
-the set of deterministic corrective actions
-used by
-.I fsck
-(the Coast Guard
-to the rescue) is presented.
-.ds RH Overview of the File System
diff --git a/sbin/fsck/SMM.doc/2.t b/sbin/fsck/SMM.doc/2.t
deleted file mode 100644
index 7d00cea..0000000
--- a/sbin/fsck/SMM.doc/2.t
+++ /dev/null
@@ -1,265 +0,0 @@
-.\" Copyright (c) 1982, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)2.t 8.1 (Berkeley) 6/5/93
-.\"
-.ds RH Overview of the file system
-.NH
-Overview of the file system
-.PP
-The file system is discussed in detail in [Mckusick84];
-this section gives a brief overview.
-.NH 2
-Superblock
-.PP
-A file system is described by its
-.I "super-block" .
-The super-block is built when the file system is created (\c
-.I newfs (8))
-and never changes.
-The super-block
-contains the basic parameters of the file system,
-such as the number of data blocks it contains
-and a count of the maximum number of files.
-Because the super-block contains critical data,
-.I newfs
-replicates it to protect against catastrophic loss.
-The
-.I "default super block"
-always resides at a fixed offset from the beginning
-of the file system's disk partition.
-The
-.I "redundant super blocks"
-are not referenced unless a head crash
-or other hard disk error causes the default super-block
-to be unusable.
-The redundant blocks are sprinkled throughout the disk partition.
-.PP
-Within the file system are files.
-Certain files are distinguished as directories and contain collections
-of pointers to files that may themselves be directories.
-Every file has a descriptor associated with it called an
-.I "inode".
-The inode contains information describing ownership of the file,
-time stamps indicating modification and access times for the file,
-and an array of indices pointing to the data blocks for the file.
-In this section,
-we assume that the first 12 blocks
-of the file are directly referenced by values stored
-in the inode structure itself\(dg.
-.FS
-\(dgThe actual number may vary from system to system, but is usually in
-the range 5-13.
-.FE
-The inode structure may also contain references to indirect blocks
-containing further data block indices.
-In a file system with a 4096 byte block size, a singly indirect
-block contains 1024 further block addresses,
-a doubly indirect block contains 1024 addresses of further single indirect
-blocks,
-and a triply indirect block contains 1024 addresses of further doubly indirect
-blocks (the triple indirect block is never needed in practice).
-.PP
-In order to create files with up to
-2\(ua32 bytes,
-using only two levels of indirection,
-the minimum size of a file system block is 4096 bytes.
-The size of file system blocks can be any power of two
-greater than or equal to 4096.
-The block size of the file system is maintained in the super-block,
-so it is possible for file systems of different block sizes
-to be accessible simultaneously on the same system.
-The block size must be decided when
-.I newfs
-creates the file system;
-the block size cannot be subsequently
-changed without rebuilding the file system.
-.NH 2
-Summary information
-.PP
-Associated with the super block is non replicated
-.I "summary information" .
-The summary information changes
-as the file system is modified.
-The summary information contains
-the number of blocks, fragments, inodes and directories in the file system.
-.NH 2
-Cylinder groups
-.PP
-The file system partitions the disk into one or more areas called
-.I "cylinder groups".
-A cylinder group is comprised of one or more consecutive
-cylinders on a disk.
-Each cylinder group includes inode slots for files, a
-.I "block map"
-describing available blocks in the cylinder group,
-and summary information describing the usage of data blocks
-within the cylinder group.
-A fixed number of inodes is allocated for each cylinder group
-when the file system is created.
-The current policy is to allocate one inode for each 2048
-bytes of disk space;
-this is expected to be far more inodes than will ever be needed.
-.PP
-All the cylinder group bookkeeping information could be
-placed at the beginning of each cylinder group.
-However if this approach were used,
-all the redundant information would be on the top platter.
-A single hardware failure that destroyed the top platter
-could cause the loss of all copies of the redundant super-blocks.
-Thus the cylinder group bookkeeping information
-begins at a floating offset from the beginning of the cylinder group.
-The offset for
-the
-.I "i+1" st
-cylinder group is about one track further
-from the beginning of the cylinder group
-than it was for the
-.I "i" th
-cylinder group.
-In this way,
-the redundant
-information spirals down into the pack;
-any single track, cylinder,
-or platter can be lost without losing all copies of the super-blocks.
-Except for the first cylinder group,
-the space between the beginning of the cylinder group
-and the beginning of the cylinder group information stores data.
-.NH 2
-Fragments
-.PP
-To avoid waste in storing small files,
-the file system space allocator divides a single
-file system block into one or more
-.I "fragments".
-The fragmentation of the file system is specified
-when the file system is created;
-each file system block can be optionally broken into
-2, 4, or 8 addressable fragments.
-The lower bound on the size of these fragments is constrained
-by the disk sector size;
-typically 512 bytes is the lower bound on fragment size.
-The block map associated with each cylinder group
-records the space availability at the fragment level.
-Aligned fragments are examined
-to determine block availability.
-.PP
-On a file system with a block size of 4096 bytes
-and a fragment size of 1024 bytes,
-a file is represented by zero or more 4096 byte blocks of data,
-and possibly a single fragmented block.
-If a file system block must be fragmented to obtain
-space for a small amount of data,
-the remainder of the block is made available for allocation
-to other files.
-For example,
-consider an 11000 byte file stored on
-a 4096/1024 byte file system.
-This file uses two full size blocks and a 3072 byte fragment.
-If no fragments with at least 3072 bytes
-are available when the file is created,
-a full size block is split yielding the necessary 3072 byte
-fragment and an unused 1024 byte fragment.
-This remaining fragment can be allocated to another file, as needed.
-.NH 2
-Updates to the file system
-.PP
-Every working day hundreds of files
-are created, modified, and removed.
-Every time a file is modified,
-the operating system performs a
-series of file system updates.
-These updates, when written on disk, yield a consistent file system.
-The file system stages
-all modifications of critical information;
-modification can
-either be completed or cleanly backed out after a crash.
-Knowing the information that is first written to the file system,
-deterministic procedures can be developed to
-repair a corrupted file system.
-To understand this process,
-the order that the update
-requests were being honored must first be understood.
-.PP
-When a user program does an operation to change the file system,
-such as a
-.I write ,
-the data to be written is copied into an internal
-.I "in-core"
-buffer in the kernel.
-Normally, the disk update is handled asynchronously;
-the user process is allowed to proceed even though
-the data has not yet been written to the disk.
-The data,
-along with the inode information reflecting the change,
-is eventually written out to disk.
-The real disk write may not happen until long after the
-.I write
-system call has returned.
-Thus at any given time, the file system,
-as it resides on the disk,
-lags the state of the file system represented by the in-core information.
-.PP
-The disk information is updated to reflect the in-core information
-when the buffer is required for another use,
-when a
-.I sync (2)
-is done (at 30 second intervals) by
-.I "/etc/update" "(8),"
-or by manual operator intervention with the
-.I sync (8)
-command.
-If the system is halted without writing out the in-core information,
-the file system on the disk will be in an inconsistent state.
-.PP
-If all updates are done asynchronously, several serious
-inconsistencies can arise.
-One inconsistency is that a block may be claimed by two inodes.
-Such an inconsistency can occur when the system is halted before
-the pointer to the block in the old inode has been cleared
-in the copy of the old inode on the disk,
-and after the pointer to the block in the new inode has been written out
-to the copy of the new inode on the disk.
-Here,
-there is no deterministic method for deciding
-which inode should really claim the block.
-A similar problem can arise with a multiply claimed inode.
-.PP
-The problem with asynchronous inode updates
-can be avoided by doing all inode deallocations synchronously.
-Consequently,
-inodes and indirect blocks are written to the disk synchronously
-(\fIi.e.\fP the process blocks until the information is
-really written to disk)
-when they are being deallocated.
-Similarly inodes are kept consistent by synchronously
-deleting, adding, or changing directory entries.
-.ds RH Fixing corrupted file systems
diff --git a/sbin/fsck/SMM.doc/3.t b/sbin/fsck/SMM.doc/3.t
deleted file mode 100644
index bb6f05b..0000000
--- a/sbin/fsck/SMM.doc/3.t
+++ /dev/null
@@ -1,452 +0,0 @@
-.\" Copyright (c) 1982, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)3.t 8.1 (Berkeley) 6/5/93
-.\"
-.ds RH Fixing corrupted file systems
-.NH
-Fixing corrupted file systems
-.PP
-A file system
-can become corrupted in several ways.
-The most common of these ways are
-improper shutdown procedures
-and hardware failures.
-.PP
-File systems may become corrupted during an
-.I "unclean halt" .
-This happens when proper shutdown
-procedures are not observed,
-physically write-protecting a mounted file system,
-or a mounted file system is taken off-line.
-The most common operator procedural failure is forgetting to
-.I sync
-the system before halting the CPU.
-.PP
-File systems may become further corrupted if proper startup
-procedures are not observed, e.g.,
-not checking a file system for inconsistencies,
-and not repairing inconsistencies.
-Allowing a corrupted file system to be used (and, thus, to be modified
-further) can be disastrous.
-.PP
-Any piece of hardware can fail at any time.
-Failures
-can be as subtle as a bad block
-on a disk pack, or as blatant as a non-functional disk-controller.
-.NH 2
-Detecting and correcting corruption
-.PP
-Normally
-.I fsck
-is run non-interactively.
-In this mode it will only fix
-corruptions that are expected to occur from an unclean halt.
-These actions are a proper subset of the actions that
-.I fsck
-will take when it is running interactively.
-Throughout this paper we assume that
-.I fsck
-is being run interactively,
-and all possible errors can be encountered.
-When an inconsistency is discovered in this mode,
-.I fsck
-reports the inconsistency for the operator to
-chose a corrective action.
-.PP
-A quiescent\(dd
-.FS
-\(dd I.e., unmounted and not being written on.
-.FE
-file system may be checked for structural integrity
-by performing consistency checks on the
-redundant data intrinsic to a file system.
-The redundant data is either read from
-the file system,
-or computed from other known values.
-The file system
-.B must
-be in a quiescent state when
-.I fsck
-is run,
-since
-.I fsck
-is a multi-pass program.
-.PP
-In the following sections,
-we discuss methods to discover inconsistencies
-and possible corrective actions
-for the cylinder group blocks, the inodes, the indirect blocks, and
-the data blocks containing directory entries.
-.NH 2
-Super-block checking
-.PP
-The most commonly corrupted item in a file system
-is the summary information
-associated with the super-block.
-The summary information is prone to corruption
-because it is modified with every change to the file
-system's blocks or inodes,
-and is usually corrupted
-after an unclean halt.
-.PP
-The super-block is checked for inconsistencies
-involving file-system size, number of inodes,
-free-block count, and the free-inode count.
-The file-system size must be larger than the
-number of blocks used by the super-block
-and the number of blocks used by the list of inodes.
-The file-system size and layout information
-are the most critical pieces of information for
-.I fsck .
-While there is no way to actually check these sizes,
-since they are statically determined by
-.I newfs ,
-.I fsck
-can check that these sizes are within reasonable bounds.
-All other file system checks require that these sizes be correct.
-If
-.I fsck
-detects corruption in the static parameters of the default super-block,
-.I fsck
-requests the operator to specify the location of an alternate super-block.
-.NH 2
-Free block checking
-.PP
-.I Fsck
-checks that all the blocks
-marked as free in the cylinder group block maps
-are not claimed by any files.
-When all the blocks have been initially accounted for,
-.I fsck
-checks that
-the number of free blocks
-plus the number of blocks claimed by the inodes
-equals the total number of blocks in the file system.
-.PP
-If anything is wrong with the block allocation maps,
-.I fsck
-will rebuild them,
-based on the list it has computed of allocated blocks.
-.PP
-The summary information associated with the super-block
-counts the total number of free blocks within the file system.
-.I Fsck
-compares this count to the
-number of free blocks it found within the file system.
-If the two counts do not agree, then
-.I fsck
-replaces the incorrect count in the summary information
-by the actual free-block count.
-.PP
-The summary information
-counts the total number of free inodes within the file system.
-.I Fsck
-compares this count to the number
-of free inodes it found within the file system.
-If the two counts do not agree, then
-.I fsck
-replaces the incorrect count in the
-summary information by the actual free-inode count.
-.NH 2
-Checking the inode state
-.PP
-An individual inode is not as likely to be corrupted as
-the allocation information.
-However, because of the great number of active inodes,
-a few of the inodes are usually corrupted.
-.PP
-The list of inodes in the file system
-is checked sequentially starting with inode 2
-(inode 0 marks unused inodes;
-inode 1 is saved for future generations)
-and progressing through the last inode in the file system.
-The state of each inode is checked for
-inconsistencies involving format and type,
-link count,
-duplicate blocks,
-bad blocks,
-and inode size.
-.PP
-Each inode contains a mode word.
-This mode word describes the type and state of the inode.
-Inodes must be one of six types:
-regular inode, directory inode, symbolic link inode,
-special block inode, special character inode, or socket inode.
-Inodes may be found in one of three allocation states:
-unallocated, allocated, and neither unallocated nor allocated.
-This last state suggests an incorrectly formated inode.
-An inode can get in this state if
-bad data is written into the inode list.
-The only possible corrective action is for
-.I fsck
-is to clear the inode.
-.NH 2
-Inode links
-.PP
-Each inode counts the
-total number of directory entries
-linked to the inode.
-.I Fsck
-verifies the link count of each inode
-by starting at the root of the file system,
-and descending through the directory structure.
-The actual link count for each inode
-is calculated during the descent.
-.PP
-If the stored link count is non-zero and the actual
-link count is zero,
-then no directory entry appears for the inode.
-If this happens,
-.I fsck
-will place the disconnected file in the
-.I lost+found
-directory.
-If the stored and actual link counts are non-zero and unequal,
-a directory entry may have been added or removed without the inode being
-updated.
-If this happens,
-.I fsck
-replaces the incorrect stored link count by the actual link count.
-.PP
-Each inode contains a list,
-or pointers to
-lists (indirect blocks),
-of all the blocks claimed by the inode.
-Since indirect blocks are owned by an inode,
-inconsistencies in indirect blocks directly
-affect the inode that owns it.
-.PP
-.I Fsck
-compares each block number claimed by an inode
-against a list of already allocated blocks.
-If another inode already claims a block number,
-then the block number is added to a list of
-.I "duplicate blocks" .
-Otherwise, the list of allocated blocks
-is updated to include the block number.
-.PP
-If there are any duplicate blocks,
-.I fsck
-will perform a partial second
-pass over the inode list
-to find the inode of the duplicated block.
-The second pass is needed,
-since without examining the files associated with
-these inodes for correct content,
-not enough information is available
-to determine which inode is corrupted and should be cleared.
-If this condition does arise
-(only hardware failure will cause it),
-then the inode with the earliest
-modify time is usually incorrect,
-and should be cleared.
-If this happens,
-.I fsck
-prompts the operator to clear both inodes.
-The operator must decide which one should be kept
-and which one should be cleared.
-.PP
-.I Fsck
-checks the range of each block number claimed by an inode.
-If the block number is
-lower than the first data block in the file system,
-or greater than the last data block,
-then the block number is a
-.I "bad block number" .
-Many bad blocks in an inode are usually caused by
-an indirect block that was not written to the file system,
-a condition which can only occur if there has been a hardware failure.
-If an inode contains bad block numbers,
-.I fsck
-prompts the operator to clear it.
-.NH 2
-Inode data size
-.PP
-Each inode contains a count of the number of data blocks
-that it contains.
-The number of actual data blocks
-is the sum of the allocated data blocks
-and the indirect blocks.
-.I Fsck
-computes the actual number of data blocks
-and compares that block count against
-the actual number of blocks the inode claims.
-If an inode contains an incorrect count
-.I fsck
-prompts the operator to fix it.
-.PP
-Each inode contains a thirty-two bit size field.
-The size is the number of data bytes
-in the file associated with the inode.
-The consistency of the byte size field is roughly checked
-by computing from the size field the maximum number of blocks
-that should be associated with the inode,
-and comparing that expected block count against
-the actual number of blocks the inode claims.
-.NH 2
-Checking the data associated with an inode
-.PP
-An inode can directly or indirectly
-reference three kinds of data blocks.
-All referenced blocks must be the same kind.
-The three types of data blocks are:
-plain data blocks, symbolic link data blocks, and directory data blocks.
-Plain data blocks
-contain the information stored in a file;
-symbolic link data blocks
-contain the path name stored in a link.
-Directory data blocks contain directory entries.
-.I Fsck
-can only check the validity of directory data blocks.
-.PP
-Each directory data block is checked for
-several types of inconsistencies.
-These inconsistencies include
-directory inode numbers pointing to unallocated inodes,
-directory inode numbers that are greater than
-the number of inodes in the file system,
-incorrect directory inode numbers for ``\fB.\fP'' and ``\fB..\fP'',
-and directories that are not attached to the file system.
-If the inode number in a directory data block
-references an unallocated inode,
-then
-.I fsck
-will remove that directory entry.
-Again,
-this condition can only arise when there has been a hardware failure.
-.PP
-.I Fsck
-also checks for directories with unallocated blocks (holes).
-Such directories should never be created.
-When found,
-.I fsck
-will prompt the user to adjust the length of the offending directory
-which is done by shortening the size of the directory to the end of the
-last allocated block preceeding the hole.
-Unfortunately, this means that another Phase 1 run has to be done.
-.I Fsck
-will remind the user to rerun fsck after repairing a
-directory containing an unallocated block.
-.PP
-If a directory entry inode number references
-outside the inode list, then
-.I fsck
-will remove that directory entry.
-This condition occurs if bad data is written into a directory data block.
-.PP
-The directory inode number entry for ``\fB.\fP''
-must be the first entry in the directory data block.
-The inode number for ``\fB.\fP''
-must reference itself;
-e.g., it must equal the inode number
-for the directory data block.
-The directory inode number entry
-for ``\fB..\fP'' must be
-the second entry in the directory data block.
-Its value must equal the inode number for the
-parent of the directory entry
-(or the inode number of the directory
-data block if the directory is the
-root directory).
-If the directory inode numbers are
-incorrect,
-.I fsck
-will replace them with the correct values.
-If there are multiple hard links to a directory,
-the first one encountered is considered the real parent
-to which ``\fB..\fP'' should point;
-\fIfsck\fP recommends deletion for the subsequently discovered names.
-.NH 2
-File system connectivity
-.PP
-.I Fsck
-checks the general connectivity of the file system.
-If directories are not linked into the file system, then
-.I fsck
-links the directory back into the file system in the
-.I lost+found
-directory.
-This condition only occurs when there has been a hardware failure.
-.ds RH "References"
-.SH
-\s+2Acknowledgements\s0
-.PP
-I thank Bill Joy, Sam Leffler, Robert Elz and Dennis Ritchie
-for their suggestions and help in implementing the new file system.
-Thanks also to Robert Henry for his editorial input to
-get this document together.
-Finally we thank our sponsors,
-the National Science Foundation under grant MCS80-05144,
-and the Defense Advance Research Projects Agency (DoD) under
-Arpa Order No. 4031 monitored by Naval Electronic System Command under
-Contract No. N00039-82-C-0235. (Kirk McKusick, July 1983)
-.PP
-I would like to thank Larry A. Wehr for advice that lead
-to the first version of
-.I fsck
-and Rick B. Brandt for adapting
-.I fsck
-to
-UNIX/TS. (T. Kowalski, July 1979)
-.sp 2
-.SH
-\s+2References\s0
-.LP
-.IP [Dolotta78] 20
-Dolotta, T. A., and Olsson, S. B. eds.,
-.I "UNIX User's Manual, Edition 1.1\^" ,
-January 1978.
-.IP [Joy83] 20
-Joy, W., Cooper, E., Fabry, R., Leffler, S., McKusick, M., and Mosher, D.
-4.2BSD System Manual,
-.I "University of California at Berkeley" ,
-.I "Computer Systems Research Group Technical Report"
-#4, 1982.
-.IP [McKusick84] 20
-McKusick, M., Joy, W., Leffler, S., and Fabry, R.
-A Fast File System for UNIX,
-\fIACM Transactions on Computer Systems 2\fP, 3.
-pp. 181-197, August 1984.
-.IP [Ritchie78] 20
-Ritchie, D. M., and Thompson, K.,
-The UNIX Time-Sharing System,
-.I "The Bell System Technical Journal"
-.B 57 ,
-6 (July-August 1978, Part 2), pp. 1905-29.
-.IP [Thompson78] 20
-Thompson, K.,
-UNIX Implementation,
-.I "The Bell System Technical Journal\^"
-.B 57 ,
-6 (July-August 1978, Part 2), pp. 1931-46.
-.ds RH Appendix A \- Fsck Error Conditions
-.bp
diff --git a/sbin/fsck/SMM.doc/4.t b/sbin/fsck/SMM.doc/4.t
deleted file mode 100644
index 5ea8179..0000000
--- a/sbin/fsck/SMM.doc/4.t
+++ /dev/null
@@ -1,1424 +0,0 @@
-.\" Copyright (c) 1982, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)4.t 8.1 (Berkeley) 6/5/93
-.\"
-.ds RH Appendix A \- Fsck Error Conditions
-.NH
-Appendix A \- Fsck Error Conditions
-.NH 2
-Conventions
-.PP
-.I Fsck
-is
-a multi-pass file system check program.
-Each file system pass invokes a different Phase of the
-.I fsck
-program.
-After the initial setup,
-.I fsck
-performs successive Phases over each file system,
-checking blocks and sizes,
-path-names,
-connectivity,
-reference counts,
-and the map of free blocks,
-(possibly rebuilding it),
-and performs some cleanup.
-.LP
-Normally
-.I fsck
-is run non-interactively to
-.I preen
-the file systems after an unclean halt.
-While preen'ing a file system,
-it will only fix corruptions that are expected
-to occur from an unclean halt.
-These actions are a proper subset of the actions that
-.I fsck
-will take when it is running interactively.
-Throughout this appendix many errors have several options
-that the operator can take.
-When an inconsistency is detected,
-.I fsck
-reports the error condition to the operator.
-If a response is required,
-.I fsck
-prints a prompt message and
-waits for a response.
-When preen'ing most errors are fatal.
-For those that are expected,
-the response taken is noted.
-This appendix explains the meaning of each error condition,
-the possible responses, and the related error conditions.
-.LP
-The error conditions are organized by the
-.I Phase
-of the
-.I fsck
-program in which they can occur.
-The error conditions that may occur
-in more than one Phase
-will be discussed in initialization.
-.NH 2
-Initialization
-.PP
-Before a file system check can be performed, certain
-tables have to be set up and certain files opened.
-This section concerns itself with the opening of files and
-the initialization of tables.
-This section lists error conditions resulting from
-command line options,
-memory requests,
-opening of files,
-status of files,
-file system size checks,
-and creation of the scratch file.
-All the initialization errors are fatal
-when the file system is being preen'ed.
-.sp
-.LP
-.B "\fIC\fP option?"
-.br
-\fIC\fP is not a legal option to
-.I fsck ;
-legal options are \-b, \-c, \-y, \-n, and \-p.
-.I Fsck
-terminates on this error condition.
-See the
-.I fsck (8)
-manual entry for further detail.
-.sp
-.LP
-.B "cannot alloc NNN bytes for blockmap"
-.br
-.B "cannot alloc NNN bytes for freemap"
-.br
-.B "cannot alloc NNN bytes for statemap"
-.br
-.B "cannot alloc NNN bytes for lncntp"
-.br
-.I Fsck 's
-request for memory for its virtual
-memory tables failed.
-This should never happen.
-.I Fsck
-terminates on this error condition.
-See a guru.
-.sp
-.LP
-.B "Can't open checklist file: \fIF\fP"
-.br
-The file system checklist file
-\fIF\fP (usually
-.I /etc/fstab )
-can not be opened for reading.
-.I Fsck
-terminates on this error condition.
-Check access modes of \fIF\fP.
-.sp
-.LP
-.B "Can't stat root"
-.br
-.I Fsck 's
-request for statistics about the root directory ``/'' failed.
-This should never happen.
-.I Fsck
-terminates on this error condition.
-See a guru.
-.sp
-.LP
-.B "Can't stat \fIF\fP"
-.br
-.B "Can't make sense out of name \fIF\fP"
-.br
-.I Fsck 's
-request for statistics about the file system \fIF\fP failed.
-When running manually,
-it ignores this file system
-and continues checking the next file system given.
-Check access modes of \fIF\fP.
-.sp
-.LP
-.B "Can't open \fIF\fP"
-.br
-.I Fsck 's
-request attempt to open the file system \fIF\fP failed.
-When running manually, it ignores this file system
-and continues checking the next file system given.
-Check access modes of \fIF\fP.
-.sp
-.LP
-.B "\fIF\fP: (NO WRITE)"
-.br
-Either the \-n flag was specified or
-.I fsck 's
-attempt to open the file system \fIF\fP for writing failed.
-When running manually,
-all the diagnostics are printed out,
-but no modifications are attempted to fix them.
-.sp
-.LP
-.B "file is not a block or character device; OK"
-.br
-You have given
-.I fsck
-a regular file name by mistake.
-Check the type of the file specified.
-.LP
-Possible responses to the OK prompt are:
-.IP YES
-ignore this error condition.
-.IP NO
-ignore this file system and continues checking
-the next file system given.
-.sp
-.LP
-.B "UNDEFINED OPTIMIZATION IN SUPERBLOCK (SET TO DEFAULT)"
-.br
-The superblock optimization parameter is neither OPT_TIME
-nor OPT_SPACE.
-.LP
-Possible responses to the SET TO DEFAULT prompt are:
-.IP YES
-The superblock is set to request optimization to minimize
-running time of the system.
-(If optimization to minimize disk space utilization is
-desired, it can be set using \fItunefs\fP(8).)
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "IMPOSSIBLE MINFREE=\fID\fP IN SUPERBLOCK (SET TO DEFAULT)"
-.br
-The superblock minimum space percentage is greater than 99%
-or less then 0%.
-.LP
-Possible responses to the SET TO DEFAULT prompt are:
-.IP YES
-The minfree parameter is set to 10%.
-(If some other percentage is desired,
-it can be set using \fItunefs\fP(8).)
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "IMPOSSIBLE INTERLEAVE=\fID\fP IN SUPERBLOCK (SET TO DEFAULT)"
-.br
-The file system interleave is less than or equal to zero.
-.LP
-Possible responses to the SET TO DEFAULT prompt are:
-.IP YES
-The interleave parameter is set to 1.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "IMPOSSIBLE NPSECT=\fID\fP IN SUPERBLOCK (SET TO DEFAULT)"
-.br
-The number of physical sectors per track is less than the number
-of usable sectors per track.
-.LP
-Possible responses to the SET TO DEFAULT prompt are:
-.IP YES
-The npsect parameter is set to the number of usable sectors per track.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-One of the following messages will appear:
-.br
-.B "MAGIC NUMBER WRONG"
-.br
-.B "NCG OUT OF RANGE"
-.br
-.B "CPG OUT OF RANGE"
-.br
-.B "NCYL DOES NOT JIVE WITH NCG*CPG"
-.br
-.B "SIZE PREPOSTEROUSLY LARGE"
-.br
-.B "TRASHED VALUES IN SUPER BLOCK"
-.br
-and will be followed by the message:
-.br
-.B "\fIF\fP: BAD SUPER BLOCK: \fIB\fP"
-.br
-.B "USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE"
-.br
-.B "SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8)."
-.br
-The super block has been corrupted.
-An alternative super block must be selected from among those
-listed by
-.I newfs
-(8) when the file system was created.
-For file systems with a blocksize less than 32K,
-specifying \-b 32 is a good first choice.
-.sp
-.LP
-.B "INTERNAL INCONSISTENCY: \fIM\fP"
-.br
-.I Fsck 's
-has had an internal panic, whose message is specified as \fIM\fP.
-This should never happen.
-See a guru.
-.sp
-.LP
-.B "CAN NOT SEEK: BLK \fIB\fP (CONTINUE)"
-.br
-.I Fsck 's
-request for moving to a specified block number \fIB\fP in
-the file system failed.
-This should never happen.
-See a guru.
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-attempt to continue to run the file system check.
-Often,
-however the problem will persist.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-If the block was part of the virtual memory buffer
-cache,
-.I fsck
-will terminate with the message ``Fatal I/O error''.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "CAN NOT READ: BLK \fIB\fP (CONTINUE)"
-.br
-.I Fsck 's
-request for reading a specified block number \fIB\fP in
-the file system failed.
-This should never happen.
-See a guru.
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-attempt to continue to run the file system check.
-It will retry the read and print out the message:
-.br
-.B "THE FOLLOWING SECTORS COULD NOT BE READ: \fIN\fP"
-.br
-where \fIN\fP indicates the sectors that could not be read.
-If
-.I fsck
-ever tries to write back one of the blocks on which the read failed
-it will print the message:
-.br
-.B "WRITING ZERO'ED BLOCK \fIN\fP TO DISK"
-.br
-where \fIN\fP indicates the sector that was written with zero's.
-If the disk is experiencing hardware problems, the problem will persist.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-If the block was part of the virtual memory buffer
-cache,
-.I fsck
-will terminate with the message ``Fatal I/O error''.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "CAN NOT WRITE: BLK \fIB\fP (CONTINUE)"
-.br
-.I Fsck 's
-request for writing a specified block number \fIB\fP
-in the file system failed.
-The disk is write-protected;
-check the write protect lock on the drive.
-If that is not the problem, see a guru.
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-attempt to continue to run the file system check.
-The write operation will be retried with the failed blocks
-indicated by the message:
-.br
-.B "THE FOLLOWING SECTORS COULD NOT BE WRITTEN: \fIN\fP"
-.br
-where \fIN\fP indicates the sectors that could not be written.
-If the disk is experiencing hardware problems, the problem will persist.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-If the block was part of the virtual memory buffer
-cache,
-.I fsck
-will terminate with the message ``Fatal I/O error''.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "bad inode number DDD to ginode"
-.br
-An internal error has attempted to read non-existent inode \fIDDD\fP.
-This error causes
-.I fsck
-to exit.
-See a guru.
-.NH 2
-Phase 1 \- Check Blocks and Sizes
-.PP
-This phase concerns itself with
-the inode list.
-This section lists error conditions resulting from
-checking inode types,
-setting up the zero-link-count table,
-examining inode block numbers for bad or duplicate blocks,
-checking inode size,
-and checking inode format.
-All errors in this phase except
-.B "INCORRECT BLOCK COUNT"
-and
-.B "PARTIALLY TRUNCATED INODE"
-are fatal if the file system is being preen'ed.
-.sp
-.LP
-.B "UNKNOWN FILE TYPE I=\fII\fP (CLEAR)"
-.br
-The mode word of the inode \fII\fP indicates that the inode is not a
-special block inode, special character inode, socket inode, regular inode,
-symbolic link, or directory inode.
-.LP
-Possible responses to the CLEAR prompt are:
-.IP YES
-de-allocate inode \fII\fP by zeroing its contents.
-This will always invoke the UNALLOCATED error condition in Phase 2
-for each directory entry pointing to this inode.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "PARTIALLY TRUNCATED INODE I=\fII\fP (SALVAGE)"
-.br
-.I Fsck
-has found inode \fII\fP whose size is shorter than the number of
-blocks allocated to it.
-This condition should only occur if the system crashes while in the
-midst of truncating a file.
-When preen'ing the file system,
-.I fsck
-completes the truncation to the specified size.
-.LP
-Possible responses to SALVAGE are:
-.IP YES
-complete the truncation to the size specified in the inode.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "LINK COUNT TABLE OVERFLOW (CONTINUE)"
-.br
-An internal table for
-.I fsck
-containing allocated inodes with a link count of
-zero cannot allocate more memory.
-Increase the virtual memory for
-.I fsck .
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-continue with the program.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-If another allocated inode with a zero link count is found,
-this error condition is repeated.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "\fIB\fP BAD I=\fII\fP"
-.br
-Inode \fII\fP contains block number \fIB\fP with a number
-lower than the number of the first data block in the file system or
-greater than the number of the last block
-in the file system.
-This error condition may invoke the
-.B "EXCESSIVE BAD BLKS"
-error condition in Phase 1 (see next paragraph) if
-inode \fII\fP has too many block numbers outside the file system range.
-This error condition will always invoke the
-.B "BAD/DUP"
-error condition in Phase 2 and Phase 4.
-.sp
-.LP
-.B "EXCESSIVE BAD BLKS I=\fII\fP (CONTINUE)"
-.br
-There is more than a tolerable number (usually 10) of blocks with a number
-lower than the number of the first data block in the file system or greater than
-the number of last block in the file system associated with inode \fII\fP.
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-ignore the rest of the blocks in this inode
-and continue checking with the next inode in the file system.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "BAD STATE DDD TO BLKERR"
-.br
-An internal error has scrambled
-.I fsck 's
-state map to have the impossible value \fIDDD\fP.
-.I Fsck
-exits immediately.
-See a guru.
-.sp
-.LP
-.B "\fIB\fP DUP I=\fII\fP"
-.br
-Inode \fII\fP contains block number \fIB\fP that is already claimed by
-another inode.
-This error condition may invoke the
-.B "EXCESSIVE DUP BLKS"
-error condition in Phase 1 if
-inode \fII\fP has too many block numbers claimed by other inodes.
-This error condition will always invoke Phase 1b and the
-.B "BAD/DUP"
-error condition in Phase 2 and Phase 4.
-.sp
-.LP
-.B "EXCESSIVE DUP BLKS I=\fII\fP (CONTINUE)"
-.br
-There is more than a tolerable number (usually 10) of blocks claimed by other
-inodes.
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-ignore the rest of the blocks in this inode
-and continue checking with the next inode in the file system.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "DUP TABLE OVERFLOW (CONTINUE)"
-.br
-An internal table in
-.I fsck
-containing duplicate block numbers cannot allocate any more space.
-Increase the amount of virtual memory available to
-.I fsck .
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-continue with the program.
-This error condition will not allow a complete check of the file system.
-A second run of
-.I fsck
-should be made to re-check this file system.
-If another duplicate block is found, this error condition will repeat.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "PARTIALLY ALLOCATED INODE I=\fII\fP (CLEAR)"
-.br
-Inode \fII\fP is neither allocated nor unallocated.
-.LP
-Possible responses to the CLEAR prompt are:
-.IP YES
-de-allocate inode \fII\fP by zeroing its contents.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "INCORRECT BLOCK COUNT I=\fII\fP (\fIX\fP should be \fIY\fP) (CORRECT)"
-.br
-The block count for inode \fII\fP is \fIX\fP blocks,
-but should be \fIY\fP blocks.
-When preen'ing the count is corrected.
-.LP
-Possible responses to the CORRECT prompt are:
-.IP YES
-replace the block count of inode \fII\fP with \fIY\fP.
-.IP NO
-ignore this error condition.
-.NH 2
-Phase 1B: Rescan for More Dups
-.PP
-When a duplicate block is found in the file system, the file system is
-rescanned to find the inode that previously claimed that block.
-This section lists the error condition when the duplicate block is found.
-.sp
-.LP
-.B "\fIB\fP DUP I=\fII\fP"
-.br
-Inode \fII\fP contains block number \fIB\fP that
-is already claimed by another inode.
-This error condition will always invoke the
-.B "BAD/DUP"
-error condition in Phase 2.
-You can determine which inodes have overlapping blocks by examining
-this error condition and the DUP error condition in Phase 1.
-.NH 2
-Phase 2 \- Check Pathnames
-.PP
-This phase concerns itself with removing directory entries
-pointing to
-error conditioned inodes
-from Phase 1 and Phase 1b.
-This section lists error conditions resulting from
-root inode mode and status,
-directory inode pointers in range,
-and directory entries pointing to bad inodes,
-and directory integrity checks.
-All errors in this phase are fatal if the file system is being preen'ed,
-except for directories not being a multiple of the blocks size
-and extraneous hard links.
-.sp
-.LP
-.B "ROOT INODE UNALLOCATED (ALLOCATE)"
-.br
-The root inode (usually inode number 2) has no allocate mode bits.
-This should never happen.
-.LP
-Possible responses to the ALLOCATE prompt are:
-.IP YES
-allocate inode 2 as the root inode.
-The files and directories usually found in the root will be recovered
-in Phase 3 and put into
-.I lost+found .
-If the attempt to allocate the root fails,
-.I fsck
-will exit with the message:
-.br
-.B "CANNOT ALLOCATE ROOT INODE" .
-.IP NO
-.I fsck
-will exit.
-.sp
-.LP
-.B "ROOT INODE NOT DIRECTORY (REALLOCATE)"
-.br
-The root inode (usually inode number 2)
-is not directory inode type.
-.LP
-Possible responses to the REALLOCATE prompt are:
-.IP YES
-clear the existing contents of the root inode
-and reallocate it.
-The files and directories usually found in the root will be recovered
-in Phase 3 and put into
-.I lost+found .
-If the attempt to allocate the root fails,
-.I fsck
-will exit with the message:
-.br
-.B "CANNOT ALLOCATE ROOT INODE" .
-.IP NO
-.I fsck
-will then prompt with
-.B "FIX"
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-replace the root inode's type to be a directory.
-If the root inode's data blocks are not directory blocks,
-many error conditions will be produced.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "DUPS/BAD IN ROOT INODE (REALLOCATE)"
-.br
-Phase 1 or Phase 1b have found duplicate blocks
-or bad blocks in the root inode (usually inode number 2) for the file system.
-.LP
-Possible responses to the REALLOCATE prompt are:
-.IP YES
-clear the existing contents of the root inode
-and reallocate it.
-The files and directories usually found in the root will be recovered
-in Phase 3 and put into
-.I lost+found .
-If the attempt to allocate the root fails,
-.I fsck
-will exit with the message:
-.br
-.B "CANNOT ALLOCATE ROOT INODE" .
-.IP NO
-.I fsck
-will then prompt with
-.B "CONTINUE" .
-.LP
-Possible responses to the CONTINUE prompt are:
-.IP YES
-ignore the
-.B "DUPS/BAD"
-error condition in the root inode and
-attempt to continue to run the file system check.
-If the root inode is not correct,
-then this may result in many other error conditions.
-.IP NO
-terminate the program.
-.sp
-.LP
-.B "NAME TOO LONG \fIF\fP"
-.br
-An excessively long path name has been found.
-This usually indicates loops in the file system name space.
-This can occur if the super user has made circular links to directories.
-The offending links must be removed (by a guru).
-.sp
-.LP
-.B "I OUT OF RANGE I=\fII\fP NAME=\fIF\fP (REMOVE)"
-.br
-A directory entry \fIF\fP has an inode number \fII\fP that is greater than
-the end of the inode list.
-.LP
-Possible responses to the REMOVE prompt are:
-.IP YES
-the directory entry \fIF\fP is removed.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "UNALLOCATED I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP \fItype\fP=\fIF\fP (REMOVE)"
-.br
-A directory or file entry \fIF\fP points to an unallocated inode \fII\fP.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, modify time \fIT\fP,
-and name \fIF\fP are printed.
-.LP
-Possible responses to the REMOVE prompt are:
-.IP YES
-the directory entry \fIF\fP is removed.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "DUP/BAD I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP \fItype\fP=\fIF\fP (REMOVE)"
-.br
-Phase 1 or Phase 1b have found duplicate blocks or bad blocks
-associated with directory or file entry \fIF\fP, inode \fII\fP.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, modify time \fIT\fP,
-and directory name \fIF\fP are printed.
-.LP
-Possible responses to the REMOVE prompt are:
-.IP YES
-the directory entry \fIF\fP is removed.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "ZERO LENGTH DIRECTORY I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (REMOVE)"
-.br
-A directory entry \fIF\fP has a size \fIS\fP that is zero.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, modify time \fIT\fP,
-and directory name \fIF\fP are printed.
-.LP
-Possible responses to the REMOVE prompt are:
-.IP YES
-the directory entry \fIF\fP is removed;
-this will always invoke the BAD/DUP error condition in Phase 4.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "DIRECTORY TOO SHORT I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fIF\fP has been found whose size \fIS\fP
-is less than the minimum size directory.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, modify time \fIT\fP,
-and directory name \fIF\fP are printed.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-increase the size of the directory to the minimum directory size.
-.IP NO
-ignore this directory.
-.sp
-.LP
-.B "DIRECTORY \fIF\fP LENGTH \fIS\fP NOT MULTIPLE OF \fIB\fP (ADJUST)
-.br
-A directory \fIF\fP has been found with size \fIS\fP that is not
-a multiple of the directory blocksize \fIB\fP.
-.LP
-Possible responses to the ADJUST prompt are:
-.IP YES
-the length is rounded up to the appropriate block size.
-This error can occur on 4.2BSD file systems.
-Thus when preen'ing the file system only a warning is printed
-and the directory is adjusted.
-.IP NO
-ignore the error condition.
-.sp
-.LP
-.B "DIRECTORY CORRUPTED I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (SALVAGE)"
-.br
-A directory with an inconsistent internal state has been found.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-throw away all entries up to the next directory boundary (usually 512-byte)
-boundary.
-This drastic action can throw away up to 42 entries,
-and should be taken only after other recovery efforts have failed.
-.IP NO
-skip up to the next directory boundary and resume reading,
-but do not modify the directory.
-.sp
-.LP
-.B "BAD INODE NUMBER FOR `.' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found whose inode number for `.' does
-does not equal \fII\fP.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-change the inode number for `.' to be equal to \fII\fP.
-.IP NO
-leave the inode number for `.' unchanged.
-.sp
-.LP
-.B "MISSING `.' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found whose first entry is unallocated.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-build an entry for `.' with inode number equal to \fII\fP.
-.IP NO
-leave the directory unchanged.
-.sp
-.LP
-.B "MISSING `.' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP"
-.br
-.B "CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS \fIF\fP"
-.br
-A directory \fII\fP has been found whose first entry is \fIF\fP.
-.I Fsck
-cannot resolve this problem.
-The file system should be mounted and the offending entry \fIF\fP
-moved elsewhere.
-The file system should then be unmounted and
-.I fsck
-should be run again.
-.sp
-.LP
-.B "MISSING `.' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP"
-.br
-.B "CANNOT FIX, INSUFFICIENT SPACE TO ADD `.'"
-.br
-A directory \fII\fP has been found whose first entry is not `.'.
-.I Fsck
-cannot resolve this problem as it should never happen.
-See a guru.
-.sp
-.LP
-.B "EXTRA `.' ENTRY I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found that has more than one entry for `.'.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-remove the extra entry for `.'.
-.IP NO
-leave the directory unchanged.
-.sp
-.LP
-.B "BAD INODE NUMBER FOR `..' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found whose inode number for `..' does
-does not equal the parent of \fII\fP.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-change the inode number for `..' to be equal to the parent of \fII\fP
-(``\fB..\fP'' in the root inode points to itself).
-.IP NO
-leave the inode number for `..' unchanged.
-.sp
-.LP
-.B "MISSING `..' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found whose second entry is unallocated.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-build an entry for `..' with inode number equal to the parent of \fII\fP
-(``\fB..\fP'' in the root inode points to itself).
-.IP NO
-leave the directory unchanged.
-.sp
-.LP
-.B "MISSING `..' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP"
-.br
-.B "CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS \fIF\fP"
-.br
-A directory \fII\fP has been found whose second entry is \fIF\fP.
-.I Fsck
-cannot resolve this problem.
-The file system should be mounted and the offending entry \fIF\fP
-moved elsewhere.
-The file system should then be unmounted and
-.I fsck
-should be run again.
-.sp
-.LP
-.B "MISSING `..' I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP"
-.br
-.B "CANNOT FIX, INSUFFICIENT SPACE TO ADD `..'"
-.br
-A directory \fII\fP has been found whose second entry is not `..'.
-.I Fsck
-cannot resolve this problem.
-The file system should be mounted and the second entry in the directory
-moved elsewhere.
-The file system should then be unmounted and
-.I fsck
-should be run again.
-.sp
-.LP
-.B "EXTRA `..' ENTRY I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP DIR=\fIF\fP (FIX)"
-.br
-A directory \fII\fP has been found that has more than one entry for `..'.
-.LP
-Possible responses to the FIX prompt are:
-.IP YES
-remove the extra entry for `..'.
-.IP NO
-leave the directory unchanged.
-.sp
-.LP
-.B "\fIN\fP IS AN EXTRANEOUS HARD LINK TO A DIRECTORY \fID\fP (REMOVE)
-.br
-.I Fsck
-has found a hard link, \fIN\fP, to a directory, \fID\fP.
-When preen'ing the extraneous links are ignored.
-.LP
-Possible responses to the REMOVE prompt are:
-.IP YES
-delete the extraneous entry, \fIN\fP.
-.IP NO
-ignore the error condition.
-.sp
-.LP
-.B "BAD INODE \fIS\fP TO DESCEND"
-.br
-An internal error has caused an impossible state \fIS\fP to be passed to the
-routine that descends the file system directory structure.
-.I Fsck
-exits.
-See a guru.
-.sp
-.LP
-.B "BAD RETURN STATE \fIS\fP FROM DESCEND"
-.br
-An internal error has caused an impossible state \fIS\fP to be returned
-from the routine that descends the file system directory structure.
-.I Fsck
-exits.
-See a guru.
-.sp
-.LP
-.B "BAD STATE \fIS\fP FOR ROOT INODE"
-.br
-An internal error has caused an impossible state \fIS\fP to be assigned
-to the root inode.
-.I Fsck
-exits.
-See a guru.
-.NH 2
-Phase 3 \- Check Connectivity
-.PP
-This phase concerns itself with the directory connectivity seen in
-Phase 2.
-This section lists error conditions resulting from
-unreferenced directories,
-and missing or full
-.I lost+found
-directories.
-.sp
-.LP
-.B "UNREF DIR I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP (RECONNECT)"
-.br
-The directory inode \fII\fP was not connected to a directory entry
-when the file system was traversed.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, and
-modify time \fIT\fP of directory inode \fII\fP are printed.
-When preen'ing, the directory is reconnected if its size is non-zero,
-otherwise it is cleared.
-.LP
-Possible responses to the RECONNECT prompt are:
-.IP YES
-reconnect directory inode \fII\fP to the file system in the
-directory for lost files (usually \fIlost+found\fP).
-This may invoke the
-.I lost+found
-error condition in Phase 3
-if there are problems connecting directory inode \fII\fP to \fIlost+found\fP.
-This may also invoke the CONNECTED error condition in Phase 3 if the link
-was successful.
-.IP NO
-ignore this error condition.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "NO lost+found DIRECTORY (CREATE)"
-.br
-There is no
-.I lost+found
-directory in the root directory of the file system;
-When preen'ing
-.I fsck
-tries to create a \fIlost+found\fP directory.
-.LP
-Possible responses to the CREATE prompt are:
-.IP YES
-create a \fIlost+found\fP directory in the root of the file system.
-This may raise the message:
-.br
-.B "NO SPACE LEFT IN / (EXPAND)"
-.br
-See below for the possible responses.
-Inability to create a \fIlost+found\fP directory generates the message:
-.br
-.B "SORRY. CANNOT CREATE lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "lost+found IS NOT A DIRECTORY (REALLOCATE)"
-.br
-The entry for
-.I lost+found
-is not a directory.
-.LP
-Possible responses to the REALLOCATE prompt are:
-.IP YES
-allocate a directory inode, and change \fIlost+found\fP to reference it.
-The previous inode reference by the \fIlost+found\fP name is not cleared.
-Thus it will either be reclaimed as an UNREF'ed inode or have its
-link count ADJUST'ed later in this Phase.
-Inability to create a \fIlost+found\fP directory generates the message:
-.br
-.B "SORRY. CANNOT CREATE lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "NO SPACE LEFT IN /lost+found (EXPAND)"
-.br
-There is no space to add another entry to the
-.I lost+found
-directory in the root directory
-of the file system.
-When preen'ing the
-.I lost+found
-directory is expanded.
-.LP
-Possible responses to the EXPAND prompt are:
-.IP YES
-the
-.I lost+found
-directory is expanded to make room for the new entry.
-If the attempted expansion fails
-.I fsck
-prints the message:
-.br
-.B "SORRY. NO SPACE IN lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-Clean out unnecessary entries in
-.I lost+found .
-This error is fatal if the file system is being preen'ed.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "DIR I=\fII1\fP CONNECTED. PARENT WAS I=\fII2\fP"
-.br
-This is an advisory message indicating a directory inode \fII1\fP was
-successfully connected to the
-.I lost+found
-directory.
-The parent inode \fII2\fP of the directory inode \fII1\fP is
-replaced by the inode number of the
-.I lost+found
-directory.
-.sp
-.LP
-.B "DIRECTORY \fIF\fP LENGTH \fIS\fP NOT MULTIPLE OF \fIB\fP (ADJUST)
-.br
-A directory \fIF\fP has been found with size \fIS\fP that is not
-a multiple of the directory blocksize \fIB\fP
-(this can reoccur in Phase 3 if it is not adjusted in Phase 2).
-.LP
-Possible responses to the ADJUST prompt are:
-.IP YES
-the length is rounded up to the appropriate block size.
-This error can occur on 4.2BSD file systems.
-Thus when preen'ing the file system only a warning is printed
-and the directory is adjusted.
-.IP NO
-ignore the error condition.
-.sp
-.LP
-.B "BAD INODE \fIS\fP TO DESCEND"
-.br
-An internal error has caused an impossible state \fIS\fP to be passed to the
-routine that descends the file system directory structure.
-.I Fsck
-exits.
-See a guru.
-.NH 2
-Phase 4 \- Check Reference Counts
-.PP
-This phase concerns itself with the link count information
-seen in Phase 2 and Phase 3.
-This section lists error conditions resulting from
-unreferenced files,
-missing or full
-.I lost+found
-directory,
-incorrect link counts for files, directories, symbolic links, or special files,
-unreferenced files, symbolic links, and directories,
-and bad or duplicate blocks in files, symbolic links, and directories.
-All errors in this phase are correctable if the file system is being preen'ed
-except running out of space in the \fIlost+found\fP directory.
-.sp
-.LP
-.B "UNREF FILE I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP (RECONNECT)"
-.br
-Inode \fII\fP was not connected to a directory entry
-when the file system was traversed.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, and
-modify time \fIT\fP of inode \fII\fP are printed.
-When preen'ing the file is cleared if either its size or its
-link count is zero,
-otherwise it is reconnected.
-.LP
-Possible responses to the RECONNECT prompt are:
-.IP YES
-reconnect inode \fII\fP to the file system in the directory for
-lost files (usually \fIlost+found\fP).
-This may invoke the
-.I lost+found
-error condition in Phase 4
-if there are problems connecting inode \fII\fP to
-.I lost+found .
-.IP NO
-ignore this error condition.
-This will always invoke the CLEAR error condition in Phase 4.
-.sp
-.LP
-.B "(CLEAR)"
-.br
-The inode mentioned in the immediately previous error condition can not be
-reconnected.
-This cannot occur if the file system is being preen'ed,
-since lack of space to reconnect files is a fatal error.
-.LP
-Possible responses to the CLEAR prompt are:
-.IP YES
-de-allocate the inode mentioned in the immediately previous error condition by zeroing its contents.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "NO lost+found DIRECTORY (CREATE)"
-.br
-There is no
-.I lost+found
-directory in the root directory of the file system;
-When preen'ing
-.I fsck
-tries to create a \fIlost+found\fP directory.
-.LP
-Possible responses to the CREATE prompt are:
-.IP YES
-create a \fIlost+found\fP directory in the root of the file system.
-This may raise the message:
-.br
-.B "NO SPACE LEFT IN / (EXPAND)"
-.br
-See below for the possible responses.
-Inability to create a \fIlost+found\fP directory generates the message:
-.br
-.B "SORRY. CANNOT CREATE lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "lost+found IS NOT A DIRECTORY (REALLOCATE)"
-.br
-The entry for
-.I lost+found
-is not a directory.
-.LP
-Possible responses to the REALLOCATE prompt are:
-.IP YES
-allocate a directory inode, and change \fIlost+found\fP to reference it.
-The previous inode reference by the \fIlost+found\fP name is not cleared.
-Thus it will either be reclaimed as an UNREF'ed inode or have its
-link count ADJUST'ed later in this Phase.
-Inability to create a \fIlost+found\fP directory generates the message:
-.br
-.B "SORRY. CANNOT CREATE lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "NO SPACE LEFT IN /lost+found (EXPAND)"
-.br
-There is no space to add another entry to the
-.I lost+found
-directory in the root directory
-of the file system.
-When preen'ing the
-.I lost+found
-directory is expanded.
-.LP
-Possible responses to the EXPAND prompt are:
-.IP YES
-the
-.I lost+found
-directory is expanded to make room for the new entry.
-If the attempted expansion fails
-.I fsck
-prints the message:
-.br
-.B "SORRY. NO SPACE IN lost+found DIRECTORY"
-.br
-and aborts the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-Clean out unnecessary entries in
-.I lost+found .
-This error is fatal if the file system is being preen'ed.
-.IP NO
-abort the attempt to linkup the lost inode.
-This will always invoke the UNREF error condition in Phase 4.
-.sp
-.LP
-.B "LINK COUNT \fItype\fP I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP COUNT=\fIX\fP SHOULD BE \fIY\fP (ADJUST)"
-.br
-The link count for inode \fII\fP,
-is \fIX\fP but should be \fIY\fP.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP, and modify time \fIT\fP
-are printed.
-When preen'ing the link count is adjusted unless the number of references
-is increasing, a condition that should never occur unless precipitated
-by a hardware failure.
-When the number of references is increasing under preen mode,
-.I fsck
-exits with the message:
-.br
-.B "LINK COUNT INCREASING"
-.LP
-Possible responses to the ADJUST prompt are:
-.IP YES
-replace the link count of file inode \fII\fP with \fIY\fP.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "UNREF \fItype\fP I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP (CLEAR)"
-.br
-Inode \fII\fP, was not connected to a directory entry when the
-file system was traversed.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP,
-and modify time \fIT\fP of inode \fII\fP
-are printed.
-When preen'ing,
-this is a file that was not connected because its size or link count was zero,
-hence it is cleared.
-.LP
-Possible responses to the CLEAR prompt are:
-.IP YES
-de-allocate inode \fII\fP by zeroing its contents.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "BAD/DUP \fItype\fP I=\fII\fP OWNER=\fIO\fP MODE=\fIM\fP SIZE=\fIS\fP MTIME=\fIT\fP (CLEAR)"
-.br
-Phase 1 or Phase 1b have found duplicate blocks
-or bad blocks associated with
-inode \fII\fP.
-The owner \fIO\fP, mode \fIM\fP, size \fIS\fP,
-and modify time \fIT\fP of inode \fII\fP
-are printed.
-This error cannot arise when the file system is being preen'ed,
-as it would have caused a fatal error earlier.
-.LP
-Possible responses to the CLEAR prompt are:
-.IP YES
-de-allocate inode \fII\fP by zeroing its contents.
-.IP NO
-ignore this error condition.
-.NH 2
-Phase 5 - Check Cyl groups
-.PP
-This phase concerns itself with the free-block and used-inode maps.
-This section lists error conditions resulting from
-allocated blocks in the free-block maps,
-free blocks missing from free-block maps,
-and the total free-block count incorrect.
-It also lists error conditions resulting from
-free inodes in the used-inode maps,
-allocated inodes missing from used-inode maps,
-and the total used-inode count incorrect.
-.sp
-.LP
-.B "CG \fIC\fP: BAD MAGIC NUMBER"
-.br
-The magic number of cylinder group \fIC\fP is wrong.
-This usually indicates that the cylinder group maps have been destroyed.
-When running manually the cylinder group is marked as needing
-to be reconstructed.
-This error is fatal if the file system is being preen'ed.
-.sp
-.LP
-.B "BLK(S) MISSING IN BIT MAPS (SALVAGE)"
-.br
-A cylinder group block map is missing some free blocks.
-During preen'ing the maps are reconstructed.
-.LP
-Possible responses to the SALVAGE prompt are:
-.IP YES
-reconstruct the free block map.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "SUMMARY INFORMATION BAD (SALVAGE)"
-.br
-The summary information was found to be incorrect.
-When preen'ing,
-the summary information is recomputed.
-.LP
-Possible responses to the SALVAGE prompt are:
-.IP YES
-reconstruct the summary information.
-.IP NO
-ignore this error condition.
-.sp
-.LP
-.B "FREE BLK COUNT(S) WRONG IN SUPERBLOCK (SALVAGE)"
-.br
-The superblock free block information was found to be incorrect.
-When preen'ing,
-the superblock free block information is recomputed.
-.LP
-Possible responses to the SALVAGE prompt are:
-.IP YES
-reconstruct the superblock free block information.
-.IP NO
-ignore this error condition.
-.NH 2
-Cleanup
-.PP
-Once a file system has been checked, a few cleanup functions are performed.
-This section lists advisory messages about
-the file system
-and modify status of the file system.
-.sp
-.LP
-.B "\fIV\fP files, \fIW\fP used, \fIX\fP free (\fIY\fP frags, \fIZ\fP blocks)"
-.br
-This is an advisory message indicating that
-the file system checked contained
-\fIV\fP files using
-\fIW\fP fragment sized blocks leaving
-\fIX\fP fragment sized blocks free in the file system.
-The numbers in parenthesis breaks the free count down into
-\fIY\fP free fragments and
-\fIZ\fP free full sized blocks.
-.sp
-.LP
-.B "***** REBOOT UNIX *****"
-.br
-This is an advisory message indicating that
-the root file system has been modified by
-.I fsck.
-If UNIX is not rebooted immediately,
-the work done by
-.I fsck
-may be undone by the in-core copies of tables
-UNIX keeps.
-When preen'ing,
-.I fsck
-will exit with a code of 4.
-The standard auto-reboot script distributed with 4.3BSD
-interprets an exit code of 4 by issuing a reboot system call.
-.sp
-.LP
-.B "***** FILE SYSTEM WAS MODIFIED *****"
-.br
-This is an advisory message indicating that
-the current file system was modified by
-.I fsck.
-If this file system is mounted or is the current root file system,
-.I fsck
-should be halted and UNIX rebooted.
-If UNIX is not rebooted immediately,
-the work done by
-.I fsck
-may be undone by the in-core copies of tables
-UNIX keeps.
diff --git a/sbin/fsck/SMM.doc/Makefile b/sbin/fsck/SMM.doc/Makefile
deleted file mode 100644
index 26823bc..0000000
--- a/sbin/fsck/SMM.doc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/8/93
-
-DIR= smm/03.fsck
-SRCS= 0.t 1.t 2.t 3.t 4.t
-MACROS= -ms
-
-.include <bsd.doc.mk>
diff --git a/sbin/fsck/dir.c b/sbin/fsck/dir.c
deleted file mode 100644
index 5def8b2..0000000
--- a/sbin/fsck/dir.c
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/time.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-char *lfname = "lost+found";
-int lfmode = 01777;
-struct dirtemplate emptydir = { 0, DIRBLKSIZ };
-struct dirtemplate dirhead = {
- 0, 12, DT_DIR, 1, ".",
- 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
-};
-struct odirtemplate odirhead = {
- 0, 12, 1, ".",
- 0, DIRBLKSIZ - 12, 2, ".."
-};
-
-static int chgino __P((struct inodesc *));
-static int dircheck __P((struct inodesc *, struct direct *));
-static int expanddir __P((struct dinode *dp, char *name));
-static void freedir __P((ino_t ino, ino_t parent));
-static struct direct *fsck_readdir __P((struct inodesc *));
-static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
-static int lftempname __P((char *bufp, ino_t ino));
-static int mkentry __P((struct inodesc *));
-
-/*
- * Propagate connected state through the tree.
- */
-void
-propagate()
-{
- register struct inoinfo **inpp, *inp;
- struct inoinfo **inpend;
- long change;
-
- inpend = &inpsort[inplast];
- do {
- change = 0;
- for (inpp = inpsort; inpp < inpend; inpp++) {
- inp = *inpp;
- if (inp->i_parent == 0)
- continue;
- if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
- inoinfo(inp->i_number)->ino_state == DSTATE) {
- inoinfo(inp->i_number)->ino_state = DFOUND;
- change++;
- }
- }
- } while (change > 0);
-}
-
-/*
- * Scan each entry in a directory block.
- */
-int
-dirscan(idesc)
- register struct inodesc *idesc;
-{
- register struct direct *dp;
- register struct bufarea *bp;
- int dsize, n;
- long blksiz;
- char dbuf[DIRBLKSIZ];
-
- if (idesc->id_type != DATA)
- errx(EEXIT, "wrong type to dirscan %d", idesc->id_type);
- if (idesc->id_entryno == 0 &&
- (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
- idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
- blksiz = idesc->id_numfrags * sblock.fs_fsize;
- if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {
- idesc->id_filesize -= blksiz;
- return (SKIP);
- }
- idesc->id_loc = 0;
- for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
- dsize = dp->d_reclen;
- if (dsize > sizeof(dbuf))
- dsize = sizeof(dbuf);
- memmove(dbuf, dp, (size_t)dsize);
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (!newinofmt) {
- struct direct *tdp = (struct direct *)dbuf;
- u_char tmp;
-
- tmp = tdp->d_namlen;
- tdp->d_namlen = tdp->d_type;
- tdp->d_type = tmp;
- }
-# endif
- idesc->id_dirp = (struct direct *)dbuf;
- if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (!newinofmt && !doinglevel2) {
- struct direct *tdp;
- u_char tmp;
-
- tdp = (struct direct *)dbuf;
- tmp = tdp->d_namlen;
- tdp->d_namlen = tdp->d_type;
- tdp->d_type = tmp;
- }
-# endif
- bp = getdirblk(idesc->id_blkno, blksiz);
- memmove(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf,
- (size_t)dsize);
- dirty(bp);
- sbdirty();
- }
- if (n & STOP)
- return (n);
- }
- return (idesc->id_filesize > 0 ? KEEPON : STOP);
-}
-
-/*
- * get next entry in a directory.
- */
-static struct direct *
-fsck_readdir(idesc)
- register struct inodesc *idesc;
-{
- register struct direct *dp, *ndp;
- register struct bufarea *bp;
- long size, blksiz, fix, dploc;
-
- blksiz = idesc->id_numfrags * sblock.fs_fsize;
- bp = getdirblk(idesc->id_blkno, blksiz);
- if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 &&
- idesc->id_loc < blksiz) {
- dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
- if (dircheck(idesc, dp))
- goto dpok;
- if (idesc->id_fix == IGNORE)
- return (0);
- fix = dofix(idesc, "DIRECTORY CORRUPTED");
- bp = getdirblk(idesc->id_blkno, blksiz);
- dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
- dp->d_reclen = DIRBLKSIZ;
- dp->d_ino = 0;
- dp->d_type = 0;
- dp->d_namlen = 0;
- dp->d_name[0] = '\0';
- if (fix)
- dirty(bp);
- idesc->id_loc += DIRBLKSIZ;
- idesc->id_filesize -= DIRBLKSIZ;
- return (dp);
- }
-dpok:
- if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz)
- return NULL;
- dploc = idesc->id_loc;
- dp = (struct direct *)(bp->b_un.b_buf + dploc);
- idesc->id_loc += dp->d_reclen;
- idesc->id_filesize -= dp->d_reclen;
- if ((idesc->id_loc % DIRBLKSIZ) == 0)
- return (dp);
- ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
- if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
- dircheck(idesc, ndp) == 0) {
- size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
- idesc->id_loc += size;
- idesc->id_filesize -= size;
- if (idesc->id_fix == IGNORE)
- return (0);
- fix = dofix(idesc, "DIRECTORY CORRUPTED");
- bp = getdirblk(idesc->id_blkno, blksiz);
- dp = (struct direct *)(bp->b_un.b_buf + dploc);
- dp->d_reclen += size;
- if (fix)
- dirty(bp);
- }
- return (dp);
-}
-
-/*
- * Verify that a directory entry is valid.
- * This is a superset of the checks made in the kernel.
- */
-static int
-dircheck(idesc, dp)
- struct inodesc *idesc;
- register struct direct *dp;
-{
- register int size;
- register char *cp;
- u_char namlen, type;
- int spaceleft;
-
- spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
- if (dp->d_reclen == 0 ||
- dp->d_reclen > spaceleft ||
- (dp->d_reclen & 0x3) != 0)
- goto bad;
- if (dp->d_ino == 0)
- return (1);
- size = DIRSIZ(!newinofmt, dp);
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- if (!newinofmt) {
- type = dp->d_namlen;
- namlen = dp->d_type;
- } else {
- namlen = dp->d_namlen;
- type = dp->d_type;
- }
-# else
- namlen = dp->d_namlen;
- type = dp->d_type;
-# endif
- if (dp->d_reclen < size ||
- idesc->id_filesize < size ||
- namlen > MAXNAMLEN ||
- type > 15)
- goto bad;
- for (cp = dp->d_name, size = 0; size < namlen; size++)
- if (*cp == '\0' || (*cp++ == '/'))
- goto bad;
- if (*cp != '\0')
- goto bad;
- return (1);
-bad:
- if (debug)
- printf("Bad dir: ino %d reclen %d namlen %d type %d name %s\n",
- dp->d_ino, dp->d_reclen, dp->d_namlen, dp->d_type,
- dp->d_name);
- return (0);
-}
-
-void
-direrror(ino, errmesg)
- ino_t ino;
- char *errmesg;
-{
-
- fileerror(ino, ino, errmesg);
-}
-
-void
-fileerror(cwd, ino, errmesg)
- ino_t cwd, ino;
- char *errmesg;
-{
- register struct dinode *dp;
- char pathbuf[MAXPATHLEN + 1];
-
- pwarn("%s ", errmesg);
- pinode(ino);
- printf("\n");
- getpathname(pathbuf, cwd, ino);
- if (ino < ROOTINO || ino > maxino) {
- pfatal("NAME=%s\n", pathbuf);
- return;
- }
- dp = ginode(ino);
- if (ftypeok(dp))
- pfatal("%s=%s\n",
- (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf);
- else
- pfatal("NAME=%s\n", pathbuf);
-}
-
-void
-adjust(idesc, lcnt)
- register struct inodesc *idesc;
- int lcnt;
-{
- struct dinode *dp;
- int saveresolved;
-
- dp = ginode(idesc->id_number);
- if (dp->di_nlink == lcnt) {
- /*
- * If we have not hit any unresolved problems, are running
- * 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 :
- ((dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"));
- pinode(idesc->id_number);
- printf(" COUNT %d SHOULD BE %d",
- dp->di_nlink, dp->di_nlink - lcnt);
- if (preen || usedsoftdep) {
- if (lcnt < 0) {
- printf("\n");
- pfatal("LINK COUNT INCREASING");
- }
- if (preen)
- printf(" (ADJUSTED)\n");
- }
- if (preen || reply("ADJUST") == 1) {
- dp->di_nlink -= lcnt;
- inodirty();
- }
- }
-}
-
-static int
-mkentry(idesc)
- struct inodesc *idesc;
-{
- register struct direct *dirp = idesc->id_dirp;
- struct direct newent;
- int newlen, oldlen;
-
- newent.d_namlen = strlen(idesc->id_name);
- newlen = DIRSIZ(0, &newent);
- if (dirp->d_ino != 0)
- oldlen = DIRSIZ(0, dirp);
- else
- oldlen = 0;
- if (dirp->d_reclen - oldlen < newlen)
- return (KEEPON);
- newent.d_reclen = dirp->d_reclen - oldlen;
- dirp->d_reclen = oldlen;
- dirp = (struct direct *)(((char *)dirp) + oldlen);
- dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
- dirp->d_reclen = newent.d_reclen;
- if (newinofmt)
- dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
- else
- dirp->d_type = 0;
- dirp->d_namlen = newent.d_namlen;
- memmove(dirp->d_name, idesc->id_name, (size_t)newent.d_namlen + 1);
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- /*
- * If the entry was split, dirscan() will only reverse the byte
- * order of the original entry, and not the new one, before
- * writing it back out. So, we reverse the byte order here if
- * necessary.
- */
- if (oldlen != 0 && !newinofmt && !doinglevel2) {
- u_char tmp;
-
- tmp = dirp->d_namlen;
- dirp->d_namlen = dirp->d_type;
- dirp->d_type = tmp;
- }
-# endif
- return (ALTERED|STOP);
-}
-
-static int
-chgino(idesc)
- struct inodesc *idesc;
-{
- register struct direct *dirp = idesc->id_dirp;
-
- if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
- return (KEEPON);
- dirp->d_ino = idesc->id_parent;
- if (newinofmt)
- dirp->d_type = inoinfo(idesc->id_parent)->ino_type;
- else
- dirp->d_type = 0;
- return (ALTERED|STOP);
-}
-
-int
-linkup(orphan, parentdir, name)
- ino_t orphan;
- ino_t parentdir;
- char *name;
-{
- register struct dinode *dp;
- int lostdir;
- ino_t oldlfdir;
- struct inodesc idesc;
- char tempname[BUFSIZ];
-
- memset(&idesc, 0, sizeof(struct inodesc));
- dp = ginode(orphan);
- lostdir = (dp->di_mode & IFMT) == IFDIR;
- pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
- pinode(orphan);
- if (preen && dp->di_size == 0)
- return (0);
- if (preen)
- printf(" (RECONNECTED)\n");
- else
- if (reply("RECONNECT") == 0)
- return (0);
- if (lfdir == 0) {
- dp = ginode(ROOTINO);
- idesc.id_name = lfname;
- idesc.id_type = DATA;
- idesc.id_func = findino;
- idesc.id_number = ROOTINO;
- if ((ckinode(dp, &idesc) & FOUND) != 0) {
- lfdir = idesc.id_parent;
- } else {
- pwarn("NO lost+found DIRECTORY");
- if (preen || reply("CREATE")) {
- lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);
- if (lfdir != 0) {
- if (makeentry(ROOTINO, lfdir, lfname) != 0) {
- numdirs++;
- if (preen)
- printf(" (CREATED)\n");
- } else {
- freedir(lfdir, ROOTINO);
- lfdir = 0;
- if (preen)
- printf("\n");
- }
- }
- }
- }
- if (lfdir == 0) {
- pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY");
- printf("\n\n");
- return (0);
- }
- }
- dp = ginode(lfdir);
- if ((dp->di_mode & IFMT) != IFDIR) {
- pfatal("lost+found IS NOT A DIRECTORY");
- if (reply("REALLOCATE") == 0)
- return (0);
- oldlfdir = lfdir;
- if ((lfdir = allocdir(ROOTINO, (ino_t)0, lfmode)) == 0) {
- pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");
- return (0);
- }
- if ((changeino(ROOTINO, lfname, lfdir) & ALTERED) == 0) {
- pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");
- return (0);
- }
- inodirty();
- idesc.id_type = ADDR;
- idesc.id_func = pass4check;
- idesc.id_number = oldlfdir;
- adjust(&idesc, inoinfo(oldlfdir)->ino_linkcnt + 1);
- inoinfo(oldlfdir)->ino_linkcnt = 0;
- dp = ginode(lfdir);
- }
- if (inoinfo(lfdir)->ino_state != DFOUND) {
- pfatal("SORRY. NO lost+found DIRECTORY\n\n");
- return (0);
- }
- (void)lftempname(tempname, orphan);
- if (makeentry(lfdir, orphan, (name ? name : tempname)) == 0) {
- pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
- printf("\n\n");
- return (0);
- }
- inoinfo(orphan)->ino_linkcnt--;
- if (lostdir) {
- if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&
- parentdir != (ino_t)-1)
- (void)makeentry(orphan, lfdir, "..");
- dp = ginode(lfdir);
- dp->di_nlink++;
- inodirty();
- inoinfo(lfdir)->ino_linkcnt++;
- pwarn("DIR I=%lu CONNECTED. ", orphan);
- if (parentdir != (ino_t)-1) {
- printf("PARENT WAS I=%lu\n", (u_long)parentdir);
- /*
- * 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.
- */
- inoinfo(parentdir)->ino_linkcnt++;
- }
- if (preen == 0)
- printf("\n");
- }
- return (1);
-}
-
-/*
- * fix an entry in a directory.
- */
-int
-changeino(dir, name, newnum)
- ino_t dir;
- char *name;
- ino_t newnum;
-{
- struct inodesc idesc;
-
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = DATA;
- idesc.id_func = chgino;
- idesc.id_number = dir;
- idesc.id_fix = DONTKNOW;
- idesc.id_name = name;
- idesc.id_parent = newnum; /* new value for name */
- return (ckinode(ginode(dir), &idesc));
-}
-
-/*
- * make an entry in a directory
- */
-int
-makeentry(parent, ino, name)
- ino_t parent, ino;
- char *name;
-{
- struct dinode *dp;
- struct inodesc idesc;
- char pathbuf[MAXPATHLEN + 1];
-
- if (parent < ROOTINO || parent >= maxino ||
- ino < ROOTINO || ino >= maxino)
- return (0);
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = DATA;
- idesc.id_func = mkentry;
- idesc.id_number = parent;
- idesc.id_parent = ino; /* this is the inode to enter */
- idesc.id_fix = DONTKNOW;
- idesc.id_name = name;
- dp = ginode(parent);
- if (dp->di_size % DIRBLKSIZ) {
- dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
- inodirty();
- }
- if ((ckinode(dp, &idesc) & ALTERED) != 0)
- return (1);
- getpathname(pathbuf, parent, parent);
- dp = ginode(parent);
- if (expanddir(dp, pathbuf) == 0)
- return (0);
- return (ckinode(dp, &idesc) & ALTERED);
-}
-
-/*
- * Attempt to expand the size of a directory
- */
-static int
-expanddir(dp, name)
- register struct dinode *dp;
- char *name;
-{
- ufs_daddr_t lastbn, newblk;
- register struct bufarea *bp;
- char *cp, firstblk[DIRBLKSIZ];
-
- lastbn = lblkno(&sblock, dp->di_size);
- if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)
- return (0);
- if ((newblk = allocblk(sblock.fs_frag)) == 0)
- return (0);
- dp->di_db[lastbn + 1] = dp->di_db[lastbn];
- dp->di_db[lastbn] = newblk;
- dp->di_size += sblock.fs_bsize;
- dp->di_blocks += btodb(sblock.fs_bsize);
- bp = getdirblk(dp->di_db[lastbn + 1],
- (long)dblksize(&sblock, dp, lastbn + 1));
- if (bp->b_errs)
- goto bad;
- memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
- bp = getdirblk(newblk, sblock.fs_bsize);
- if (bp->b_errs)
- goto bad;
- memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
- for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
- cp < &bp->b_un.b_buf[sblock.fs_bsize];
- cp += DIRBLKSIZ)
- memmove(cp, &emptydir, sizeof emptydir);
- dirty(bp);
- bp = getdirblk(dp->di_db[lastbn + 1],
- (long)dblksize(&sblock, dp, lastbn + 1));
- if (bp->b_errs)
- goto bad;
- memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir);
- pwarn("NO SPACE LEFT IN %s", name);
- if (preen)
- printf(" (EXPANDED)\n");
- else if (reply("EXPAND") == 0)
- goto bad;
- dirty(bp);
- inodirty();
- return (1);
-bad:
- dp->di_db[lastbn] = dp->di_db[lastbn + 1];
- dp->di_db[lastbn + 1] = 0;
- dp->di_size -= sblock.fs_bsize;
- dp->di_blocks -= btodb(sblock.fs_bsize);
- freeblk(newblk, sblock.fs_frag);
- return (0);
-}
-
-/*
- * allocate a new directory
- */
-ino_t
-allocdir(parent, request, mode)
- ino_t parent, request;
- int mode;
-{
- ino_t ino;
- char *cp;
- struct dinode *dp;
- struct bufarea *bp;
- struct inoinfo *inp;
- struct dirtemplate *dirp;
-
- ino = allocino(request, IFDIR|mode);
- if (newinofmt)
- dirp = &dirhead;
- else
- dirp = (struct dirtemplate *)&odirhead;
- dirp->dot_ino = ino;
- dirp->dotdot_ino = parent;
- dp = ginode(ino);
- bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
- if (bp->b_errs) {
- freeino(ino);
- return (0);
- }
- memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate));
- for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
- cp < &bp->b_un.b_buf[sblock.fs_fsize];
- cp += DIRBLKSIZ)
- memmove(cp, &emptydir, sizeof emptydir);
- dirty(bp);
- dp->di_nlink = 2;
- inodirty();
- if (ino == ROOTINO) {
- inoinfo(ino)->ino_linkcnt = dp->di_nlink;
- cacheino(dp, ino);
- return(ino);
- }
- if (inoinfo(parent)->ino_state != DSTATE &&
- inoinfo(parent)->ino_state != DFOUND) {
- freeino(ino);
- return (0);
- }
- cacheino(dp, ino);
- inp = getinoinfo(ino);
- inp->i_parent = parent;
- inp->i_dotdot = parent;
- inoinfo(ino)->ino_state = inoinfo(parent)->ino_state;
- if (inoinfo(ino)->ino_state == DSTATE) {
- inoinfo(ino)->ino_linkcnt = dp->di_nlink;
- inoinfo(parent)->ino_linkcnt++;
- }
- dp = ginode(parent);
- dp->di_nlink++;
- inodirty();
- return (ino);
-}
-
-/*
- * free a directory inode
- */
-static void
-freedir(ino, parent)
- ino_t ino, parent;
-{
- struct dinode *dp;
-
- if (ino != parent) {
- dp = ginode(parent);
- dp->di_nlink--;
- inodirty();
- }
- freeino(ino);
-}
-
-/*
- * generate a temporary name for the lost+found directory.
- */
-static int
-lftempname(bufp, ino)
- char *bufp;
- ino_t ino;
-{
- register ino_t in;
- register char *cp;
- int namlen;
-
- cp = bufp + 2;
- for (in = maxino; in > 0; in /= 10)
- cp++;
- *--cp = 0;
- namlen = cp - bufp;
- in = ino;
- while (cp > bufp) {
- *--cp = (in % 10) + '0';
- in /= 10;
- }
- *cp = '#';
- return (namlen);
-}
-
-/*
- * Get a directory block.
- * Insure that it is held until another is requested.
- */
-static struct bufarea *
-getdirblk(blkno, size)
- ufs_daddr_t blkno;
- long size;
-{
-
- if (pdirbp != 0)
- pdirbp->b_flags &= ~B_INUSE;
- pdirbp = getdatablk(blkno, size);
- return (pdirbp);
-}
diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8
deleted file mode 100644
index 59d7fa8..0000000
--- a/sbin/fsck/fsck.8
+++ /dev/null
@@ -1,321 +0,0 @@
-.\"
-.\" Copyright (c) 1980, 1989, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgment:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)fsck.8 8.4 (Berkeley) 5/9/95
-.\" $FreeBSD$
-.\"
-.Dd November 15, 1996
-.Dt FSCK 8
-.Os BSD 4
-.Sh NAME
-.Nm fsck
-.Nd filesystem consistency check and interactive repair
-.Sh SYNOPSIS
-.Nm fsck
-.Fl p
-.Op Fl f
-.Op Fl m Ar mode
-.Op Ar filesystem
-.Ar ...
-.Nm fsck
-.Op Fl ny
-.Op Fl b Ar block#
-.Op Fl c Ar level
-.Op Fl l Ar maxparallel
-.Op Fl m Ar mode
-.Op Ar filesystem
-.Ar ...
-.Sh DESCRIPTION
-The first form of
-.Nm
-preens a standard set of filesystems or the specified filesystems.
-It is normally used in the script
-.Pa /etc/rc
-during automatic reboot.
-Here
-.Nm
-reads the table
-.Pa /etc/fstab
-to determine which filesystems to check.
-Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro''
-and that have non-zero pass number are checked.
-Filesystems with pass number 1 (normally just the root filesystem)
-are checked one at a time.
-When pass 1 completes, all remaining filesystems are checked,
-running one process per disk drive.
-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
-to be the partition designator.
-.Pp
-In "preen" mode the clean flag of each filesystem's superblock is examined
-and only those filesystems that
-are not marked clean are checked.
-Filesystems are marked clean when they are unmounted,
-when they have been mounted read-only, or when
-.Nm
-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
-The kernel takes care that only a restricted class of innocuous filesystem
-inconsistencies can happen unless hardware or software failures intervene.
-These are limited to the following:
-.Pp
-.Bl -item -compact -offset indent
-.It
-Unreferenced inodes
-.It
-Link counts in inodes too large
-.It
-Missing blocks in the free map
-.It
-Blocks in the free map also in files
-.It
-Counts in the super-block wrong
-.El
-.Pp
-These are the only inconsistencies that
-.Nm
-with the
-.Fl p
-option will correct; if it encounters other inconsistencies, it exits
-with an abnormal return status and an automatic reboot will then fail.
-For each corrected inconsistency one or more lines will be printed
-identifying the filesystem on which the correction will take place,
-and the nature of the correction. After successfully correcting a filesystem,
-.Nm
-will print the number of files on that filesystem,
-the number of used and free blocks,
-and the percentage of fragmentation.
-.Pp
-If sent a
-.Dv QUIT
-signal,
-.Nm
-will finish the filesystem checks, then exit with an abnormal
-return status that causes an automatic reboot to fail.
-This is useful when you want to finish the filesystem checks during an
-automatic reboot,
-but do not want the machine to come up multiuser after the checks complete.
-.Pp
-Without the
-.Fl p
-option,
-.Nm
-audits and interactively repairs inconsistent conditions for filesystems.
-If the filesystem is inconsistent the operator is prompted for concurrence
-before each correction is attempted.
-It should be noted that some of the corrective actions which are not
-correctable under the
-.Fl p
-option will result in some loss of data.
-The amount and severity of data lost may be determined from the diagnostic
-output.
-The default action for each consistency correction
-is to wait for the operator to respond
-.Li yes
-or
-.Li no .
-If the operator does not have write permission on the filesystem
-.Nm
-will default to a
-.Fl n
-action.
-.Pp
-.Nm Fsck
-has more consistency checks than
-its predecessors
-.Em check , dcheck , fcheck ,
-and
-.Em icheck
-combined.
-.Pp
-The following flags are interpreted by
-.Nm Ns .
-.Bl -tag -width indent
-.It Fl b
-Use the block specified immediately after the flag as
-the super block for the filesystem. Block 32 is usually
-an alternate super block.
-.It Fl c
-Convert the filesystem to the specified level.
-Note that the level of a filesystem can only be raised.
-.Bl -tag -width indent
-There are currently four levels defined:
-.It 0
-The filesystem is in the old (static table) format.
-.It 1
-The filesystem is in the new (dynamic table) format.
-.It 2
-The filesystem supports 32-bit uid's and gid's,
-short symbolic links are stored in the inode,
-and directories have an added field showing the file type.
-.It 3
-If maxcontig is greater than one,
-build the free segment maps to aid in finding contiguous sets of blocks.
-If maxcontig is equal to one, delete any existing segment maps.
-.El
-.Pp
-In interactive mode,
-.Nm
-will list the conversion to be made
-and ask whether the conversion should be done.
-If a negative answer is given,
-no further operations are done on the filesystem.
-In preen mode,
-the conversion is listed and done if
-possible without user interaction.
-Conversion in preen mode is best used when all the filesystems
-are being converted at once.
-The format of a filesystem can be determined from the
-first line of output from
-.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
-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 Ns ;
-this should be used with great caution as this is a free license
-to continue after essentially unlimited trouble has been encountered.
-.El
-.Pp
-If no filesystems are given to
-.Nm
-then a default list of filesystems is read from
-the file
-.Pa /etc/fstab .
-.Pp
-.Bl -enum -indent indent -compact
-Inconsistencies checked are as follows:
-.It
-Blocks claimed by more than one inode or the free map.
-.It
-Blocks claimed by an inode outside the range of the filesystem.
-.It
-Incorrect link counts.
-.It
-Size checks:
-.Bl -item -indent indent -compact
-.It
-Directory size not a multiple of DIRBLKSIZ.
-.It
-Partially truncated file.
-.El
-.It
-Bad inode format.
-.It
-Blocks not accounted for anywhere.
-.It
-Directory checks:
-.Bl -item -indent indent -compact
-.It
-File pointing to unallocated inode.
-.It
-Inode number out of range.
-.It
-Directories with unallocated blocks (holes).
-.It
-Dot or dot-dot not the first two entries of a directory
-or having the wrong inode number.
-.El
-.It
-Super Block checks:
-.Bl -item -indent indent -compact
-.It
-More blocks for inodes than there are in the filesystem.
-.It
-Bad free block map format.
-.It
-Total free block and/or free inode count incorrect.
-.El
-.El
-.Pp
-Orphaned files and directories (allocated but unreferenced) are,
-with the operator's concurrence, reconnected by
-placing them in the
-.Pa lost+found
-directory.
-The name assigned is the inode number.
-If the
-.Pa lost+found
-directory does not exist, it is created.
-If there is insufficient space its size is increased.
-.Pp
-Because of inconsistencies between the block device and the buffer cache,
-the raw device should always be used.
-.Sh FILES
-.Bl -tag -width /etc/fstab -compact
-.It Pa /etc/fstab
-contains default list of filesystems to check.
-.El
-.Sh DIAGNOSTICS
-The diagnostics produced by
-.Nm
-are fully enumerated and explained in Appendix A of
-.Rs
-.%T "Fsck \- The UNIX File System Check Program"
-.Re
-.Sh SEE ALSO
-.Xr fs 5 ,
-.Xr fstab 5 ,
-.Xr fsdb 8 ,
-.Xr newfs 8 ,
-.Xr reboot 8
diff --git a/sbin/fsck/fsck.c b/sbin/fsck/fsck.c
new file mode 100644
index 0000000..4bc24ac
--- /dev/null
+++ b/sbin/fsck/fsck.c
@@ -0,0 +1,540 @@
+/* $NetBSD: fsck.c,v 1.21 1999/04/22 04:20:53 abs Exp $ */
+
+/*
+ * Copyright (c) 1996 Christos Zoulas. All rights reserved.
+ * Copyright (c) 1980, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From: @(#)mount.c 8.19 (Berkeley) 4/19/94
+ * From: NetBSD: mount.c,v 1.24 1995/11/18 03:34:29 cgd Exp
+ * $FreeBSD$
+ *
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: fsck.c,v 1.21 1999/04/22 04:20:53 abs Exp $");
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/queue.h>
+#include <sys/wait.h>
+#define FSTYPENAMES
+#define DKTYPENAMES
+#include <sys/disklabel.h>
+#include <sys/ioctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fstab.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+#include "fsutil.h"
+
+static enum { IN_LIST, NOT_IN_LIST } which = NOT_IN_LIST;
+
+TAILQ_HEAD(fstypelist, entry) opthead, selhead;
+
+struct entry {
+ char *type;
+ char *options;
+ TAILQ_ENTRY(entry) entries;
+};
+
+static int maxrun = 0;
+static char *options = NULL;
+static int flags = 0;
+
+int main __P((int, char *[]));
+
+static int checkfs __P((const char *, const char *, const char *, void *,
+ pid_t *));
+static int selected __P((const char *));
+static void addoption __P((char *));
+static const char *getoptions __P((const char *));
+static void addentry __P((struct fstypelist *, const char *, const char *));
+static void maketypelist __P((char *));
+static void catopt __P((char **, const char *));
+static void mangle __P((char *, int *, const char ***, int *));
+static const char *getfslab __P((const char *));
+static void usage __P((void));
+static void *isok __P((struct fstab *));
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ struct fstab *fs;
+ int i, rval = 0;
+ const char *vfstype = NULL;
+ char globopt[3];
+
+ globopt[0] = '-';
+ globopt[2] = '\0';
+
+ TAILQ_INIT(&selhead);
+ TAILQ_INIT(&opthead);
+
+ while ((i = getopt(argc, argv, "dvpfnyl:t:T:")) != -1)
+ switch (i) {
+ case 'd':
+ flags |= CHECK_DEBUG;
+ break;
+
+ case 'v':
+ flags |= CHECK_VERBOSE;
+ break;
+
+ case 'p':
+ flags |= CHECK_PREEN;
+ /*FALLTHROUGH*/
+ case 'n':
+ case 'f':
+ case 'y':
+ globopt[1] = i;
+ catopt(&options, globopt);
+ break;
+
+ case 'l':
+ maxrun = atoi(optarg);
+ break;
+
+ case 'T':
+ if (*optarg)
+ addoption(optarg);
+ break;
+
+ case 't':
+ if (selhead.tqh_first != NULL)
+ errx(1, "only one -t option may be specified.");
+
+ maketypelist(optarg);
+ vfstype = optarg;
+ break;
+
+ case '?':
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0)
+ return checkfstab(flags, maxrun, isok, checkfs);
+
+#define BADTYPE(type) \
+ (strcmp(type, FSTAB_RO) && \
+ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))
+
+
+ for (; argc--; argv++) {
+ const char *spec, *type, *cp;
+ char device[MAXPATHLEN];
+
+ spec = *argv;
+ cp = strrchr(spec, '/');
+ if (cp == 0) {
+ (void)snprintf(device, sizeof(device), "%s%s",
+ _PATH_DEV, spec);
+ spec = device;
+ }
+ if ((fs = getfsfile(spec)) == NULL &&
+ (fs = getfsspec(spec)) == NULL) {
+ if (vfstype == NULL)
+ vfstype = getfslab(spec);
+ type = vfstype;
+ }
+ else {
+ spec = fs->fs_spec;
+ type = fs->fs_vfstype;
+ if (BADTYPE(fs->fs_type))
+ errx(1, "%s has unknown file system type.",
+ spec);
+ }
+
+ rval |= checkfs(type, devcheck(spec), *argv, NULL, NULL);
+ }
+
+ return rval;
+}
+
+
+static void *
+isok(fs)
+ struct fstab *fs;
+{
+ if (fs->fs_passno == 0)
+ return NULL;
+
+ if (BADTYPE(fs->fs_type))
+ return NULL;
+
+ if (!selected(fs->fs_vfstype))
+ return NULL;
+
+ return fs;
+}
+
+
+static int
+checkfs(pvfstype, spec, mntpt, auxarg, pidp)
+ const char *pvfstype, *spec, *mntpt;
+ void *auxarg;
+ pid_t *pidp;
+{
+ /* List of directories containing fsck_xxx subcommands. */
+ static const char *edirs[] = {
+ _PATH_SBIN,
+ _PATH_USRSBIN,
+ NULL
+ };
+ const char **argv, **edir;
+ pid_t pid;
+ int argc, i, status, maxargc;
+ char *optbuf, execname[MAXPATHLEN + 1], execbase[MAXPATHLEN];
+ char *vfstype = NULL;
+ const char *extra = NULL;
+
+#ifdef __GNUC__
+ /* Avoid vfork clobbering */
+ (void) &optbuf;
+ (void) &vfstype;
+#endif
+ /*
+ * We convert the vfstype to lowercase and any spaces to underscores
+ * to not confuse the issue
+ */
+ vfstype = strdup(pvfstype);
+ if (vfstype == NULL)
+ perror("strdup(pvfstype)");
+ for (i = 0; i < strlen(vfstype); i++) {
+ vfstype[i] = tolower(vfstype[i]);
+ if (vfstype[i] == ' ')
+ vfstype[i] = '_';
+ }
+
+ extra = getoptions(vfstype);
+ optbuf = NULL;
+ if (options)
+ catopt(&optbuf, options);
+ if (extra)
+ catopt(&optbuf, extra);
+
+ maxargc = 64;
+ argv = emalloc(sizeof(char *) * maxargc);
+
+ (void) snprintf(execbase, sizeof(execbase), "fsck_%s", vfstype);
+ argc = 0;
+ argv[argc++] = execbase;
+ if (optbuf)
+ mangle(optbuf, &argc, &argv, &maxargc);
+ argv[argc++] = spec;
+ argv[argc] = NULL;
+
+ if (flags & (CHECK_DEBUG|CHECK_VERBOSE)) {
+ (void)printf("start %s %swait", mntpt,
+ pidp ? "no" : "");
+ for (i = 0; i < argc; i++)
+ (void)printf(" %s", argv[i]);
+ (void)printf("\n");
+ }
+
+ switch (pid = vfork()) {
+ case -1: /* Error. */
+ warn("vfork");
+ if (optbuf)
+ free(optbuf);
+ free(vfstype);
+ return (1);
+
+ case 0: /* Child. */
+ if (flags & CHECK_DEBUG)
+ _exit(0);
+
+ /* Go find an executable. */
+ edir = edirs;
+ do {
+ (void)snprintf(execname,
+ sizeof(execname), "%s/%s", *edir, execbase);
+ execv(execname, (char * const *)argv);
+ if (errno != ENOENT) {
+ if (spec)
+ warn("exec %s for %s", execname, spec);
+ else
+ warn("exec %s", execname);
+ }
+ } while (*++edir != NULL);
+
+ if (errno == ENOENT) {
+ if (spec)
+ warn("exec %s for %s", execname, spec);
+ else
+ warn("exec %s", execname);
+ }
+ _exit(1);
+ /* NOTREACHED */
+
+ default: /* Parent. */
+ if (optbuf)
+ free(optbuf);
+
+ free(vfstype);
+
+ if (pidp) {
+ *pidp = pid;
+ return 0;
+ }
+
+ if (waitpid(pid, &status, 0) < 0) {
+ warn("waitpid");
+ return (1);
+ }
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0)
+ return (WEXITSTATUS(status));
+ }
+ else if (WIFSIGNALED(status)) {
+ warnx("%s: %s", spec, strsignal(WTERMSIG(status)));
+ return (1);
+ }
+ break;
+ }
+
+ return (0);
+}
+
+
+static int
+selected(type)
+ const char *type;
+{
+ struct entry *e;
+
+ /* If no type specified, it's always selected. */
+ for (e = selhead.tqh_first; e != NULL; e = e->entries.tqe_next)
+ if (!strncmp(e->type, type, MFSNAMELEN))
+ return which == IN_LIST ? 1 : 0;
+
+ return which == IN_LIST ? 0 : 1;
+}
+
+
+static const char *
+getoptions(type)
+ const char *type;
+{
+ struct entry *e;
+
+ for (e = opthead.tqh_first; e != NULL; e = e->entries.tqe_next)
+ if (!strncmp(e->type, type, MFSNAMELEN))
+ return e->options;
+ return "";
+}
+
+
+static void
+addoption(optstr)
+ char *optstr;
+{
+ char *newoptions;
+ struct entry *e;
+
+ if ((newoptions = strchr(optstr, ':')) == NULL)
+ errx(1, "Invalid option string");
+
+ *newoptions++ = '\0';
+
+ for (e = opthead.tqh_first; e != NULL; e = e->entries.tqe_next)
+ if (!strncmp(e->type, optstr, MFSNAMELEN)) {
+ catopt(&e->options, newoptions);
+ return;
+ }
+ addentry(&opthead, optstr, newoptions);
+}
+
+
+static void
+addentry(list, type, opts)
+ struct fstypelist *list;
+ const char *type;
+ const char *opts;
+{
+ struct entry *e;
+
+ e = emalloc(sizeof(struct entry));
+ e->type = estrdup(type);
+ e->options = estrdup(opts);
+ TAILQ_INSERT_TAIL(list, e, entries);
+}
+
+
+static void
+maketypelist(fslist)
+ char *fslist;
+{
+ char *ptr;
+
+ if ((fslist == NULL) || (fslist[0] == '\0'))
+ errx(1, "empty type list");
+
+ if (fslist[0] == 'n' && fslist[1] == 'o') {
+ fslist += 2;
+ which = NOT_IN_LIST;
+ }
+ else
+ which = IN_LIST;
+
+ while ((ptr = strsep(&fslist, ",")) != NULL)
+ addentry(&selhead, ptr, "");
+
+}
+
+
+static void
+catopt(sp, o)
+ char **sp;
+ const char *o;
+{
+ char *s;
+ size_t i, j;
+
+ s = *sp;
+ if (s) {
+ i = strlen(s);
+ j = i + 1 + strlen(o) + 1;
+ s = erealloc(s, j);
+ (void)snprintf(s + i, j, ",%s", o);
+ } else
+ s = estrdup(o);
+ *sp = s;
+}
+
+
+static void
+mangle(options, argcp, argvp, maxargcp)
+ char *options;
+ int *argcp, *maxargcp;
+ const char ***argvp;
+{
+ char *p, *s;
+ int argc, maxargc;
+ const char **argv;
+
+ argc = *argcp;
+ argv = *argvp;
+ maxargc = *maxargcp;
+
+ for (s = options; (p = strsep(&s, ",")) != NULL;) {
+ /* Always leave space for one more argument and the NULL. */
+ if (argc >= maxargc - 3) {
+ maxargc <<= 1;
+ argv = erealloc(argv, maxargc * sizeof(char *));
+ }
+ if (*p != '\0') {
+ if (*p == '-') {
+ argv[argc++] = p;
+ p = strchr(p, '=');
+ if (p) {
+ *p = '\0';
+ argv[argc++] = p+1;
+ }
+ } else {
+ argv[argc++] = "-o";
+ argv[argc++] = p;
+ }
+ }
+ }
+
+ *argcp = argc;
+ *argvp = argv;
+ *maxargcp = maxargc;
+}
+
+
+const static char *
+getfslab(str)
+ const char *str;
+{
+ struct disklabel dl;
+ int fd;
+ char p;
+ const char *vfstype;
+ u_char t;
+
+ /* deduce the filesystem type from the disk label */
+ if ((fd = open(str, O_RDONLY)) == -1)
+ err(1, "cannot open `%s'", str);
+
+ if (ioctl(fd, DIOCGDINFO, &dl) == -1)
+ err(1, "cannot get disklabel for `%s'", str);
+
+ (void) close(fd);
+
+ p = str[strlen(str) - 1];
+
+ if ((p - 'a') >= dl.d_npartitions)
+ errx(1, "partition `%s' is not defined on disk", str);
+
+ if ((t = dl.d_partitions[p - 'a'].p_fstype) >= FSMAXTYPES)
+ errx(1, "partition `%s' is not of a legal vfstype",
+ str);
+
+ if ((vfstype = fstypenames[t]) == NULL)
+ errx(1, "vfstype `%s' on partition `%s' is not supported",
+ fstypenames[t], str);
+
+ return vfstype;
+}
+
+
+static void
+usage()
+{
+ extern char *__progname;
+ static const char common[] =
+ "[-dpvlyn] [-T fstype:fsoptions] [-t fstype]";
+
+ (void)fprintf(stderr, "Usage: %s %s [special|node]...\n",
+ __progname, common);
+ exit(1);
+}
diff --git a/sbin/fsck/fsck.h b/sbin/fsck/fsck.h
deleted file mode 100644
index f0280fe..0000000
--- a/sbin/fsck/fsck.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)fsck.h 8.4 (Berkeley) 5/9/95
- * $FreeBSD$
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define MAXDUP 10 /* limit on dup blks (per inode) */
-#define MAXBAD 10 /* limit on bad blks (per inode) */
-#define MAXBUFSPACE 40*1024 /* maximum space to allocate to buffers */
-#define INOBUFSIZE 56*1024 /* size of buffer to read inodes in pass1 */
-
-/*
- * Each inode on the filesystem is described by the following structure.
- * 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 FSTATE 02 /* inode is file */
-#define DSTATE 03 /* inode is directory */
-#define DFOUND 04 /* directory found during descent */
-#define DCLEAR 05 /* directory 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.
- */
-struct bufarea {
- struct bufarea *b_next; /* free list queue */
- struct bufarea *b_prev; /* free list queue */
- ufs_daddr_t b_bno;
- int b_size;
- int b_errs;
- int b_flags;
- union {
- char *b_buf; /* buffer space */
- ufs_daddr_t *b_indir; /* indirect block */
- struct fs *b_fs; /* super block */
- struct cg *b_cg; /* cylinder group */
- struct dinode *b_dinode; /* inode block */
- } b_un;
- char b_dirty;
-};
-
-#define B_INUSE 1
-
-#define MINBUFS 5 /* minimum number of buffers required */
-struct bufarea bufhead; /* head of list of other blks in filesys */
-struct bufarea sblk; /* file system superblock */
-struct bufarea cgblk; /* cylinder group blocks */
-struct bufarea *pdirbp; /* current directory contents */
-struct bufarea *pbp; /* current inode block */
-
-#define dirty(bp) (bp)->b_dirty = 1
-#define initbarea(bp) \
- (bp)->b_dirty = 0; \
- (bp)->b_bno = (ufs_daddr_t)-1; \
- (bp)->b_flags = 0;
-
-#define sbdirty() sblk.b_dirty = 1
-#define cgdirty() cgblk.b_dirty = 1
-#define sblock (*sblk.b_un.b_fs)
-#define cgrp (*cgblk.b_un.b_cg)
-
-enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
-ino_t cursnapshot;
-
-struct inodesc {
- enum fixstate id_fix; /* policy on fixing errors */
- int (*id_func)(); /* function to be applied to blocks of inode */
- ino_t id_number; /* inode number described */
- ino_t id_parent; /* for DATA nodes, their parent */
- int id_lbn; /* logical block number of current block */
- ufs_daddr_t id_blkno; /* current block number being examined */
- int id_numfrags; /* number of frags contained in block */
- quad_t id_filesize; /* for DATA nodes, the size of the directory */
- int id_loc; /* for DATA nodes, current location in dir */
- int id_entryno; /* for DATA nodes, current entry number */
- struct direct *id_dirp; /* for DATA nodes, ptr to current entry */
- char *id_name; /* for DATA nodes, name to find or enter */
- char id_type; /* type of descriptor, DATA or ADDR */
-};
-/* file types */
-#define DATA 1 /* a directory */
-#define SNAP 2 /* a snapshot */
-#define ADDR 3 /* anything but a directory or a snapshot */
-
-/*
- * Linked list of duplicate blocks.
- *
- * The list is composed of two parts. The first part of the
- * list (from duplist through the node pointed to by muldup)
- * contains a single copy of each duplicate block that has been
- * found. The second part of the list (from muldup to the end)
- * contains duplicate blocks that have been found more than once.
- * To check if a block has been found as a duplicate it is only
- * necessary to search from duplist through muldup. To find the
- * total number of times that a block has been found as a duplicate
- * the entire list must be searched for occurences of the block
- * in question. The following diagram shows a sample list where
- * w (found twice), x (found once), y (found three times), and z
- * (found once) are duplicate block numbers:
- *
- * w -> y -> x -> z -> y -> w -> y
- * ^ ^
- * | |
- * duplist muldup
- */
-struct dups {
- struct dups *next;
- ufs_daddr_t dup;
-};
-struct dups *duplist; /* head of dup list */
-struct dups *muldup; /* end of unique duplicate dup block numbers */
-
-/*
- * Linked list of inodes with zero link counts.
- */
-struct zlncnt {
- struct zlncnt *next;
- ino_t zlncnt;
-};
-struct zlncnt *zlnhead; /* head of zero link count list */
-
-/*
- * Inode cache data structures.
- */
-struct inoinfo {
- struct inoinfo *i_nexthash; /* next entry in hash chain */
- ino_t i_number; /* inode number of this entry */
- ino_t i_parent; /* inode number of parent */
- ino_t i_dotdot; /* inode number of `..' */
- size_t i_isize; /* size of inode */
- u_int i_numblks; /* size of block array in bytes */
- ufs_daddr_t i_blks[1]; /* actually longer */
-} **inphead, **inpsort;
-long numdirs, dirhash, listmax, inplast;
-long countdirs; /* number of directories we actually found */
-
-char *cdevname; /* name of device being checked */
-long dev_bsize; /* computed value of DEV_BSIZE */
-long secsize; /* actual disk sector size */
-char fflag; /* force check, ignore clean flag */
-char nflag; /* assume a no response */
-char yflag; /* assume a yes response */
-int bflag; /* location of alternate super block */
-int debug; /* output debugging info */
-int cvtlevel; /* convert to newer file system format */
-int doinglevel1; /* converting to new cylinder group format */
-int doinglevel2; /* converting to new inode format */
-int newinofmt; /* filesystem has new inode format */
-char usedsoftdep; /* just fix soft dependency 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 havesb; /* superblock has been read */
-int fsmodified; /* 1 => write done to file system */
-int fsreadfd; /* file descriptor for reading file system */
-int fswritefd; /* file descriptor for writing file system */
-
-ufs_daddr_t maxfsblock; /* number of blocks in the file system */
-char *blockmap; /* ptr to primary blk allocation map */
-ino_t maxino; /* number of inodes in file system */
-
-ino_t lfdir; /* lost & found directory inode number */
-char *lfname; /* lost & found directory name */
-int lfmode; /* lost & found directory creation mode */
-
-ufs_daddr_t n_blks; /* number of blocks in use */
-ufs_daddr_t n_files; /* number of files in use */
-
-#define clearinode(dp) (*(dp) = zino)
-struct dinode zino;
-
-#define setbmap(blkno) setbit(blockmap, blkno)
-#define testbmap(blkno) isset(blockmap, blkno)
-#define clrbmap(blkno) clrbit(blockmap, blkno)
-
-#define STOP 0x01
-#define SKIP 0x02
-#define KEEPON 0x04
-#define ALTERED 0x08
-#define FOUND 0x10
-
-#define EEXIT 8 /* Standard error exit. */
-
-struct fstab;
-
-
-void adjust __P((struct inodesc *, int lcnt));
-ufs_daddr_t allocblk __P((long frags));
-ino_t allocdir __P((ino_t parent, ino_t request, int mode));
-ino_t allocino __P((ino_t request, int type));
-void blkerror __P((ino_t ino, char *type, ufs_daddr_t blk));
-char *blockcheck __P((char *name));
-int bread __P((int fd, char *buf, ufs_daddr_t blk, long size));
-void bufinit __P((void));
-void bwrite __P((int fd, char *buf, ufs_daddr_t blk, long size));
-void cacheino __P((struct dinode *dp, ino_t inumber));
-void catch __P((int));
-void catchquit __P((int));
-int changeino __P((ino_t dir, char *name, ino_t newnum));
-int checkfstab __P((int preen, int maxrun,
- int (*docheck)(struct fstab *),
- int (*chkit)(char *, char *, long, int)));
-int chkrange __P((ufs_daddr_t blk, int cnt));
-void ckfini __P((int markclean));
-int ckinode __P((struct dinode *dp, struct inodesc *));
-void clri __P((struct inodesc *, char *type, int flag));
-int clearentry __P((struct inodesc *));
-void direrror __P((ino_t ino, char *errmesg));
-int dirscan __P((struct inodesc *));
-int dofix __P((struct inodesc *, char *msg));
-void ffs_clrblock __P((struct fs *, u_char *, ufs_daddr_t));
-void ffs_fragacct __P((struct fs *, int, int32_t [], int));
-int ffs_isblock __P((struct fs *, u_char *, ufs_daddr_t));
-void ffs_setblock __P((struct fs *, u_char *, ufs_daddr_t));
-void fileerror __P((ino_t cwd, ino_t ino, char *errmesg));
-int findino __P((struct inodesc *));
-int findname __P((struct inodesc *));
-void flush __P((int fd, struct bufarea *bp));
-void freeblk __P((ufs_daddr_t blkno, long frags));
-void freeino __P((ino_t ino));
-void freeinodebuf __P((void));
-int ftypeok __P((struct dinode *dp));
-void getblk __P((struct bufarea *bp, ufs_daddr_t blk, long size));
-struct bufarea *getdatablk __P((ufs_daddr_t blkno, long size));
-struct inoinfo *getinoinfo __P((ino_t inumber));
-struct dinode *getnextinode __P((ino_t inumber));
-void getpathname __P((char *namebuf, ino_t curdir, ino_t ino));
-struct dinode *ginode __P((ino_t inumber));
-void inocleanup __P((void));
-void inodirty __P((void));
-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));
-void panic __P((const char *fmt, ...));
-void pass1 __P((void));
-void pass1b __P((void));
-int pass1check __P((struct inodesc *));
-void pass2 __P((void));
-void pass3 __P((void));
-void pass4 __P((void));
-int pass4check __P((struct inodesc *));
-void pass5 __P((void));
-void pfatal __P((const char *fmt, ...));
-void pinode __P((ino_t ino));
-void propagate __P((void));
-void pwarn __P((const char *fmt, ...));
-int reply __P((char *question));
-void setinodebuf __P((ino_t));
-int setup __P((char *dev));
-void voidquit __P((int));
diff --git a/sbin/fsck/fsutil.c b/sbin/fsck/fsutil.c
new file mode 100644
index 0000000..f83c936
--- /dev/null
+++ b/sbin/fsck/fsutil.c
@@ -0,0 +1,363 @@
+/* $NetBSD: fsutil.c,v 1.7 1998/07/30 17:41:03 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: fsutil.c,v 1.7 1998/07/30 17:41:03 thorpej Exp $");
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include <errno.h>
+#include <fstab.h>
+#include <err.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "fsutil.h"
+
+static const char *dev = NULL;
+static int hot = 0;
+static int preen = 0;
+
+extern char *__progname;
+
+static void vmsg __P((int, const char *, va_list));
+
+void
+setcdevname(cd, pr)
+ const char *cd;
+ int pr;
+{
+ dev = cd;
+ preen = pr;
+}
+
+const char *
+cdevname()
+{
+ return dev;
+}
+
+int
+hotroot()
+{
+ return hot;
+}
+
+/*VARARGS*/
+void
+#if __STDC__
+errexit(const char *fmt, ...)
+#else
+errexit(va_alist)
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ const char *fmt;
+
+ va_start(ap);
+ fmt = va_arg(ap, const char *);
+#endif
+ (void) vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(8);
+}
+
+static void
+vmsg(fatal, fmt, ap)
+ int fatal;
+ const char *fmt;
+ va_list ap;
+{
+ if (!fatal && preen)
+ (void) printf("%s: ", dev);
+
+ (void) vprintf(fmt, ap);
+
+ if (fatal && preen)
+ (void) printf("\n");
+
+ if (fatal && preen) {
+ (void) printf(
+ "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
+ dev, __progname);
+ exit(8);
+ }
+}
+
+/*VARARGS*/
+void
+#if __STDC__
+pfatal(const char *fmt, ...)
+#else
+pfatal(va_alist)
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ const char *fmt;
+
+ va_start(ap);
+ fmt = va_arg(ap, const char *);
+#endif
+ vmsg(1, fmt, ap);
+ va_end(ap);
+}
+
+/*VARARGS*/
+void
+#if __STDC__
+pwarn(const char *fmt, ...)
+#else
+pwarn(va_alist)
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ const char *fmt;
+
+ va_start(ap);
+ fmt = va_arg(ap, const char *);
+#endif
+ vmsg(0, fmt, ap);
+ va_end(ap);
+}
+
+void
+perror(s)
+ const char *s;
+{
+ pfatal("%s (%s)", s, strerror(errno));
+}
+
+void
+#if __STDC__
+panic(const char *fmt, ...)
+#else
+panic(va_alist)
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ const char *fmt;
+
+ va_start(ap);
+ fmt = va_arg(ap, const char *);
+#endif
+ vmsg(1, fmt, ap);
+ va_end(ap);
+ exit(8);
+}
+
+const char *
+unrawname(name)
+ const char *name;
+{
+ static char unrawbuf[32];
+ const char *dp;
+ struct stat stb;
+
+ if ((dp = strrchr(name, '/')) == 0)
+ return (name);
+ if (stat(name, &stb) < 0)
+ return (name);
+ if (!S_ISCHR(stb.st_mode))
+ return (name);
+ if (dp[1] != 'r')
+ return (name);
+ (void)snprintf(unrawbuf, 32, "%.*s/%s", (int)(dp - name), name, dp + 2);
+ return (unrawbuf);
+}
+
+const char *
+rawname(name)
+ const char *name;
+{
+ static char rawbuf[32];
+ const char *dp;
+
+ if ((dp = strrchr(name, '/')) == 0)
+ return (0);
+ (void)snprintf(rawbuf, 32, "%.*s/r%s", (int)(dp - name), name, dp + 1);
+ return (rawbuf);
+}
+
+const char *
+devcheck(origname)
+ const char *origname;
+{
+ struct stat stslash, stchar;
+
+ if (stat("/", &stslash) < 0) {
+ perror("/");
+ printf("Can't stat root\n");
+ return (origname);
+ }
+ if (stat(origname, &stchar) < 0) {
+ perror(origname);
+ printf("Can't stat %s\n", origname);
+ return (origname);
+ }
+ if (!S_ISCHR(stchar.st_mode)) {
+ perror(origname);
+ printf("%s is not a char device\n", origname);
+ }
+ return (origname);
+}
+
+#if 0
+/*
+ * XXX this code is from NetBSD, but fails in FreeBSD because we
+ * don't have blockdevs. I don't think its needed.
+ */
+const char *
+blockcheck(origname)
+ const char *origname;
+{
+ struct stat stslash, stblock, stchar;
+ const char *newname, *raw;
+ struct fstab *fsp;
+ int retried = 0;
+
+ hot = 0;
+ if (stat("/", &stslash) < 0) {
+ perror("/");
+ printf("Can't stat root\n");
+ return (origname);
+ }
+ newname = origname;
+retry:
+ if (stat(newname, &stblock) < 0) {
+ perror(newname);
+ printf("Can't stat %s\n", newname);
+ return (origname);
+ }
+ if (S_ISBLK(stblock.st_mode)) {
+ if (stslash.st_dev == stblock.st_rdev)
+ hot++;
+ raw = rawname(newname);
+ if (stat(raw, &stchar) < 0) {
+ perror(raw);
+ printf("Can't stat %s\n", raw);
+ return (origname);
+ }
+ if (S_ISCHR(stchar.st_mode)) {
+ return (raw);
+ } else {
+ printf("%s is not a character device\n", raw);
+ return (origname);
+ }
+ } else if (S_ISCHR(stblock.st_mode) && !retried) {
+ newname = unrawname(newname);
+ retried++;
+ goto retry;
+ } else if ((fsp = getfsfile(newname)) != 0 && !retried) {
+ newname = fsp->fs_spec;
+ retried++;
+ goto retry;
+ }
+ /*
+ * Not a block or character device, just return name and
+ * let the user decide whether to use it.
+ */
+ return (origname);
+}
+#endif
+
+
+void *
+emalloc(s)
+ size_t s;
+{
+ void *p;
+
+ p = malloc(s);
+ if (p == NULL)
+ err(1, "malloc failed");
+ return (p);
+}
+
+
+void *
+erealloc(p, s)
+ void *p;
+ size_t s;
+{
+ void *q;
+
+ q = realloc(p, s);
+ if (q == NULL)
+ err(1, "realloc failed");
+ return (q);
+}
+
+
+char *
+estrdup(s)
+ const char *s;
+{
+ char *p;
+
+ p = strdup(s);
+ if (p == NULL)
+ err(1, "strdup failed");
+ return (p);
+}
diff --git a/sbin/fsck/fsutil.h b/sbin/fsck/fsutil.h
new file mode 100644
index 0000000..98c4506
--- /dev/null
+++ b/sbin/fsck/fsutil.h
@@ -0,0 +1,62 @@
+/* $NetBSD: fsutil.h,v 1.4 1998/07/26 20:02:36 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1996 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+void perror __P((const char *));
+void errexit __P((const char *, ...))
+ __attribute__((__noreturn__,__format__(__printf__,1,2)));
+void pfatal __P((const char *, ...))
+ __attribute__((__format__(__printf__,1,2)));
+void pwarn __P((const char *, ...))
+ __attribute__((__format__(__printf__,1,2)));
+void panic __P((const char *, ...))
+ __attribute__((__noreturn__,__format__(__printf__,1,2)));
+const char *rawname __P((const char *));
+const char *unrawname __P((const char *));
+#if 0
+const char *blockcheck __P((const char *));
+#endif
+const char *devcheck __P((const char *));
+const char *cdevname __P((void));
+void setcdevname __P((const char *, int));
+int hotroot __P((void));
+void *emalloc __P((size_t));
+void *erealloc __P((void *, size_t));
+char *estrdup __P((const char *));
+
+#define CHECK_PREEN 1
+#define CHECK_VERBOSE 2
+#define CHECK_DEBUG 4
+
+struct fstab;
+int checkfstab __P((int, int, void *(*)(struct fstab *),
+ int (*) (const char *, const char *, const char *, void *, pid_t *)));
diff --git a/sbin/fsck/inode.c b/sbin/fsck/inode.c
deleted file mode 100644
index 8b2f14b..0000000
--- a/sbin/fsck/inode.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/time.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <pwd.h>
-#include <string.h>
-
-#include "fsck.h"
-
-static ino_t startinum;
-
-static int iblock __P((struct inodesc *, long ilevel, quad_t isize));
-
-int
-ckinode(dp, idesc)
- struct dinode *dp;
- register struct inodesc *idesc;
-{
- ufs_daddr_t *ap;
- int ret;
- long n, ndb, offset;
- struct dinode dino;
- quad_t remsize, sizepb;
- mode_t mode;
- char pathbuf[MAXPATHLEN + 1];
-
- if (idesc->id_fix != IGNORE)
- idesc->id_fix = DONTKNOW;
- idesc->id_lbn = -1;
- idesc->id_entryno = 0;
- idesc->id_filesize = dp->di_size;
- mode = dp->di_mode & IFMT;
- if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
- dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
- return (KEEPON);
- dino = *dp;
- ndb = howmany(dino.di_size, sblock.fs_bsize);
- for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
- idesc->id_lbn++;
- if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
- idesc->id_numfrags =
- numfrags(&sblock, fragroundup(&sblock, offset));
- else
- idesc->id_numfrags = sblock.fs_frag;
- if (*ap == 0) {
- if (idesc->id_type == DATA && ndb >= 0) {
- /* An empty block in a directory XXX */
- getpathname(pathbuf, idesc->id_number,
- idesc->id_number);
- pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
- pathbuf);
- if (reply("ADJUST LENGTH") == 1) {
- dp = ginode(idesc->id_number);
- dp->di_size = (ap - &dino.di_db[0]) *
- sblock.fs_bsize;
- printf(
- "YOU MUST RERUN FSCK AFTERWARDS\n");
- rerun = 1;
- inodirty();
-
- }
- }
- continue;
- }
- idesc->id_blkno = *ap;
- if (idesc->id_type != DATA)
- ret = (*idesc->id_func)(idesc);
- else
- ret = dirscan(idesc);
- if (ret & STOP)
- return (ret);
- }
- idesc->id_numfrags = sblock.fs_frag;
- remsize = dino.di_size - sblock.fs_bsize * NDADDR;
- sizepb = sblock.fs_bsize;
- for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
- sizepb *= NINDIR(&sblock);
- if (*ap) {
- idesc->id_blkno = *ap;
- ret = iblock(idesc, n, remsize);
- if (ret & STOP)
- return (ret);
- } else {
- idesc->id_lbn += sizepb / sblock.fs_bsize;
- if (idesc->id_type == DATA && remsize > 0) {
- /* An empty block in a directory XXX */
- getpathname(pathbuf, idesc->id_number,
- idesc->id_number);
- pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
- pathbuf);
- if (reply("ADJUST LENGTH") == 1) {
- dp = ginode(idesc->id_number);
- dp->di_size -= remsize;
- remsize = 0;
- printf(
- "YOU MUST RERUN FSCK AFTERWARDS\n");
- rerun = 1;
- inodirty();
- break;
- }
- }
- }
- remsize -= sizepb;
- }
- return (KEEPON);
-}
-
-static int
-iblock(idesc, ilevel, isize)
- struct inodesc *idesc;
- long ilevel;
- quad_t isize;
-{
- ufs_daddr_t *ap;
- ufs_daddr_t *aplim;
- struct bufarea *bp;
- int i, n, (*func)(), nif;
- quad_t sizepb;
- char buf[BUFSIZ];
- char pathbuf[MAXPATHLEN + 1];
- struct dinode *dp;
-
- if (idesc->id_type != DATA) {
- func = idesc->id_func;
- if (((n = (*func)(idesc)) & KEEPON) == 0)
- return (n);
- } else
- func = dirscan;
- if (chkrange(idesc->id_blkno, idesc->id_numfrags))
- return (SKIP);
- bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
- ilevel--;
- for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
- sizepb *= NINDIR(&sblock);
- nif = howmany(isize , sizepb);
- if (nif > NINDIR(&sblock))
- nif = NINDIR(&sblock);
- if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
- aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
- for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
- if (*ap == 0)
- continue;
- (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
- (u_long)idesc->id_number);
- if (dofix(idesc, buf)) {
- *ap = 0;
- dirty(bp);
- }
- }
- flush(fswritefd, bp);
- }
- aplim = &bp->b_un.b_indir[nif];
- for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
- if (ilevel == 0)
- idesc->id_lbn++;
- if (*ap) {
- idesc->id_blkno = *ap;
- if (ilevel == 0)
- n = (*func)(idesc);
- else
- n = iblock(idesc, ilevel, isize);
- if (n & STOP) {
- bp->b_flags &= ~B_INUSE;
- return (n);
- }
- } else {
- if (idesc->id_type == DATA && isize > 0) {
- /* An empty block in a directory XXX */
- getpathname(pathbuf, idesc->id_number,
- idesc->id_number);
- pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
- pathbuf);
- if (reply("ADJUST LENGTH") == 1) {
- dp = ginode(idesc->id_number);
- dp->di_size -= isize;
- isize = 0;
- printf(
- "YOU MUST RERUN FSCK AFTERWARDS\n");
- rerun = 1;
- inodirty();
- bp->b_flags &= ~B_INUSE;
- return(STOP);
- }
- }
- }
- isize -= sizepb;
- }
- bp->b_flags &= ~B_INUSE;
- return (KEEPON);
-}
-
-/*
- * Check that a block in a legal block number.
- * Return 0 if in range, 1 if out of range.
- */
-int
-chkrange(blk, cnt)
- ufs_daddr_t blk;
- int cnt;
-{
- register int c;
-
- if (cnt <= 0 || blk <= 0 || blk > maxfsblock ||
- cnt - 1 > maxfsblock - blk)
- 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);
- if (blk < cgdmin(&sblock, c)) {
- if ((blk + cnt) > cgsblock(&sblock, c)) {
- if (debug) {
- printf("blk %ld < cgdmin %ld;",
- (long)blk, (long)cgdmin(&sblock, c));
- printf(" blk + cnt %ld > cgsbase %ld\n",
- (long)(blk + cnt),
- (long)cgsblock(&sblock, c));
- }
- return (1);
- }
- } else {
- if ((blk + cnt) > cgbase(&sblock, c+1)) {
- if (debug) {
- printf("blk %ld >= cgdmin %ld;",
- (long)blk, (long)cgdmin(&sblock, c));
- printf(" blk + cnt %ld > sblock.fs_fpg %ld\n",
- (long)(blk + cnt), (long)sblock.fs_fpg);
- }
- return (1);
- }
- }
- return (0);
-}
-
-/*
- * General purpose interface for reading inodes.
- */
-struct dinode *
-ginode(inumber)
- ino_t inumber;
-{
- ufs_daddr_t iblk;
-
- if (inumber < ROOTINO || inumber > maxino)
- errx(EEXIT, "bad inode number %d to ginode", inumber);
- if (startinum == 0 ||
- inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
- iblk = ino_to_fsba(&sblock, inumber);
- if (pbp != 0)
- pbp->b_flags &= ~B_INUSE;
- pbp = getdatablk(iblk, sblock.fs_bsize);
- startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
- }
- return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
-}
-
-/*
- * Special purpose version of ginode used to optimize first pass
- * over all the inodes in numerical order.
- */
-ino_t nextino, lastinum, lastvalidinum;
-long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-struct dinode *inodebuf;
-
-struct dinode *
-getnextinode(inumber)
- ino_t inumber;
-{
- long size;
- ufs_daddr_t dblk;
- static struct dinode *dp;
-
- if (inumber != nextino++ || inumber > lastvalidinum)
- errx(EEXIT, "bad inode number %d to nextinode", inumber);
- if (inumber >= lastinum) {
- readcnt++;
- dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
- if (readcnt % readpercg == 0) {
- size = partialsize;
- lastinum += partialcnt;
- } else {
- size = inobufsize;
- lastinum += fullcnt;
- }
- /*
- * 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;
- }
- return (dp++);
-}
-
-void
-setinodebuf(inum)
- ino_t inum;
-{
-
- if (inum % sblock.fs_ipg != 0)
- errx(EEXIT, "bad inode number %d to setinodebuf", inum);
- lastvalidinum = inum + sblock.fs_ipg - 1;
- startinum = 0;
- nextino = inum;
- lastinum = inum;
- readcnt = 0;
- if (inodebuf != NULL)
- return;
- inobufsize = blkroundup(&sblock, INOBUFSIZE);
- fullcnt = inobufsize / sizeof(struct dinode);
- readpercg = sblock.fs_ipg / fullcnt;
- partialcnt = sblock.fs_ipg % fullcnt;
- partialsize = partialcnt * sizeof(struct dinode);
- if (partialcnt != 0) {
- readpercg++;
- } else {
- partialcnt = fullcnt;
- partialsize = inobufsize;
- }
- if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
- errx(EEXIT, "cannot allocate space for inode buffer");
-}
-
-void
-freeinodebuf()
-{
-
- if (inodebuf != NULL)
- free((char *)inodebuf);
- inodebuf = NULL;
-}
-
-/*
- * Routines to maintain information about directory inodes.
- * This is built during the first pass and used during the
- * second and third passes.
- *
- * Enter inodes into the cache.
- */
-void
-cacheino(dp, inumber)
- register struct dinode *dp;
- ino_t inumber;
-{
- register struct inoinfo *inp;
- struct inoinfo **inpp;
- int blks;
-
- blks = howmany(dp->di_size, sblock.fs_bsize);
- if (blks > NDADDR)
- blks = NDADDR + NIADDR;
- inp = (struct inoinfo *)
- malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
- if (inp == NULL)
- errx(EEXIT, "cannot increase directory list");
- inpp = &inphead[inumber % dirhash];
- inp->i_nexthash = *inpp;
- *inpp = inp;
- inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
- inp->i_dotdot = (ino_t)0;
- inp->i_number = inumber;
- inp->i_isize = dp->di_size;
- inp->i_numblks = blks * sizeof(ufs_daddr_t);
- memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks);
- if (inplast == listmax) {
- listmax += 100;
- inpsort = (struct inoinfo **)realloc((char *)inpsort,
- (unsigned)listmax * sizeof(struct inoinfo *));
- if (inpsort == NULL)
- errx(EEXIT, "cannot increase directory list");
- }
- inpsort[inplast++] = inp;
-}
-
-/*
- * Look up an inode cache structure.
- */
-struct inoinfo *
-getinoinfo(inumber)
- ino_t inumber;
-{
- register struct inoinfo *inp;
-
- for (inp = inphead[inumber % dirhash]; inp; inp = inp->i_nexthash) {
- if (inp->i_number != inumber)
- continue;
- return (inp);
- }
- errx(EEXIT, "cannot find inode %d", inumber);
- return ((struct inoinfo *)0);
-}
-
-/*
- * Clean up all the inode cache structure.
- */
-void
-inocleanup()
-{
- register struct inoinfo **inpp;
-
- if (inphead == NULL)
- return;
- for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
- free((char *)(*inpp));
- free((char *)inphead);
- free((char *)inpsort);
- inphead = inpsort = NULL;
-}
-
-void
-inodirty()
-{
-
- dirty(pbp);
-}
-
-void
-clri(idesc, type, flag)
- register struct inodesc *idesc;
- char *type;
- int flag;
-{
- register struct dinode *dp;
-
- dp = ginode(idesc->id_number);
- if (flag == 1) {
- pwarn("%s %s", type,
- (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
- pinode(idesc->id_number);
- }
- if (preen || reply("CLEAR") == 1) {
- if (preen)
- printf(" (CLEARED)\n");
- n_files--;
- (void)ckinode(dp, idesc);
- clearinode(dp);
- inoinfo(idesc->id_number)->ino_state = USTATE;
- inodirty();
- }
-}
-
-int
-findname(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);
- }
- memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
- return (STOP|FOUND);
-}
-
-int
-findino(idesc)
- struct inodesc *idesc;
-{
- register struct direct *dirp = idesc->id_dirp;
-
- if (dirp->d_ino == 0)
- return (KEEPON);
- if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
- dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) {
- idesc->id_parent = dirp->d_ino;
- return (STOP|FOUND);
- }
- 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
-pinode(ino)
- ino_t ino;
-{
- register struct dinode *dp;
- register char *p;
- struct passwd *pw;
- time_t t;
-
- printf(" I=%lu ", (u_long)ino);
- if (ino < ROOTINO || ino > maxino)
- return;
- dp = ginode(ino);
- printf(" OWNER=");
- if ((pw = getpwuid((int)dp->di_uid)) != 0)
- printf("%s ", pw->pw_name);
- else
- printf("%u ", (unsigned)dp->di_uid);
- printf("MODE=%o\n", dp->di_mode);
- if (preen)
- printf("%s: ", cdevname);
- printf("SIZE=%qu ", dp->di_size);
- t = dp->di_mtime;
- p = ctime(&t);
- printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
-}
-
-void
-blkerror(ino, type, blk)
- ino_t ino;
- char *type;
- ufs_daddr_t blk;
-{
-
- pfatal("%ld %s I=%lu", blk, type, ino);
- printf("\n");
- switch (inoinfo(ino)->ino_state) {
-
- case FSTATE:
- inoinfo(ino)->ino_state = FCLEAR;
- return;
-
- case DSTATE:
- inoinfo(ino)->ino_state = DCLEAR;
- return;
-
- case FCLEAR:
- case DCLEAR:
- return;
-
- default:
- errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state);
- /* NOTREACHED */
- }
-}
-
-/*
- * allocate an unused inode
- */
-ino_t
-allocino(request, type)
- ino_t request;
- int type;
-{
- register ino_t ino;
- register struct dinode *dp;
- struct cg *cgp = &cgrp;
- int cg;
-
- if (request == 0)
- request = ROOTINO;
- else if (inoinfo(request)->ino_state != USTATE)
- return (0);
- for (ino = request; ino < maxino; ino++)
- if (inoinfo(ino)->ino_state == USTATE)
- break;
- if (ino == maxino)
- return (0);
- cg = ino_to_cg(&sblock, ino);
- getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
- if (!cg_chkmagic(cgp))
- pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
- setbit(cg_inosused(cgp), ino % sblock.fs_ipg);
- cgp->cg_cs.cs_nifree--;
- switch (type & IFMT) {
- case IFDIR:
- inoinfo(ino)->ino_state = DSTATE;
- cgp->cg_cs.cs_ndir++;
- break;
- case IFREG:
- case IFLNK:
- inoinfo(ino)->ino_state = FSTATE;
- break;
- default:
- return (0);
- }
- cgdirty();
- dp = ginode(ino);
- dp->di_db[0] = allocblk((long)1);
- if (dp->di_db[0] == 0) {
- inoinfo(ino)->ino_state = USTATE;
- return (0);
- }
- dp->di_mode = type;
- dp->di_flags = 0;
- dp->di_atime = time(NULL);
- dp->di_mtime = dp->di_ctime = dp->di_atime;
- dp->di_mtimensec = dp->di_ctimensec = dp->di_atimensec = 0;
- dp->di_size = sblock.fs_fsize;
- dp->di_blocks = btodb(sblock.fs_fsize);
- n_files++;
- inodirty();
- if (newinofmt)
- inoinfo(ino)->ino_type = IFTODT(type);
- return (ino);
-}
-
-/*
- * deallocate an inode
- */
-void
-freeino(ino)
- ino_t ino;
-{
- struct inodesc idesc;
- struct dinode *dp;
-
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = ADDR;
- idesc.id_func = pass4check;
- idesc.id_number = ino;
- dp = ginode(ino);
- (void)ckinode(dp, &idesc);
- clearinode(dp);
- inodirty();
- inoinfo(ino)->ino_state = USTATE;
- n_files--;
-}
diff --git a/sbin/fsck/main.c b/sbin/fsck/main.c
deleted file mode 100644
index 6463990..0000000
--- a/sbin/fsck/main.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1980, 1986, 1993\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/mount.h>
-#include <sys/resource.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fstab.h>
-#include <paths.h>
-
-#include "fsck.h"
-
-static int argtoi __P((int flag, char *req, char *str, int base));
-static int docheck __P((struct fstab *fsp));
-static int checkfilesys __P((char *filesys, char *mntpt, long auxdata,
- int child));
-static struct statfs *getmntpt __P((const char *));
-int main __P((int argc, char *argv[]));
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int ch;
- int ret, maxrun = 0;
- struct rlimit rlimit;
-
- sync();
- while ((ch = getopt(argc, argv, "dfpnNyYb:c:l:m:")) != -1) {
- switch (ch) {
- case 'p':
- preen++;
- break;
-
- case 'b':
- bflag = argtoi('b', "number", optarg, 10);
- printf("Alternate super block location: %d\n", bflag);
- break;
-
- case 'c':
- cvtlevel = argtoi('c', "conversion level", optarg, 10);
- break;
-
- case 'd':
- debug++;
- break;
-
- case 'f':
- fflag++;
- break;
-
- case 'l':
- maxrun = argtoi('l', "number", optarg, 10);
- break;
-
- case 'm':
- lfmode = argtoi('m', "mode", optarg, 8);
- if (lfmode &~ 07777)
- errx(EEXIT, "bad mode to -m: %o", lfmode);
- printf("** lost+found creation mode %o\n", lfmode);
- break;
-
- case 'n':
- case 'N':
- nflag++;
- yflag = 0;
- break;
-
- case 'y':
- case 'Y':
- yflag++;
- nflag = 0;
- break;
-
- default:
- errx(EEXIT, "%c option?", ch);
- }
- }
- argc -= optind;
- argv += optind;
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void)signal(SIGINT, catch);
- if (preen)
- (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) {
- while (argc-- > 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);
- }
- ret = checkfstab(preen, maxrun, docheck, checkfilesys);
- if (returntosingle)
- exit(2);
- exit(ret);
-}
-
-static int
-argtoi(flag, req, str, base)
- int flag;
- char *req, *str;
- int base;
-{
- char *cp;
- int ret;
-
- ret = (int)strtol(str, &cp, base);
- if (cp == str || *cp)
- errx(EEXIT, "-%c flag requires a %s", flag, req);
- return (ret);
-}
-
-/*
- * Determine whether a filesystem should be checked.
- */
-static int
-docheck(fsp)
- register struct fstab *fsp;
-{
-
- if (strcmp(fsp->fs_vfstype, "ufs") ||
- (strcmp(fsp->fs_type, FSTAB_RW) &&
- strcmp(fsp->fs_type, FSTAB_RO)) ||
- fsp->fs_passno == 0)
- return (0);
- return (1);
-}
-
-/*
- * Check the specified filesystem.
- */
-/* ARGSUSED */
-static int
-checkfilesys(filesys, mntpt, auxdata, child)
- char *filesys, *mntpt;
- long auxdata;
- int child;
-{
- ufs_daddr_t n_ffree, n_bfree;
- struct dups *dp;
- struct statfs *mntbuf;
- struct zlncnt *zlnp;
- int cylno;
-
- if (preen && child)
- (void)signal(SIGQUIT, voidquit);
- cdevname = filesys;
- if (debug && preen)
- pwarn("starting\n");
- switch (setup(filesys)) {
- case 0:
- if (preen)
- pfatal("CAN'T CHECK FILE SYSTEM.");
- return (0);
- 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);
- }
-
- /*
- * Get the mount point information of the filesystem, if
- * it is available.
- */
- mntbuf = getmntpt(filesys);
-
- /*
- * Cleared if any questions answered no. Used to decide if
- * the superblock should be marked clean.
- */
- resolved = 1;
- /*
- * 1: scan inodes tallying blocks used
- */
- if (preen == 0) {
- printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
- if (mntbuf != NULL && mntbuf->f_flags & MNT_ROOTFS)
- printf("** Root file system\n");
- printf("** Phase 1 - Check Blocks and Sizes\n");
- }
- pass1();
-
- /*
- * 1b: locate first references to duplicates, if any
- */
- if (duplist) {
- if (preen || usedsoftdep)
- pfatal("INTERNAL ERROR: dups with -p");
- printf("** Phase 1b - Rescan For More DUPS\n");
- pass1b();
- }
-
- /*
- * 2: traverse directories from root to mark all connected directories
- */
- if (preen == 0)
- printf("** Phase 2 - Check Pathnames\n");
- pass2();
-
- /*
- * 3: scan inodes looking for disconnected directories
- */
- if (preen == 0)
- printf("** Phase 3 - Check Connectivity\n");
- pass3();
-
- /*
- * 4: scan inodes looking for disconnected files; check reference counts
- */
- if (preen == 0)
- printf("** Phase 4 - Check Reference Counts\n");
- pass4();
-
- /*
- * 5: check and repair resource counts in cylinder groups
- */
- if (preen == 0)
- printf("** Phase 5 - Check Cyl groups\n");
- pass5();
-
- /*
- * print out summary statistics
- */
- n_ffree = sblock.fs_cstotal.cs_nffree;
- n_bfree = sblock.fs_cstotal.cs_nbfree;
- pwarn("%ld files, %ld used, %ld free ",
- n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
- printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",
- n_ffree, n_bfree, n_ffree * 100.0 / sblock.fs_dsize);
- if (debug &&
- (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
- printf("%d files missing\n", n_files);
- if (debug) {
- n_blks += sblock.fs_ncg *
- (cgdmin(&sblock, 0) - cgsblock(&sblock, 0));
- n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0);
- n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize);
- if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree))
- printf("%d blocks missing\n", n_blks);
- if (duplist != NULL) {
- printf("The following duplicate blocks remain:");
- for (dp = duplist; dp; dp = dp->next)
- printf(" %d,", dp->dup);
- printf("\n");
- }
- if (zlnhead != NULL) {
- printf("The following zero link count inodes remain:");
- for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
- printf(" %u,", zlnp->zlncnt);
- printf("\n");
- }
- }
- zlnhead = (struct zlncnt *)0;
- duplist = (struct dups *)0;
- muldup = (struct dups *)0;
- inocleanup();
- if (fsmodified) {
- sblock.fs_time = time(NULL);
- sbdirty();
- }
- if (cvtlevel && sblk.b_dirty) {
- /*
- * Write out the duplicate super blocks
- */
- for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
- bwrite(fswritefd, (char *)&sblock,
- fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
- }
- if (rerun)
- resolved = 0;
-
- /*
- * Check to see if the filesystem is mounted read-write.
- */
- if (mntbuf != NULL && (mntbuf->f_flags & MNT_RDONLY) == 0)
- resolved = 0;
- ckfini(resolved);
-
- for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
- if (inostathead[cylno].il_stat != NULL)
- free((char *)inostathead[cylno].il_stat);
- free((char *)inostathead);
- inostathead = NULL;
- if (fsmodified && !preen)
- printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
- if (rerun)
- printf("\n***** PLEASE RERUN FSCK *****\n");
- if (mntbuf != NULL) {
- struct ufs_args args;
- int ret;
- /*
- * We modified a mounted filesystem. Do a mount update on
- * it unless it is read-write, so we can continue using it
- * as safely as possible.
- */
- if (mntbuf->f_flags & MNT_RDONLY) {
- args.fspec = 0;
- args.export.ex_flags = 0;
- args.export.ex_root = 0;
- ret = mount("ufs", mntbuf->f_mntonname,
- mntbuf->f_flags | MNT_UPDATE | MNT_RELOAD, &args);
- if (ret == 0)
- return (0);
- pwarn("mount reload of '%s' failed: %s\n\n",
- mntbuf->f_mntonname, strerror(errno));
- }
- if (!fsmodified)
- return (0);
- if (!preen)
- printf("\n***** REBOOT NOW *****\n");
- sync();
- return (4);
- }
- return (0);
-}
-
-/*
- * Get the directory that the device is mounted on.
- */
-static struct statfs *
-getmntpt(name)
- const char *name;
-{
- struct stat devstat, mntdevstat;
- char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
- char *devname;
- struct statfs *mntbuf;
- int i, mntsize;
-
- if (stat(name, &devstat) != 0 ||
- !(S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode)))
- return (NULL);
- mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
- for (i = 0; i < mntsize; i++) {
- if (strcmp(mntbuf[i].f_fstypename, "ufs") != 0)
- continue;
- devname = mntbuf[i].f_mntfromname;
- if (*devname != '/') {
- strcpy(device, _PATH_DEV);
- strcat(device, devname);
- devname = device;
- }
- if (stat(devname, &mntdevstat) == 0 &&
- mntdevstat.st_rdev == devstat.st_rdev)
- return (&mntbuf[i]);
- }
- return (NULL);
-}
diff --git a/sbin/fsck/pass1.c b/sbin/fsck/pass1.c
deleted file mode 100644
index fcd596b..0000000
--- a/sbin/fsck/pass1.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-static ufs_daddr_t badblk;
-static ufs_daddr_t dupblk;
-static ino_t lastino; /* last inode in use */
-
-static void checkinode __P((ino_t inumber, struct inodesc *));
-
-void
-pass1()
-{
- u_int8_t *cp;
- ino_t inumber;
- int c, i, cgd, inosused;
- struct inostat *info;
- struct inodesc idesc;
-
- /*
- * Set file system reserved blocks in used block map.
- */
- for (c = 0; c < sblock.fs_ncg; c++) {
- cgd = cgdmin(&sblock, c);
- if (c == 0) {
- i = cgbase(&sblock, c);
- cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
- } else
- i = cgsblock(&sblock, c);
- for (; i < cgd; i++)
- setbmap(i);
- }
- /*
- * Find all allocated blocks.
- */
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_func = pass1check;
- n_files = n_blks = 0;
- for (c = 0; c < sblock.fs_ncg; c++) {
- inumber = c * sblock.fs_ipg;
- 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;
- }
- 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();
-}
-
-static void
-checkinode(inumber, idesc)
- ino_t inumber;
- register struct inodesc *idesc;
-{
- register struct dinode *dp;
- struct zlncnt *zlnp;
- int ndb, j;
- mode_t mode;
- char *symbuf;
-
- dp = getnextinode(inumber);
- mode = dp->di_mode & IFMT;
- if (mode == 0) {
- if (memcmp(dp->di_db, zino.di_db,
- NDADDR * sizeof(ufs_daddr_t)) ||
- memcmp(dp->di_ib, zino.di_ib,
- NIADDR * sizeof(ufs_daddr_t)) ||
- dp->di_mode || dp->di_size) {
- pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
- if (reply("CLEAR") == 1) {
- dp = ginode(inumber);
- clearinode(dp);
- inodirty();
- }
- }
- inoinfo(inumber)->ino_state = USTATE;
- return;
- }
- lastino = inumber;
- if (/* dp->di_size < 0 || */
- dp->di_size + sblock.fs_bsize - 1 < dp->di_size ||
- (mode == IFDIR && dp->di_size > MAXDIRSIZE)) {
- if (debug)
- printf("bad size %qu:", dp->di_size);
- goto unknown;
- }
- if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
- dp = ginode(inumber);
- dp->di_size = sblock.fs_fsize;
- dp->di_mode = IFREG|0600;
- inodirty();
- }
- if ((mode == IFBLK || mode == IFCHR || mode == IFIFO ||
- mode == IFSOCK) && dp->di_size != 0) {
- if (debug)
- printf("bad special-file size %qu:", dp->di_size);
- goto unknown;
- }
- ndb = howmany(dp->di_size, sblock.fs_bsize);
- if (ndb < 0) {
- if (debug)
- printf("bad size %qu ndb %d:",
- dp->di_size, ndb);
- goto unknown;
- }
- if (mode == IFBLK || mode == IFCHR)
- ndb++;
- if (mode == IFLNK) {
- if (doinglevel2 &&
- dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN &&
- dp->di_blocks != 0) {
- symbuf = alloca(secsize);
- if (bread(fsreadfd, symbuf,
- fsbtodb(&sblock, dp->di_db[0]),
- (long)secsize) != 0)
- errx(EEXIT, "cannot read symlink");
- if (debug) {
- symbuf[dp->di_size] = 0;
- printf("convert symlink %lu(%s) of size %ld\n",
- (u_long)inumber, symbuf, (long)dp->di_size);
- }
- dp = ginode(inumber);
- memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
- dp->di_blocks = 0;
- inodirty();
- }
- /*
- * Fake ndb value so direct/indirect block checks below
- * will detect any garbage after symlink string.
- */
- if (dp->di_size < sblock.fs_maxsymlinklen) {
- ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
- if (ndb > NDADDR) {
- j = ndb - NDADDR;
- for (ndb = 1; j > 1; j--)
- ndb *= NINDIR(&sblock);
- ndb += NDADDR;
- }
- }
- }
- for (j = ndb; j < NDADDR; j++)
- if (dp->di_db[j] != 0) {
- if (debug)
- printf("bad direct addr: %ld\n",
- (long)dp->di_db[j]);
- goto unknown;
- }
- for (j = 0, ndb -= NDADDR; ndb > 0; j++)
- ndb /= NINDIR(&sblock);
- for (; j < NIADDR; j++)
- if (dp->di_ib[j] != 0) {
- if (debug)
- printf("bad indirect addr: %ld\n",
- (long)dp->di_ib[j]);
- goto unknown;
- }
- if (ftypeok(dp) == 0)
- goto unknown;
- n_files++;
- inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
- if (dp->di_nlink <= 0) {
- zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
- if (zlnp == NULL) {
- pfatal("LINK COUNT TABLE OVERFLOW");
- if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- } else {
- zlnp->zlncnt = inumber;
- zlnp->next = zlnhead;
- zlnhead = zlnp;
- }
- }
- if (mode == IFDIR) {
- if (dp->di_size == 0)
- inoinfo(inumber)->ino_state = DCLEAR;
- else
- inoinfo(inumber)->ino_state = DSTATE;
- cacheino(dp, inumber);
- countdirs++;
- } else
- inoinfo(inumber)->ino_state = FSTATE;
- inoinfo(inumber)->ino_type = IFTODT(mode);
- if (doinglevel2 &&
- (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
- dp = ginode(inumber);
- dp->di_uid = dp->di_ouid;
- dp->di_ouid = -1;
- dp->di_gid = dp->di_ogid;
- dp->di_ogid = -1;
- inodirty();
- }
- badblk = dupblk = 0;
- idesc->id_number = inumber;
- if (dp->di_flags & SF_SNAPSHOT)
- idesc->id_type = SNAP;
- else
- idesc->id_type = ADDR;
- (void)ckinode(dp, idesc);
- idesc->id_entryno *= btodb(sblock.fs_fsize);
- if (dp->di_blocks != idesc->id_entryno) {
- pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
- inumber, dp->di_blocks, idesc->id_entryno);
- if (preen)
- printf(" (CORRECTED)\n");
- else if (reply("CORRECT") == 0)
- return;
- dp = ginode(inumber);
- dp->di_blocks = idesc->id_entryno;
- inodirty();
- }
- return;
-unknown:
- pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
- inoinfo(inumber)->ino_state = FCLEAR;
- if (reply("CLEAR") == 1) {
- inoinfo(inumber)->ino_state = USTATE;
- dp = ginode(inumber);
- clearinode(dp);
- inodirty();
- }
-}
-
-int
-pass1check(idesc)
- register struct inodesc *idesc;
-{
- int res = KEEPON;
- int anyout, nfrags;
- ufs_daddr_t blkno = idesc->id_blkno;
- register struct dups *dlp;
- struct dups *new;
-
- if (idesc->id_type == SNAP) {
- if (blkno == BLK_NOCOPY)
- return (KEEPON);
- if (idesc->id_number == cursnapshot) {
- if (blkno == blkstofrags(&sblock, idesc->id_lbn))
- return (KEEPON);
- if (blkno == BLK_SNAP) {
- blkno = blkstofrags(&sblock, idesc->id_lbn);
- idesc->id_entryno -= idesc->id_numfrags;
- }
- } else {
- if (blkno == BLK_SNAP)
- return (KEEPON);
- }
- }
- if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
- blkerror(idesc->id_number, "BAD", blkno);
- if (badblk++ >= MAXBAD) {
- pwarn("EXCESSIVE BAD BLKS I=%lu",
- idesc->id_number);
- if (preen)
- printf(" (SKIPPING)\n");
- else if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- return (STOP);
- }
- }
- for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
- if (anyout && chkrange(blkno, 1)) {
- res = SKIP;
- } else if (!testbmap(blkno)) {
- n_blks++;
- setbmap(blkno);
- } else {
- blkerror(idesc->id_number, "DUP", blkno);
- if (dupblk++ >= MAXDUP) {
- pwarn("EXCESSIVE DUP BLKS I=%lu",
- idesc->id_number);
- if (preen)
- printf(" (SKIPPING)\n");
- else if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- return (STOP);
- }
- new = (struct dups *)malloc(sizeof(struct dups));
- if (new == NULL) {
- pfatal("DUP TABLE OVERFLOW.");
- if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- return (STOP);
- }
- new->dup = blkno;
- if (muldup == 0) {
- duplist = muldup = new;
- new->next = 0;
- } else {
- new->next = muldup->next;
- muldup->next = new;
- }
- for (dlp = duplist; dlp != muldup; dlp = dlp->next)
- if (dlp->dup == blkno)
- break;
- if (dlp == muldup && dlp->dup != blkno)
- muldup = new;
- }
- /*
- * count the number of blocks found in id_entryno
- */
- idesc->id_entryno++;
- }
- return (res);
-}
diff --git a/sbin/fsck/pass1b.c b/sbin/fsck/pass1b.c
deleted file mode 100644
index 7ef662f..0000000
--- a/sbin/fsck/pass1b.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass1b.c 8.4 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
-
-#include <string.h>
-
-#include "fsck.h"
-
-static struct dups *duphead;
-static int pass1bcheck __P((struct inodesc *));
-
-void
-pass1b()
-{
- register int c, i;
- register struct dinode *dp;
- struct inodesc idesc;
- ino_t inumber;
-
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = ADDR;
- idesc.id_func = pass1bcheck;
- duphead = duplist;
- inumber = 0;
- for (c = 0; c < sblock.fs_ncg; c++) {
- for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
- if (inumber < ROOTINO)
- continue;
- dp = ginode(inumber);
- if (dp == NULL)
- continue;
- idesc.id_number = inumber;
- if (inoinfo(inumber)->ino_state != USTATE &&
- (ckinode(dp, &idesc) & STOP))
- return;
- }
- }
-}
-
-static int
-pass1bcheck(idesc)
- register struct inodesc *idesc;
-{
- register struct dups *dlp;
- int nfrags, res = KEEPON;
- ufs_daddr_t blkno = idesc->id_blkno;
-
- for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
- if (chkrange(blkno, 1))
- res = SKIP;
- for (dlp = duphead; dlp; dlp = dlp->next) {
- if (dlp->dup == blkno) {
- blkerror(idesc->id_number, "DUP", blkno);
- dlp->dup = duphead->dup;
- duphead->dup = blkno;
- duphead = duphead->next;
- }
- if (dlp == muldup)
- break;
- }
- if (muldup == 0 || duphead == muldup->next)
- return (STOP);
- }
- return (res);
-}
diff --git a/sbin/fsck/pass2.c b/sbin/fsck/pass2.c
deleted file mode 100644
index 088ecff..0000000
--- a/sbin/fsck/pass2.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-#define MINDIRSIZE (sizeof (struct dirtemplate))
-
-static int blksort __P((const void *, const void *));
-static int pass2check __P((struct inodesc *));
-
-void
-pass2()
-{
- register struct dinode *dp;
- register struct inoinfo **inpp, *inp;
- struct inoinfo **inpend;
- struct inodesc curino;
- struct dinode dino;
- char pathbuf[MAXPATHLEN + 1];
-
- switch (inoinfo(ROOTINO)->ino_state) {
-
- case USTATE:
- pfatal("ROOT INODE UNALLOCATED");
- if (reply("ALLOCATE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
- break;
-
- case DCLEAR:
- pfatal("DUPS/BAD IN ROOT INODE");
- if (reply("REALLOCATE")) {
- freeino(ROOTINO);
- if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
- break;
- }
- if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- break;
-
- case FSTATE:
- case FCLEAR:
- pfatal("ROOT INODE NOT DIRECTORY");
- if (reply("REALLOCATE")) {
- freeino(ROOTINO);
- if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
- errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
- break;
- }
- if (reply("FIX") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- dp = ginode(ROOTINO);
- dp->di_mode &= ~IFMT;
- dp->di_mode |= IFDIR;
- inodirty();
- break;
-
- case DSTATE:
- break;
-
- default:
- errx(EEXIT, "BAD STATE %d FOR ROOT INODE",
- inoinfo(ROOTINO)->ino_state);
- }
- inoinfo(ROOTINO)->ino_state = DFOUND;
- if (newinofmt) {
- inoinfo(WINO)->ino_state = FSTATE;
- inoinfo(WINO)->ino_type = DT_WHT;
- }
- /*
- * Sort the directory list into disk block order.
- */
- qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
- /*
- * Check the integrity of each directory.
- */
- memset(&curino, 0, sizeof(struct inodesc));
- curino.id_type = DATA;
- curino.id_func = pass2check;
- dp = &dino;
- inpend = &inpsort[inplast];
- for (inpp = inpsort; inpp < inpend; inpp++) {
- inp = *inpp;
- if (inp->i_isize == 0)
- continue;
- if (inp->i_isize < MINDIRSIZE) {
- direrror(inp->i_number, "DIRECTORY TOO SHORT");
- inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ);
- if (reply("FIX") == 1) {
- dp = ginode(inp->i_number);
- dp->di_size = inp->i_isize;
- inodirty();
- dp = &dino;
- }
- } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) {
- getpathname(pathbuf, inp->i_number, inp->i_number);
- if (usedsoftdep)
- pfatal("%s %s: LENGTH %d NOT MULTIPLE OF %d",
- "DIRECTORY", pathbuf, inp->i_isize,
- DIRBLKSIZ);
- else
- pwarn("%s %s: LENGTH %d NOT MULTIPLE OF %d",
- "DIRECTORY", pathbuf, inp->i_isize,
- DIRBLKSIZ);
- if (preen)
- printf(" (ADJUSTED)\n");
- inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
- if (preen || reply("ADJUST") == 1) {
- dp = ginode(inp->i_number);
- dp->di_size = roundup(inp->i_isize, DIRBLKSIZ);
- inodirty();
- dp = &dino;
- }
- }
- memset(&dino, 0, sizeof(struct dinode));
- dino.di_mode = IFDIR;
- dp->di_size = inp->i_isize;
- memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
- curino.id_number = inp->i_number;
- curino.id_parent = inp->i_parent;
- (void)ckinode(dp, &curino);
- }
- /*
- * Now that the parents of all directories have been found,
- * make another pass to verify the value of `..'
- */
- for (inpp = inpsort; inpp < inpend; inpp++) {
- inp = *inpp;
- if (inp->i_parent == 0 || inp->i_isize == 0)
- continue;
- if (inoinfo(inp->i_parent)->ino_state == DFOUND &&
- inoinfo(inp->i_number)->ino_state == DSTATE)
- inoinfo(inp->i_number)->ino_state = DFOUND;
- if (inp->i_dotdot == inp->i_parent ||
- inp->i_dotdot == (ino_t)-1)
- continue;
- if (inp->i_dotdot == 0) {
- inp->i_dotdot = inp->i_parent;
- fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
- if (reply("FIX") == 0)
- continue;
- (void)makeentry(inp->i_number, inp->i_parent, "..");
- inoinfo(inp->i_parent)->ino_linkcnt--;
- continue;
- }
- fileerror(inp->i_parent, inp->i_number,
- "BAD INODE NUMBER FOR '..'");
- if (reply("FIX") == 0)
- continue;
- inoinfo(inp->i_dotdot)->ino_linkcnt++;
- inoinfo(inp->i_parent)->ino_linkcnt--;
- inp->i_dotdot = inp->i_parent;
- (void)changeino(inp->i_number, "..", inp->i_parent);
- }
- /*
- * Mark all the directories that can be found from the root.
- */
- propagate();
-}
-
-static int
-pass2check(idesc)
- struct inodesc *idesc;
-{
- register struct direct *dirp = idesc->id_dirp;
- register struct inoinfo *inp;
- int n, entrysize, ret = 0;
- struct dinode *dp;
- char *errmsg;
- struct direct proto;
- char namebuf[MAXPATHLEN + 1];
- char pathbuf[MAXPATHLEN + 1];
-
- /*
- * If converting, set directory entry type.
- */
- if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
- dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
- ret |= ALTERED;
- }
- /*
- * check for "."
- */
- if (idesc->id_entryno != 0)
- goto chk1;
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) {
- if (dirp->d_ino != idesc->id_number) {
- direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
- dirp->d_ino = idesc->id_number;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
- if (newinofmt && dirp->d_type != DT_DIR) {
- direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
- dirp->d_type = DT_DIR;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
- goto chk1;
- }
- direrror(idesc->id_number, "MISSING '.'");
- proto.d_ino = idesc->id_number;
- if (newinofmt)
- proto.d_type = DT_DIR;
- else
- proto.d_type = 0;
- proto.d_namlen = 1;
- (void)strcpy(proto.d_name, ".");
-# if BYTE_ORDER == LITTLE_ENDIAN
- if (!newinofmt) {
- u_char tmp;
-
- tmp = proto.d_type;
- proto.d_type = proto.d_namlen;
- proto.d_namlen = tmp;
- }
-# endif
- entrysize = DIRSIZ(0, &proto);
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
- pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
- dirp->d_name);
- } else if (dirp->d_reclen < entrysize) {
- pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
- } else if (dirp->d_reclen < 2 * entrysize) {
- proto.d_reclen = dirp->d_reclen;
- memmove(dirp, &proto, (size_t)entrysize);
- if (reply("FIX") == 1)
- ret |= ALTERED;
- } else {
- n = dirp->d_reclen - entrysize;
- proto.d_reclen = entrysize;
- memmove(dirp, &proto, (size_t)entrysize);
- idesc->id_entryno++;
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- dirp = (struct direct *)((char *)(dirp) + entrysize);
- memset(dirp, 0, (size_t)n);
- dirp->d_reclen = n;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
-chk1:
- if (idesc->id_entryno > 1)
- goto chk2;
- inp = getinoinfo(idesc->id_number);
- proto.d_ino = inp->i_parent;
- if (newinofmt)
- proto.d_type = DT_DIR;
- else
- proto.d_type = 0;
- proto.d_namlen = 2;
- (void)strcpy(proto.d_name, "..");
-# if BYTE_ORDER == LITTLE_ENDIAN
- if (!newinofmt) {
- u_char tmp;
-
- tmp = proto.d_type;
- proto.d_type = proto.d_namlen;
- proto.d_namlen = tmp;
- }
-# endif
- entrysize = DIRSIZ(0, &proto);
- if (idesc->id_entryno == 0) {
- n = DIRSIZ(0, dirp);
- if (dirp->d_reclen < n + entrysize)
- goto chk2;
- proto.d_reclen = dirp->d_reclen - n;
- dirp->d_reclen = n;
- idesc->id_entryno++;
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- dirp = (struct direct *)((char *)(dirp) + n);
- memset(dirp, 0, (size_t)proto.d_reclen);
- dirp->d_reclen = proto.d_reclen;
- }
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
- inp->i_dotdot = dirp->d_ino;
- if (newinofmt && dirp->d_type != DT_DIR) {
- direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
- dirp->d_type = DT_DIR;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
- goto chk2;
- }
- if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) {
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
- pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
- dirp->d_name);
- inp->i_dotdot = (ino_t)-1;
- } else if (dirp->d_reclen < entrysize) {
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
- pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
- inp->i_dotdot = (ino_t)-1;
- } else if (inp->i_parent != 0) {
- /*
- * We know the parent, so fix now.
- */
- inp->i_dotdot = inp->i_parent;
- fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
- proto.d_reclen = dirp->d_reclen;
- memmove(dirp, &proto, (size_t)entrysize);
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
- idesc->id_entryno++;
- if (dirp->d_ino != 0)
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- return (ret|KEEPON);
-chk2:
- if (dirp->d_ino == 0)
- return (ret|KEEPON);
- if (dirp->d_namlen <= 2 &&
- dirp->d_name[0] == '.' &&
- idesc->id_entryno >= 2) {
- if (dirp->d_namlen == 1) {
- direrror(idesc->id_number, "EXTRA '.' ENTRY");
- dirp->d_ino = 0;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- return (KEEPON | ret);
- }
- if (dirp->d_name[1] == '.') {
- direrror(idesc->id_number, "EXTRA '..' ENTRY");
- dirp->d_ino = 0;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- return (KEEPON | ret);
- }
- }
- idesc->id_entryno++;
- n = 0;
- if (dirp->d_ino > maxino) {
- fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
- n = reply("REMOVE");
- } else if (newinofmt &&
- ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) ||
- (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) {
- fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY");
- dirp->d_ino = WINO;
- dirp->d_type = DT_WHT;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- } else {
-again:
- switch (inoinfo(dirp->d_ino)->ino_state) {
- case USTATE:
- if (idesc->id_entryno <= 2)
- break;
- fileerror(idesc->id_number, dirp->d_ino, "UNALLOCATED");
- n = reply("REMOVE");
- break;
-
- case DCLEAR:
- case FCLEAR:
- if (idesc->id_entryno <= 2)
- break;
- if (inoinfo(dirp->d_ino)->ino_state == FCLEAR)
- errmsg = "DUP/BAD";
- else if (!preen && !usedsoftdep)
- errmsg = "ZERO LENGTH DIRECTORY";
- else {
- n = 1;
- break;
- }
- fileerror(idesc->id_number, dirp->d_ino, errmsg);
- if ((n = reply("REMOVE")) == 1)
- break;
- dp = ginode(dirp->d_ino);
- inoinfo(dirp->d_ino)->ino_state =
- (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
- inoinfo(dirp->d_ino)->ino_linkcnt = dp->di_nlink;
- goto again;
-
- case DSTATE:
- if (inoinfo(idesc->id_number)->ino_state == DFOUND)
- inoinfo(dirp->d_ino)->ino_state = DFOUND;
- /* fall through */
-
- case DFOUND:
- inp = getinoinfo(dirp->d_ino);
- if (inp->i_parent != 0 && idesc->id_entryno > 2) {
- getpathname(pathbuf, idesc->id_number,
- idesc->id_number);
- getpathname(namebuf, dirp->d_ino, dirp->d_ino);
- pwarn("%s %s %s\n", pathbuf,
- "IS AN EXTRANEOUS HARD LINK TO DIRECTORY",
- namebuf);
- if (preen) {
- printf(" (REMOVED)\n");
- n = 1;
- break;
- }
- if ((n = reply("REMOVE")) == 1)
- break;
- }
- if (idesc->id_entryno > 2)
- inp->i_parent = idesc->id_number;
- /* fall through */
-
- case FSTATE:
- if (newinofmt &&
- dirp->d_type != inoinfo(dirp->d_ino)->ino_type) {
- fileerror(idesc->id_number, dirp->d_ino,
- "BAD TYPE VALUE");
- dirp->d_type = inoinfo(dirp->d_ino)->ino_type;
- if (reply("FIX") == 1)
- ret |= ALTERED;
- }
- inoinfo(dirp->d_ino)->ino_linkcnt--;
- break;
-
- default:
- errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
- inoinfo(dirp->d_ino)->ino_state, dirp->d_ino);
- }
- }
- if (n == 0)
- return (ret|KEEPON);
- dirp->d_ino = 0;
- return (ret|KEEPON|ALTERED);
-}
-
-/*
- * Routine to sort disk blocks.
- */
-static int
-blksort(arg1, arg2)
- const void *arg1, *arg2;
-{
-
- return ((*(struct inoinfo **)arg1)->i_blks[0] -
- (*(struct inoinfo **)arg2)->i_blks[0]);
-}
diff --git a/sbin/fsck/pass3.c b/sbin/fsck/pass3.c
deleted file mode 100644
index 80e38e9..0000000
--- a/sbin/fsck/pass3.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass3.c 8.2 (Berkeley) 4/27/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-#include <ufs/ffs/fs.h>
-
-#include <string.h>
-
-#include "fsck.h"
-
-void
-pass3()
-{
- struct inoinfo *inp;
- int loopcnt, inpindex, state;
- ino_t orphan;
- struct inodesc idesc;
- char namebuf[MAXNAMLEN+1];
-
- for (inpindex = inplast - 1; inpindex >= 0; inpindex--) {
- inp = inpsort[inpindex];
- state = inoinfo(inp->i_number)->ino_state;
- if (inp->i_number == ROOTINO ||
- (inp->i_parent != 0 && state != DSTATE))
- continue;
- if (state == DCLEAR)
- 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++) {
- orphan = inp->i_number;
- if (inp->i_parent == 0 ||
- inoinfo(inp->i_parent)->ino_state != DSTATE ||
- loopcnt > countdirs)
- break;
- inp = getinoinfo(inp->i_parent);
- }
- if (loopcnt <= countdirs) {
- if (linkup(orphan, inp->i_dotdot, NULL)) {
- inp->i_parent = inp->i_dotdot = lfdir;
- 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();
- }
-}
diff --git a/sbin/fsck/pass4.c b/sbin/fsck/pass4.c
deleted file mode 100644
index 0012c50..0000000
--- a/sbin/fsck/pass4.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-void
-pass4()
-{
- register ino_t inumber;
- register struct zlncnt *zlnp;
- struct dinode *dp;
- struct inodesc idesc;
- int i, n, cg;
-
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = ADDR;
- idesc.id_func = pass4check;
- for (cg = 0; cg < sblock.fs_ncg; cg++) {
- inumber = cg * sblock.fs_ipg;
- 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 DFOUND:
- n = inoinfo(inumber)->ino_linkcnt;
- if (n) {
- adjust(&idesc, (short)n);
- break;
- }
- for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) {
- if (zlnp->zlncnt == inumber) {
- zlnp->zlncnt = zlnhead->zlncnt;
- zlnp = zlnhead;
- zlnhead = zlnhead->next;
- free((char *)zlnp);
- clri(&idesc, "UNREF", 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);
- }
- }
- }
-}
-
-int
-pass4check(idesc)
- register struct inodesc *idesc;
-{
- register struct dups *dlp;
- int nfrags, res = KEEPON;
- ufs_daddr_t blkno = idesc->id_blkno;
-
- for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
- if (chkrange(blkno, 1)) {
- res = SKIP;
- } else if (testbmap(blkno)) {
- for (dlp = duplist; dlp; dlp = dlp->next) {
- if (dlp->dup != blkno)
- continue;
- dlp->dup = duplist->dup;
- dlp = duplist;
- duplist = duplist->next;
- free((char *)dlp);
- break;
- }
- if (dlp == 0) {
- clrbmap(blkno);
- n_blks--;
- }
- }
- }
- return (res);
-}
diff --git a/sbin/fsck/pass5.c b/sbin/fsck/pass5.c
deleted file mode 100644
index e395625..0000000
--- a/sbin/fsck/pass5.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-void
-pass5()
-{
- int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
- int inomapsize, blkmapsize, astart, aend, ustart, uend;
- struct fs *fs = &sblock;
- struct cg *cg = &cgrp;
- ufs_daddr_t dbase, dmax;
- ufs_daddr_t d;
- long i, j, k, l, m, n;
- struct csum *cs;
- struct csum cstotal;
- struct inodesc idesc[3];
- char buf[MAXBSIZE];
- register struct cg *newcg = (struct cg *)buf;
- struct ocg *ocg = (struct ocg *)buf;
-
- inoinfo(WINO)->ino_state = USTATE;
- memset(newcg, 0, (size_t)fs->fs_cgsize);
- newcg->cg_niblk = fs->fs_ipg;
- if (cvtlevel >= 3) {
- if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
- if (preen)
- pwarn("DELETING CLUSTERING MAPS\n");
- if (preen || reply("DELETE CLUSTERING MAPS")) {
- fs->fs_contigsumsize = 0;
- doinglevel1 = 1;
- sbdirty();
- }
- }
- if (fs->fs_maxcontig > 1) {
- char *doit = 0;
-
- if (fs->fs_contigsumsize < 1) {
- doit = "CREAT";
- } else if (fs->fs_contigsumsize < fs->fs_maxcontig &&
- fs->fs_contigsumsize < FS_MAXCONTIG) {
- doit = "EXPAND";
- }
- if (doit) {
- i = fs->fs_contigsumsize;
- fs->fs_contigsumsize =
- MIN(fs->fs_maxcontig, FS_MAXCONTIG);
- if (CGSIZE(fs) > fs->fs_bsize) {
- pwarn("CANNOT %s CLUSTER MAPS\n", doit);
- fs->fs_contigsumsize = i;
- } else if (preen ||
- reply("CREATE CLUSTER MAPS")) {
- if (preen)
- pwarn("%sING CLUSTER MAPS\n",
- doit);
- fs->fs_cgsize =
- fragroundup(fs, CGSIZE(fs));
- doinglevel1 = 1;
- sbdirty();
- }
- }
- }
- }
- switch ((int)fs->fs_postblformat) {
-
- case FS_42POSTBLFMT:
- basesize = (char *)(&ocg->cg_btot[0]) -
- (char *)(&ocg->cg_firstfield);
- sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]);
- mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
- (u_char *)&ocg->cg_iused[0];
- blkmapsize = howmany(fs->fs_fpg, NBBY);
- inomapsize = &ocg->cg_free[0] - (u_char *)&ocg->cg_iused[0];
- ocg->cg_magic = CG_MAGIC;
- savednrpos = fs->fs_nrpos;
- fs->fs_nrpos = 8;
- break;
-
- case FS_DYNAMICPOSTBLFMT:
- newcg->cg_btotoff =
- &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
- newcg->cg_boff =
- newcg->cg_btotoff + fs->fs_cpg * sizeof(int32_t);
- newcg->cg_iusedoff = newcg->cg_boff +
- fs->fs_cpg * fs->fs_nrpos * sizeof(u_int16_t);
- newcg->cg_freeoff =
- newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
- inomapsize = newcg->cg_freeoff - newcg->cg_iusedoff;
- newcg->cg_nextfreeoff = newcg->cg_freeoff +
- howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY);
- blkmapsize = newcg->cg_nextfreeoff - newcg->cg_freeoff;
- if (fs->fs_contigsumsize > 0) {
- newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
- sizeof(u_int32_t);
- newcg->cg_clustersumoff =
- roundup(newcg->cg_clustersumoff, sizeof(u_int32_t));
- newcg->cg_clusteroff = newcg->cg_clustersumoff +
- (fs->fs_contigsumsize + 1) * sizeof(u_int32_t);
- newcg->cg_nextfreeoff = newcg->cg_clusteroff +
- howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
- }
- newcg->cg_magic = CG_MAGIC;
- basesize = &newcg->cg_space[0] -
- (u_char *)(&newcg->cg_firstfield);
- sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
- mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
- break;
-
- default:
- inomapsize = blkmapsize = sumsize = 0; /* keep lint happy */
- errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
- fs->fs_postblformat);
- }
- memset(&idesc[0], 0, sizeof idesc);
- for (i = 0; i < 3; i++) {
- idesc[i].id_type = ADDR;
- if (doinglevel2)
- idesc[i].id_fix = FIX;
- }
- memset(&cstotal, 0, sizeof(struct csum));
- j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
- for (i = fs->fs_size; i < j; i++)
- setbmap(i);
- for (c = 0; c < fs->fs_ncg; c++) {
- getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
- if (!cg_chkmagic(cg))
- pfatal("CG %d: BAD MAGIC NUMBER\n", c);
- dbase = cgbase(fs, c);
- dmax = dbase + fs->fs_fpg;
- if (dmax > fs->fs_size)
- dmax = fs->fs_size;
- newcg->cg_time = cg->cg_time;
- newcg->cg_cgx = c;
- if (c == fs->fs_ncg - 1)
- newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
- else
- newcg->cg_ncyl = fs->fs_cpg;
- newcg->cg_ndblk = dmax - dbase;
- if (fs->fs_contigsumsize > 0)
- newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
- newcg->cg_cs.cs_ndir = 0;
- newcg->cg_cs.cs_nffree = 0;
- newcg->cg_cs.cs_nbfree = 0;
- newcg->cg_cs.cs_nifree = fs->fs_ipg;
- if (cg->cg_rotor < newcg->cg_ndblk)
- newcg->cg_rotor = cg->cg_rotor;
- else
- newcg->cg_rotor = 0;
- if (cg->cg_frotor < newcg->cg_ndblk)
- newcg->cg_frotor = cg->cg_frotor;
- else
- newcg->cg_frotor = 0;
- if (cg->cg_irotor < newcg->cg_niblk)
- newcg->cg_irotor = cg->cg_irotor;
- else
- newcg->cg_irotor = 0;
- memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
- memset(&cg_blktot(newcg)[0], 0,
- (size_t)(sumsize + mapsize));
- if (fs->fs_postblformat == FS_42POSTBLFMT)
- ocg->cg_magic = CG_MAGIC;
- j = fs->fs_ipg * c;
- for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
- switch (inoinfo(j)->ino_state) {
-
- case USTATE:
- break;
-
- case DSTATE:
- case DCLEAR:
- case DFOUND:
- newcg->cg_cs.cs_ndir++;
- /* fall through */
-
- case FSTATE:
- case FCLEAR:
- newcg->cg_cs.cs_nifree--;
- setbit(cg_inosused(newcg), i);
- break;
-
- default:
- if (j < ROOTINO)
- break;
- errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
- inoinfo(j)->ino_state, j);
- }
- }
- if (c == 0)
- for (i = 0; i < ROOTINO; i++) {
- setbit(cg_inosused(newcg), i);
- newcg->cg_cs.cs_nifree--;
- }
- for (i = 0, d = dbase;
- d < dmax;
- d += fs->fs_frag, i += fs->fs_frag) {
- frags = 0;
- for (j = 0; j < fs->fs_frag; j++) {
- if (testbmap(d + j))
- continue;
- setbit(cg_blksfree(newcg), i + j);
- frags++;
- }
- if (frags == fs->fs_frag) {
- newcg->cg_cs.cs_nbfree++;
- j = cbtocylno(fs, i);
- cg_blktot(newcg)[j]++;
- cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
- if (fs->fs_contigsumsize > 0)
- setbit(cg_clustersfree(newcg),
- i / fs->fs_frag);
- } else if (frags > 0) {
- newcg->cg_cs.cs_nffree += frags;
- blk = blkmap(fs, cg_blksfree(newcg), i);
- ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
- }
- }
- if (fs->fs_contigsumsize > 0) {
- int32_t *sump = cg_clustersum(newcg);
- u_char *mapp = cg_clustersfree(newcg);
- int map = *mapp++;
- int bit = 1;
- int run = 0;
-
- for (i = 0; i < newcg->cg_nclusterblks; i++) {
- if ((map & bit) != 0) {
- run++;
- } else if (run != 0) {
- if (run > fs->fs_contigsumsize)
- run = fs->fs_contigsumsize;
- sump[run]++;
- run = 0;
- }
- if ((i & (NBBY - 1)) != (NBBY - 1)) {
- bit <<= 1;
- } else {
- map = *mapp++;
- bit = 1;
- }
- }
- if (run != 0) {
- if (run > fs->fs_contigsumsize)
- run = fs->fs_contigsumsize;
- sump[run]++;
- }
- }
- cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
- cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
- cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
- cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
- cs = &fs->fs_cs(fs, c);
- if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 &&
- dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
- memmove(cs, &newcg->cg_cs, sizeof *cs);
- sbdirty();
- }
- if (doinglevel1) {
- memmove(cg, newcg, (size_t)fs->fs_cgsize);
- cgdirty();
- continue;
- }
- if ((memcmp(newcg, cg, basesize) != 0 ||
- memcmp(&cg_blktot(newcg)[0],
- &cg_blktot(cg)[0], sumsize) != 0) &&
- dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
- memmove(cg, newcg, (size_t)basesize);
- memmove(&cg_blktot(cg)[0],
- &cg_blktot(newcg)[0], (size_t)sumsize);
- cgdirty();
- }
- if (debug) {
- for (i = 0; i < inomapsize; i++) {
- j = cg_inosused(newcg)[i];
- k = cg_inosused(cg)[i];
- if (j == k)
- continue;
- for (m = 0, l = 1; m < NBBY; m++, l <<= 1) {
- if ((j & l) == (k & l))
- continue;
- n = c * fs->fs_ipg + i * NBBY + m;
- if ((j & l) != 0)
- pwarn("%s INODE %d MARKED %s\n",
- "ALLOCATED", n, "FREE");
- else
- pwarn("%s INODE %d MARKED %s\n",
- "UNALLOCATED", n, "USED");
- }
- }
- astart = ustart = -1;
- for (i = 0; i < blkmapsize; i++) {
- j = cg_blksfree(cg)[i];
- k = cg_blksfree(newcg)[i];
- if (j == k)
- continue;
- for (m = 0, l = 1; m < NBBY; m++, l <<= 1) {
- if ((j & l) == (k & l))
- continue;
- n = c * fs->fs_fpg + i * NBBY + m;
- if ((j & l) != 0) {
- if (astart == -1) {
- astart = aend = n;
- continue;
- }
- if (aend + 1 == n) {
- aend = n;
- continue;
- }
- pwarn("%s FRAGS %d-%d %s\n",
- "ALLOCATED", astart, aend,
- "MARKED FREE");
- astart = aend = n;
- } else {
- if (ustart == -1) {
- ustart = uend = n;
- continue;
- }
- if (uend + 1 == n) {
- uend = n;
- continue;
- }
- pwarn("%s FRAGS %d-%d %s\n",
- "UNALLOCATED", ustart, uend,
- "MARKED USED");
- ustart = uend = n;
- }
- }
- }
- if (astart != -1)
- pwarn("%s FRAGS %d-%d %s\n",
- "ALLOCATED", astart, aend,
- "MARKED FREE");
- if (ustart != -1)
- pwarn("%s FRAGS %d-%d %s\n",
- "UNALLOCATED", ustart, uend,
- "MARKED USED");
- }
- if (usedsoftdep) {
- for (i = 0; i < inomapsize; i++) {
- j = cg_inosused(newcg)[i];
- if ((cg_inosused(cg)[i] & j) == j)
- continue;
- for (k = 0; k < NBBY; k++) {
- if ((j & (1 << k)) == 0)
- continue;
- if (cg_inosused(cg)[i] & (1 << k))
- continue;
- pwarn("ALLOCATED INODE %d MARKED FREE\n",
- c * fs->fs_ipg + i * NBBY + k);
- }
- }
- for (i = 0; i < blkmapsize; i++) {
- j = cg_blksfree(cg)[i];
- if ((cg_blksfree(newcg)[i] & j) == j)
- continue;
- for (k = 0; k < NBBY; k++) {
- if ((j & (1 << k)) == 0)
- continue;
- if (cg_blksfree(newcg)[i] & (1 << k))
- continue;
- pwarn("ALLOCATED FRAG %d MARKED FREE\n",
- c * fs->fs_fpg + i * NBBY + k);
- }
- }
- }
- if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 &&
- dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
- memmove(cg_inosused(cg), cg_inosused(newcg),
- (size_t)mapsize);
- cgdirty();
- }
- }
- if (fs->fs_postblformat == FS_42POSTBLFMT)
- fs->fs_nrpos = savednrpos;
- if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0
- && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
- memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
- fs->fs_ronly = 0;
- fs->fs_fmod = 0;
- sbdirty();
- }
-}
diff --git a/sbin/fsck/pathnames.h b/sbin/fsck/pathnames.h
new file mode 100644
index 0000000..5f3166e
--- /dev/null
+++ b/sbin/fsck/pathnames.h
@@ -0,0 +1,35 @@
+/* $NetBSD: pathnames.h,v 1.1 1996/09/11 20:27:15 christos Exp $ */
+
+/*
+ * Copyright (c) 1996 Christos Zoulas. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christos Zoulas.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define _PATH_SBIN "/sbin"
+#define _PATH_USRSBIN "/usr/sbin"
diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c
deleted file mode 100644
index e43aada..0000000
--- a/sbin/fsck/preen.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)preen.c 8.5 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <ufs/ufs/dinode.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fstab.h>
-#include <string.h>
-
-#include "fsck.h"
-
-struct part {
- struct part *next; /* forward link of partitions on disk */
- char *name; /* device name */
- char *fsname; /* mounted filesystem name */
- long auxdata; /* auxillary data for application */
-} *badlist, **badnext = &badlist;
-
-struct disk {
- char *name; /* disk base name */
- struct disk *next; /* forward link for list of disks */
- struct part *part; /* head of list of partitions on disk */
- int pid; /* If != 0, pid of proc working on */
-} *disks;
-
-int nrun, ndisks;
-
-static void addpart __P((char *name, char *fsname, long auxdata));
-static struct disk *finddisk __P((char *name));
-static int startdisk __P((struct disk *dk,
- int (*checkit)(char *, char *, long, int)));
-
-int
-checkfstab(preen, maxrun, docheck, chkit)
- int preen;
- int maxrun;
- int (*docheck)(struct fstab *);
- int (*chkit)(char *, char *, long, int);
-{
- register struct fstab *fsp;
- register struct disk *dk, *nextdisk;
- register struct part *pt;
- int ret, pid, retcode, passno, sumstatus, status;
- long auxdata;
- char *name;
-
- sumstatus = 0;
- for (passno = 1; passno <= 2; passno++) {
- if (setfsent() == 0) {
- fprintf(stderr, "Can't open checklist file: %s\n",
- _PATH_FSTAB);
- return (8);
- }
- while ((fsp = getfsent()) != 0) {
- if ((auxdata = (*docheck)(fsp)) == 0)
- continue;
- if (preen == 0 ||
- (passno == 1 && fsp->fs_passno == 1)) {
- if ((name = blockcheck(fsp->fs_spec)) != 0) {
- if ((sumstatus = (*chkit)(name,
- fsp->fs_file, auxdata, 0)) != 0)
- return (sumstatus);
- } else if (preen)
- return (8);
- } else if (passno == 2 && fsp->fs_passno > 1) {
- if ((name = blockcheck(fsp->fs_spec)) == NULL) {
- fprintf(stderr, "BAD DISK NAME %s\n",
- fsp->fs_spec);
- sumstatus |= 8;
- continue;
- }
- addpart(name, fsp->fs_file, auxdata);
- }
- }
- if (preen == 0)
- return (0);
- }
- if (preen) {
- if (maxrun == 0)
- maxrun = ndisks;
- if (maxrun > ndisks)
- maxrun = ndisks;
- nextdisk = disks;
- for (passno = 0; passno < maxrun; ++passno) {
- while ((ret = startdisk(nextdisk, chkit)) && nrun > 0)
- sleep(10);
- if (ret)
- return (ret);
- nextdisk = nextdisk->next;
- }
- while ((pid = wait(&status)) != -1) {
- for (dk = disks; dk; dk = dk->next)
- if (dk->pid == pid)
- break;
- if (dk == 0) {
- printf("Unknown pid %d\n", pid);
- continue;
- }
- if (WIFEXITED(status))
- retcode = WEXITSTATUS(status);
- else
- retcode = 0;
- if (WIFSIGNALED(status)) {
- printf("%s (%s): EXITED WITH SIGNAL %d\n",
- dk->part->name, dk->part->fsname,
- WTERMSIG(status));
- retcode = 8;
- }
- if (retcode != 0) {
- sumstatus |= retcode;
- *badnext = dk->part;
- badnext = &dk->part->next;
- dk->part = dk->part->next;
- *badnext = NULL;
- } else
- dk->part = dk->part->next;
- dk->pid = 0;
- nrun--;
- if (dk->part == NULL)
- ndisks--;
-
- if (nextdisk == NULL) {
- if (dk->part) {
- while ((ret = startdisk(dk, chkit)) &&
- nrun > 0)
- sleep(10);
- if (ret)
- return (ret);
- }
- } else if (nrun < maxrun && nrun < ndisks) {
- for ( ;; ) {
- if ((nextdisk = nextdisk->next) == NULL)
- nextdisk = disks;
- if (nextdisk->part != NULL &&
- nextdisk->pid == 0)
- break;
- }
- while ((ret = startdisk(nextdisk, chkit)) &&
- nrun > 0)
- sleep(10);
- if (ret)
- return (ret);
- }
- }
- }
- if (sumstatus) {
- if (badlist == 0)
- return (sumstatus);
- fprintf(stderr, "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
- badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:");
- for (pt = badlist; pt; pt = pt->next)
- fprintf(stderr, "%s (%s)%s", pt->name, pt->fsname,
- pt->next ? ", " : "\n");
- return (sumstatus);
- }
- (void)endfsent();
- return (0);
-}
-
-static struct disk *
-finddisk(name)
- char *name;
-{
- register struct disk *dk, **dkp;
- register char *p;
- size_t len;
-
- p = strrchr(name, '/');
- p = p == NULL ? name : p + 1;
- while (*p != '\0' && !isdigit((u_char)*p))
- p++;
- while (isdigit((u_char)*p))
- p++;
- len = (size_t)(p - name);
- for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
- if (strncmp(dk->name, name, len) == 0 &&
- dk->name[len] == 0)
- return (dk);
- }
- if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
- fprintf(stderr, "out of memory");
- exit (8);
- }
- dk = *dkp;
- if ((dk->name = malloc(len + 1)) == NULL) {
- fprintf(stderr, "out of memory");
- exit (8);
- }
- (void)strncpy(dk->name, name, len);
- dk->name[len] = '\0';
- dk->part = NULL;
- dk->next = NULL;
- dk->pid = 0;
- ndisks++;
- return (dk);
-}
-
-static void
-addpart(name, fsname, auxdata)
- char *name, *fsname;
- long auxdata;
-{
- struct disk *dk = finddisk(name);
- register struct part *pt, **ppt = &dk->part;
-
- for (pt = dk->part; pt; ppt = &pt->next, pt = pt->next)
- if (strcmp(pt->name, name) == 0) {
- printf("%s in fstab more than once!\n", name);
- return;
- }
- if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
- fprintf(stderr, "out of memory");
- exit (8);
- }
- pt = *ppt;
- if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
- fprintf(stderr, "out of memory");
- exit (8);
- }
- (void)strcpy(pt->name, name);
- if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
- fprintf(stderr, "out of memory");
- exit (8);
- }
- (void)strcpy(pt->fsname, fsname);
- pt->next = NULL;
- pt->auxdata = auxdata;
-}
-
-static int
-startdisk(dk, checkit)
- register struct disk *dk;
- int (*checkit)(char *, char *, long, int);
-{
- register struct part *pt = dk->part;
-
- dk->pid = fork();
- if (dk->pid < 0) {
- perror("fork");
- return (8);
- }
- if (dk->pid == 0)
- exit((*checkit)(pt->name, pt->fsname, pt->auxdata, 1));
- nrun++;
- return (0);
-}
-
-char *
-blockcheck(origname)
- char *origname;
-{
- struct stat stslash, stblock, stchar;
- char *newname, *raw;
- struct fstab *fsinfo;
- int retried = 0, len;
-
- newname = origname;
-retry:
- if (stat(newname, &stblock) < 0) {
- printf("Can't stat %s: %s\n", newname, strerror(errno));
- return (origname);
- }
- switch(stblock.st_mode & S_IFMT) {
- case S_IFCHR:
- case S_IFBLK:
- return(newname);
- case S_IFDIR:
- if (retried)
- break;
-
- len = strlen(origname) - 1;
- if (len > 0 && origname[len] == '/')
- /* remove trailing slash */
- origname[len] = '\0';
- if ((fsinfo = getfsfile(origname)) == NULL) {
- printf("Can't resolve %s to character special device",
- origname);
- return (0);
- }
- newname = fsinfo->fs_spec;
- retried++;
- goto retry;
- }
- /*
- * Not a block or character device, just return name and
- * let the user decide whether to use it.
- */
- return (origname);
-}
diff --git a/sbin/fsck/setup.c b/sbin/fsck/setup.c
deleted file mode 100644
index 6c4098c..0000000
--- a/sbin/fsck/setup.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#define DKTYPENAMES
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/disklabel.h>
-#include <sys/file.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ffs/fs.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <string.h>
-
-#include "fsck.h"
-
-struct bufarea asblk;
-#define altsblock (*asblk.b_un.b_fs)
-#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
-
-static void badsb __P((int listerr, char *s));
-static int calcsb __P((char *dev, int devfd, struct fs *fs));
-static struct disklabel *getdisklabel __P((char *s, int fd));
-static int readsb __P((int listerr));
-
-/*
- * Read in a superblock finding an alternate if necessary.
- * Return 1 if successful, 0 if unsuccessful, -1 if filesystem
- * is already clean (preen mode only).
- */
-int
-setup(dev)
- char *dev;
-{
- long cg, size, asked, i, j;
- long skipclean, bmapsize;
- struct disklabel *lp;
- off_t sizepb;
- struct stat statb;
- struct fs proto;
-
- havesb = 0;
- fswritefd = -1;
- cursnapshot = 0;
- skipclean = fflag ? 0 : preen;
- if (stat(dev, &statb) < 0) {
- printf("Can't stat %s: %s\n", dev, strerror(errno));
- return (0);
- }
- if ((statb.st_mode & S_IFMT) != S_IFCHR &&
- (statb.st_mode & S_IFMT) != S_IFBLK) {
- if ((statb.st_flags & SF_SNAPSHOT) != 0) {
- cursnapshot = statb.st_ino;
- } else {
- pfatal("%s is not a disk device", dev);
- if (reply("CONTINUE") == 0)
- return (0);
- }
- }
- if ((fsreadfd = open(dev, O_RDONLY)) < 0) {
- printf("Can't open %s: %s\n", dev, strerror(errno));
- return (0);
- }
- if (preen == 0)
- printf("** %s", dev);
- if (nflag || (fswritefd = open(dev, O_WRONLY)) < 0) {
- fswritefd = -1;
- if (preen)
- pfatal("NO WRITE ACCESS");
- printf(" (NO WRITE)");
- }
- if (preen == 0)
- printf("\n");
- fsmodified = 0;
- lfdir = 0;
- initbarea(&sblk);
- initbarea(&asblk);
- sblk.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)
- errx(EEXIT, "cannot allocate space for superblock");
- if ((lp = getdisklabel(NULL, fsreadfd)))
- dev_bsize = secsize = lp->d_secsize;
- else
- dev_bsize = secsize = DEV_BSIZE;
- /*
- * Read in the superblock, looking for alternates if necessary
- */
- if (readsb(1) == 0) {
- skipclean = 0;
- if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0)
- return(0);
- if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0)
- return (0);
- for (cg = 0; cg < proto.fs_ncg; cg++) {
- bflag = fsbtodb(&proto, cgsblock(&proto, cg));
- if (readsb(0) != 0)
- break;
- }
- if (cg >= proto.fs_ncg) {
- printf("%s %s\n%s %s\n%s %s\n",
- "SEARCH FOR ALTERNATE SUPER-BLOCK",
- "FAILED. YOU MUST USE THE",
- "-b OPTION TO FSCK TO SPECIFY THE",
- "LOCATION OF AN ALTERNATE",
- "SUPER-BLOCK TO SUPPLY NEEDED",
- "INFORMATION; SEE fsck(8).");
- bflag = 0;
- return(0);
- }
- pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
- bflag = 0;
- }
- if (skipclean && sblock.fs_clean) {
- pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
- return (-1);
- }
- maxfsblock = sblock.fs_size;
- maxino = sblock.fs_ncg * sblock.fs_ipg;
- /*
- * Check and potentially fix certain fields in the super block.
- */
- if (sblock.fs_optim != FS_OPTTIME && sblock.fs_optim != FS_OPTSPACE) {
- pfatal("UNDEFINED OPTIMIZATION IN SUPERBLOCK");
- if (reply("SET TO DEFAULT") == 1) {
- sblock.fs_optim = FS_OPTTIME;
- sbdirty();
- }
- }
- if ((sblock.fs_minfree < 0 || sblock.fs_minfree > 99)) {
- pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK",
- sblock.fs_minfree);
- if (reply("SET TO DEFAULT") == 1) {
- sblock.fs_minfree = 10;
- sbdirty();
- }
- }
- if (sblock.fs_interleave < 1 ||
- sblock.fs_interleave > sblock.fs_nsect) {
- pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK",
- sblock.fs_interleave);
- sblock.fs_interleave = 1;
- if (preen)
- printf(" (FIXED)\n");
- if (preen || reply("SET TO DEFAULT") == 1) {
- sbdirty();
- dirty(&asblk);
- }
- }
- if (sblock.fs_npsect < sblock.fs_nsect ||
- sblock.fs_npsect > sblock.fs_nsect*2) {
- pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK",
- sblock.fs_npsect);
- sblock.fs_npsect = sblock.fs_nsect;
- if (preen)
- printf(" (FIXED)\n");
- if (preen || reply("SET TO DEFAULT") == 1) {
- sbdirty();
- dirty(&asblk);
- }
- }
- if (sblock.fs_inodefmt >= FS_44INODEFMT) {
- newinofmt = 1;
- } else {
- sblock.fs_qbmask = ~sblock.fs_bmask;
- sblock.fs_qfmask = ~sblock.fs_fmask;
- newinofmt = 0;
- }
- /*
- * Convert to new inode format.
- */
- if (cvtlevel >= 2 && sblock.fs_inodefmt < FS_44INODEFMT) {
- if (preen)
- pwarn("CONVERTING TO NEW INODE FORMAT\n");
- else if (!reply("CONVERT TO NEW INODE FORMAT"))
- return(0);
- doinglevel2++;
- sblock.fs_inodefmt = FS_44INODEFMT;
- sizepb = sblock.fs_bsize;
- sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;
- for (i = 0; i < NIADDR; i++) {
- sizepb *= NINDIR(&sblock);
- sblock.fs_maxfilesize += sizepb;
- }
- sblock.fs_maxsymlinklen = MAXSYMLINKLEN;
- sblock.fs_qbmask = ~sblock.fs_bmask;
- sblock.fs_qfmask = ~sblock.fs_fmask;
- sbdirty();
- dirty(&asblk);
- }
- /*
- * Convert to new cylinder group format.
- */
- if (cvtlevel >= 1 && sblock.fs_postblformat == FS_42POSTBLFMT) {
- if (preen)
- pwarn("CONVERTING TO NEW CYLINDER GROUP FORMAT\n");
- else if (!reply("CONVERT TO NEW CYLINDER GROUP FORMAT"))
- return(0);
- doinglevel1++;
- sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
- sblock.fs_nrpos = 8;
- sblock.fs_postbloff =
- (char *)(&sblock.fs_opostbl[0][0]) -
- (char *)(&sblock.fs_firstfield);
- sblock.fs_rotbloff = &sblock.fs_space[0] -
- (u_char *)(&sblock.fs_firstfield);
- sblock.fs_cgsize =
- fragroundup(&sblock, CGSIZE(&sblock));
- sbdirty();
- dirty(&asblk);
- }
- if (asblk.b_dirty && !bflag) {
- memmove(&altsblock, &sblock, (size_t)sblock.fs_sbsize);
- flush(fswritefd, &asblk);
- }
- /*
- * read in the summary info.
- */
- asked = 0;
- for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
- size = sblock.fs_cssize - i < sblock.fs_bsize ?
- sblock.fs_cssize - i : sblock.fs_bsize;
- sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size);
- if (bread(fsreadfd, (char *)sblock.fs_csp[j],
- fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
- size) != 0 && !asked) {
- pfatal("BAD SUMMARY INFORMATION");
- if (reply("CONTINUE") == 0) {
- ckfini(0);
- exit(EEXIT);
- }
- asked++;
- }
- }
- /*
- * allocate and initialize the necessary maps
- */
- bmapsize = roundup(howmany(maxfsblock, NBBY), sizeof(short));
- blockmap = calloc((unsigned)bmapsize, sizeof (char));
- if (blockmap == NULL) {
- printf("cannot alloc %u bytes for blockmap\n",
- (unsigned)bmapsize);
- goto badsb;
- }
- inostathead = calloc((unsigned)(sblock.fs_ncg),
- sizeof(struct inostatlist));
- if (inostathead == NULL) {
- printf("cannot alloc %u bytes for inostathead\n",
- (unsigned)(sizeof(struct inostatlist) * (sblock.fs_ncg)));
- goto badsb;
- }
- numdirs = sblock.fs_cstotal.cs_ndir;
- dirhash = numdirs;
- if (numdirs == 0) {
- printf("numdirs is zero, try using an alternate superblock\n");
- goto badsb;
- }
- inplast = 0;
- listmax = numdirs + 10;
- inpsort = (struct inoinfo **)calloc((unsigned)listmax,
- sizeof(struct inoinfo *));
- inphead = (struct inoinfo **)calloc((unsigned)numdirs,
- sizeof(struct inoinfo *));
- if (inpsort == NULL || inphead == NULL) {
- printf("cannot alloc %u bytes for inphead\n",
- (unsigned)numdirs * sizeof(struct inoinfo *));
- goto badsb;
- }
- bufinit();
- if (sblock.fs_flags & FS_DOSOFTDEP)
- usedsoftdep = 1;
- else
- usedsoftdep = 0;
- return (1);
-
-badsb:
- ckfini(0);
- return (0);
-}
-
-/*
- * Read in the super block and its summary info.
- */
-static int
-readsb(listerr)
- int listerr;
-{
- ufs_daddr_t super = bflag ? bflag : SBOFF / dev_bsize;
-
- if (bread(fsreadfd, (char *)&sblock, super, (long)SBSIZE) != 0)
- return (0);
- sblk.b_bno = super;
- sblk.b_size = SBSIZE;
- /*
- * run a few consistency checks of the super block
- */
- if (sblock.fs_magic != FS_MAGIC)
- { badsb(listerr, "MAGIC NUMBER WRONG"); return (0); }
- if (sblock.fs_ncg < 1)
- { badsb(listerr, "NCG OUT OF RANGE"); return (0); }
- if (sblock.fs_cpg < 1)
- { badsb(listerr, "CPG OUT OF RANGE"); return (0); }
- if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl ||
- (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl)
- { badsb(listerr, "NCYL LESS THAN NCG*CPG"); return (0); }
- if (sblock.fs_sbsize > SBSIZE)
- { badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); }
- /*
- * Compute block size that the filesystem is based on,
- * according to fsbtodb, and adjust superblock block number
- * so we can tell if this is an alternate later.
- */
- super *= dev_bsize;
- dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
- sblk.b_bno = super / dev_bsize;
- if (bflag) {
- havesb = 1;
- return (1);
- }
- /*
- * Set all possible fields that could differ, then do check
- * of whole super block against an alternate super block.
- * When an alternate super-block is specified this check is skipped.
- */
- getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
- if (asblk.b_errs)
- return (0);
- altsblock.fs_firstfield = sblock.fs_firstfield;
- altsblock.fs_unused_1 = sblock.fs_unused_1;
- altsblock.fs_time = sblock.fs_time;
- altsblock.fs_cstotal = sblock.fs_cstotal;
- altsblock.fs_cgrotor = sblock.fs_cgrotor;
- altsblock.fs_fmod = sblock.fs_fmod;
- altsblock.fs_clean = sblock.fs_clean;
- altsblock.fs_ronly = sblock.fs_ronly;
- altsblock.fs_flags = sblock.fs_flags;
- altsblock.fs_maxcontig = sblock.fs_maxcontig;
- altsblock.fs_minfree = sblock.fs_minfree;
- altsblock.fs_optim = sblock.fs_optim;
- altsblock.fs_rotdelay = sblock.fs_rotdelay;
- altsblock.fs_maxbpg = sblock.fs_maxbpg;
- memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
- altsblock.fs_maxcluster = sblock.fs_maxcluster;
- memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
- memmove(altsblock.fs_snapinum, sblock.fs_snapinum,
- sizeof sblock.fs_snapinum);
- memmove(altsblock.fs_sparecon,
- sblock.fs_sparecon, sizeof sblock.fs_sparecon);
- /*
- * The following should not have to be copied.
- */
- altsblock.fs_fsbtodb = sblock.fs_fsbtodb;
- altsblock.fs_interleave = sblock.fs_interleave;
- altsblock.fs_npsect = sblock.fs_npsect;
- altsblock.fs_nrpos = sblock.fs_nrpos;
- altsblock.fs_state = sblock.fs_state;
- altsblock.fs_qbmask = sblock.fs_qbmask;
- altsblock.fs_qfmask = sblock.fs_qfmask;
- altsblock.fs_state = sblock.fs_state;
- altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
- if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) {
- if (debug) {
- long *nlp, *olp, *endlp;
-
- printf("superblock mismatches\n");
- nlp = (long *)&altsblock;
- olp = (long *)&sblock;
- endlp = olp + (sblock.fs_sbsize / sizeof *olp);
- for ( ; olp < endlp; olp++, nlp++) {
- if (*olp == *nlp)
- continue;
- printf(
- "offset %d, original %ld, alternate %ld\n",
- olp - (long *)&sblock, *olp, *nlp);
- }
- }
- badsb(listerr,
- "VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
- return (0);
- }
- havesb = 1;
- return (1);
-}
-
-static void
-badsb(listerr, s)
- int listerr;
- char *s;
-{
-
- if (!listerr)
- return;
- if (preen)
- printf("%s: ", cdevname);
- pfatal("BAD SUPER BLOCK: %s\n", s);
-}
-
-/*
- * Calculate a prototype superblock based on information in the disk label.
- * When done the cgsblock macro can be calculated and the fs_ncg field
- * can be used. Do NOT attempt to use other macros without verifying that
- * their needed information is available!
- */
-static int
-calcsb(dev, devfd, fs)
- char *dev;
- int devfd;
- register struct fs *fs;
-{
- register struct disklabel *lp;
- register struct partition *pp;
- register char *cp;
- int i;
-
- cp = strchr(dev, '\0') - 1;
- if (cp == (char *)-1 || ((*cp < 'a' || *cp > 'h') && !isdigit(*cp))) {
- pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
- return (0);
- }
- lp = getdisklabel(dev, devfd);
- if (isdigit(*cp))
- pp = &lp->d_partitions[0];
- else
- pp = &lp->d_partitions[*cp - 'a'];
- if (pp->p_fstype != FS_BSDFFS) {
- pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n",
- dev, pp->p_fstype < FSMAXTYPES ?
- fstypenames[pp->p_fstype] : "unknown");
- return (0);
- }
- if (pp->p_fsize == 0 || pp->p_frag == 0 ||
- pp->p_cpg == 0 || pp->p_size == 0) {
- 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);
- }
- memset(fs, 0, sizeof(struct fs));
- fs->fs_fsize = pp->p_fsize;
- fs->fs_frag = pp->p_frag;
- fs->fs_cpg = pp->p_cpg;
- fs->fs_size = pp->p_size;
- fs->fs_ntrak = lp->d_ntracks;
- fs->fs_nsect = lp->d_nsectors;
- fs->fs_spc = lp->d_secpercyl;
- fs->fs_nspf = fs->fs_fsize / lp->d_secsize;
- fs->fs_sblkno = roundup(
- howmany(lp->d_bbsize + lp->d_sbsize, fs->fs_fsize),
- fs->fs_frag);
- fs->fs_cgmask = 0xffffffff;
- for (i = fs->fs_ntrak; i > 1; i >>= 1)
- fs->fs_cgmask <<= 1;
- if (!POWEROF2(fs->fs_ntrak))
- fs->fs_cgmask <<= 1;
- fs->fs_cgoffset = roundup(
- howmany(fs->fs_nsect, NSPF(fs)), fs->fs_frag);
- fs->fs_fpg = (fs->fs_cpg * fs->fs_spc) / NSPF(fs);
- fs->fs_ncg = howmany(fs->fs_size / fs->fs_spc, fs->fs_cpg);
- for (fs->fs_fsbtodb = 0, i = NSPF(fs); i > 1; i >>= 1)
- fs->fs_fsbtodb++;
- dev_bsize = lp->d_secsize;
- return (1);
-}
-
-static struct disklabel *
-getdisklabel(s, fd)
- char *s;
- int fd;
-{
- static struct disklabel lab;
-
- if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) {
- if (s == NULL)
- return ((struct disklabel *)NULL);
- pwarn("ioctl (GCINFO): %s\n", strerror(errno));
- errx(EEXIT, "%s: can't read disk label", s);
- }
- return (&lab);
-}
diff --git a/sbin/fsck/utilities.c b/sbin/fsck/utilities.c
deleted file mode 100644
index 0ccd9bb..0000000
--- a/sbin/fsck/utilities.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Copyright (c) 1980, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-#if 0
-static const char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
-#endif
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <ufs/ufs/dinode.h>
-#include <ufs/ufs/dir.h>
-#include <ufs/ffs/fs.h>
-
-#include <err.h>
-#include <string.h>
-
-#include "fsck.h"
-
-long diskreads, totalreads; /* Disk cache statistics */
-
-static void rwerror __P((char *mesg, ufs_daddr_t blk));
-
-int
-ftypeok(dp)
- struct dinode *dp;
-{
- switch (dp->di_mode & IFMT) {
-
- case IFDIR:
- case IFREG:
- case IFBLK:
- case IFCHR:
- case IFLNK:
- case IFSOCK:
- case IFIFO:
- return (1);
-
- default:
- if (debug)
- printf("bad file type 0%o\n", dp->di_mode);
- return (0);
- }
-}
-
-int
-reply(question)
- char *question;
-{
- int persevere;
- char c;
-
- if (preen)
- pfatal("INTERNAL ERROR: GOT TO reply()");
- persevere = !strcmp(question, "CONTINUE");
- printf("\n");
- if (!persevere && (nflag || fswritefd < 0)) {
- printf("%s? no\n\n", question);
- resolved = 0;
- return (0);
- }
- if (yflag || (persevere && nflag)) {
- printf("%s? yes\n\n", question);
- return (1);
- }
- do {
- printf("%s? [yn] ", question);
- (void) fflush(stdout);
- c = getc(stdin);
- while (c != '\n' && getc(stdin) != '\n') {
- if (feof(stdin)) {
- resolved = 0;
- return (0);
- }
- }
- } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
- printf("\n");
- if (c == 'y' || c == 'Y')
- return (1);
- resolved = 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.
- */
-void
-bufinit()
-{
- register struct bufarea *bp;
- long bufcnt, i;
- char *bufp;
-
- pbp = pdirbp = (struct bufarea *)0;
- bufp = malloc((unsigned int)sblock.fs_bsize);
- if (bufp == 0)
- errx(EEXIT, "cannot allocate buffer pool");
- cgblk.b_un.b_buf = bufp;
- initbarea(&cgblk);
- bufhead.b_next = bufhead.b_prev = &bufhead;
- bufcnt = MAXBUFSPACE / sblock.fs_bsize;
- if (bufcnt < MINBUFS)
- bufcnt = MINBUFS;
- for (i = 0; i < bufcnt; i++) {
- bp = (struct bufarea *)malloc(sizeof(struct bufarea));
- bufp = malloc((unsigned int)sblock.fs_bsize);
- if (bp == NULL || bufp == NULL) {
- if (i >= MINBUFS)
- break;
- errx(EEXIT, "cannot allocate buffer pool");
- }
- bp->b_un.b_buf = bufp;
- bp->b_prev = &bufhead;
- bp->b_next = bufhead.b_next;
- bufhead.b_next->b_prev = bp;
- bufhead.b_next = bp;
- initbarea(bp);
- }
- bufhead.b_size = i; /* save number of buffers */
-}
-
-/*
- * Manage a cache of directory blocks.
- */
-struct bufarea *
-getdatablk(blkno, size)
- ufs_daddr_t blkno;
- long size;
-{
- register struct bufarea *bp;
-
- for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
- if (bp->b_bno == fsbtodb(&sblock, blkno))
- goto foundit;
- for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
- if ((bp->b_flags & B_INUSE) == 0)
- break;
- if (bp == &bufhead)
- errx(EEXIT, "deadlocked buffer pool");
- getblk(bp, blkno, size);
- /* fall through */
-foundit:
- totalreads++;
- bp->b_prev->b_next = bp->b_next;
- bp->b_next->b_prev = bp->b_prev;
- bp->b_prev = &bufhead;
- bp->b_next = bufhead.b_next;
- bufhead.b_next->b_prev = bp;
- bufhead.b_next = bp;
- bp->b_flags |= B_INUSE;
- return (bp);
-}
-
-void
-getblk(bp, blk, size)
- register struct bufarea *bp;
- ufs_daddr_t blk;
- long size;
-{
- ufs_daddr_t dblk;
-
- dblk = fsbtodb(&sblock, blk);
- if (bp->b_bno != dblk) {
- flush(fswritefd, bp);
- diskreads++;
- bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
- bp->b_bno = dblk;
- bp->b_size = size;
- }
-}
-
-void
-flush(fd, bp)
- int fd;
- register struct bufarea *bp;
-{
- register int i, j;
-
- if (!bp->b_dirty)
- return;
- if (bp->b_errs != 0)
- pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n",
- (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
- bp->b_bno);
- bp->b_dirty = 0;
- bp->b_errs = 0;
- bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
- if (bp != &sblk)
- return;
- for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
- bwrite(fswritefd, (char *)sblock.fs_csp[j],
- fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
- sblock.fs_cssize - i < sblock.fs_bsize ?
- sblock.fs_cssize - i : sblock.fs_bsize);
- }
-}
-
-static void
-rwerror(mesg, blk)
- char *mesg;
- ufs_daddr_t blk;
-{
-
- if (preen == 0)
- printf("\n");
- pfatal("CANNOT %s: BLK %ld", mesg, blk);
- if (reply("CONTINUE") == 0)
- exit(EEXIT);
-}
-
-void
-ckfini(markclean)
- int markclean;
-{
- register struct bufarea *bp, *nbp;
- int ofsmodified, cnt = 0;
-
- if (fswritefd < 0) {
- (void)close(fsreadfd);
- return;
- }
- flush(fswritefd, &sblk);
- if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
- !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
- sblk.b_bno = SBOFF / dev_bsize;
- sbdirty();
- flush(fswritefd, &sblk);
- }
- flush(fswritefd, &cgblk);
- free(cgblk.b_un.b_buf);
- for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) {
- cnt++;
- flush(fswritefd, bp);
- nbp = bp->b_prev;
- free(bp->b_un.b_buf);
- free((char *)bp);
- }
- if (bufhead.b_size != cnt)
- errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
- pbp = pdirbp = (struct bufarea *)0;
- if (sblock.fs_clean != markclean) {
- sblock.fs_clean = markclean;
- sbdirty();
- ofsmodified = fsmodified;
- flush(fswritefd, &sblk);
- fsmodified = ofsmodified;
- if (!preen) {
- 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)
- printf("cache missed %ld of %ld (%d%%)\n", diskreads,
- totalreads, (int)(diskreads * 100 / totalreads));
- (void)close(fsreadfd);
- (void)close(fswritefd);
-}
-
-int
-bread(fd, buf, blk, size)
- int fd;
- char *buf;
- ufs_daddr_t blk;
- long size;
-{
- char *cp;
- int i, errs;
- off_t offset;
-
- offset = blk;
- offset *= dev_bsize;
- if (lseek(fd, offset, 0) < 0)
- rwerror("SEEK", blk);
- else if (read(fd, buf, (int)size) == size)
- return (0);
- rwerror("READ", blk);
- if (lseek(fd, offset, 0) < 0)
- rwerror("SEEK", blk);
- errs = 0;
- memset(buf, 0, (size_t)size);
- printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
- for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
- if (read(fd, cp, (int)secsize) != secsize) {
- (void)lseek(fd, offset + i + secsize, 0);
- if (secsize != dev_bsize && dev_bsize != 1)
- printf(" %ld (%ld),",
- (blk * dev_bsize + i) / secsize,
- blk + i / dev_bsize);
- else
- printf(" %ld,", blk + i / dev_bsize);
- errs++;
- }
- }
- printf("\n");
- if (errs)
- resolved = 0;
- return (errs);
-}
-
-void
-bwrite(fd, buf, blk, size)
- int fd;
- char *buf;
- ufs_daddr_t blk;
- long size;
-{
- int i;
- char *cp;
- off_t offset;
-
- if (fd < 0)
- return;
- offset = blk;
- offset *= dev_bsize;
- if (lseek(fd, offset, 0) < 0)
- rwerror("SEEK", blk);
- else if (write(fd, buf, (int)size) == size) {
- fsmodified = 1;
- return;
- }
- resolved = 0;
- rwerror("WRITE", blk);
- if (lseek(fd, offset, 0) < 0)
- rwerror("SEEK", blk);
- printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
- for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
- if (write(fd, cp, (int)dev_bsize) != dev_bsize) {
- (void)lseek(fd, offset + i + dev_bsize, 0);
- printf(" %ld,", blk + i / dev_bsize);
- }
- printf("\n");
- return;
-}
-
-/*
- * allocate a data block with the specified number of fragments
- */
-ufs_daddr_t
-allocblk(frags)
- long frags;
-{
- int i, j, k, cg, baseblk;
- struct cg *cgp = &cgrp;
-
- if (frags <= 0 || frags > sblock.fs_frag)
- return (0);
- for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) {
- for (j = 0; j <= sblock.fs_frag - frags; j++) {
- if (testbmap(i + j))
- continue;
- for (k = 1; k < frags; k++)
- if (testbmap(i + j + k))
- break;
- if (k < frags) {
- j += k;
- continue;
- }
- cg = dtog(&sblock, i + j);
- getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
- if (!cg_chkmagic(cgp))
- pfatal("CG %d: BAD MAGIC NUMBER\n", cg);
- baseblk = dtogd(&sblock, i + j);
- for (k = 0; k < frags; k++) {
- setbmap(i + j + k);
- clrbit(cg_blksfree(cgp), baseblk + k);
- }
- n_blks += frags;
- if (frags == sblock.fs_frag)
- cgp->cg_cs.cs_nbfree--;
- else
- cgp->cg_cs.cs_nffree -= frags;
- cgdirty();
- return (i + j);
- }
- }
- return (0);
-}
-
-/*
- * Free a previously allocated block
- */
-void
-freeblk(blkno, frags)
- ufs_daddr_t blkno;
- long frags;
-{
- struct inodesc idesc;
-
- idesc.id_blkno = blkno;
- idesc.id_numfrags = frags;
- (void)pass4check(&idesc);
-}
-
-/*
- * Find a pathname
- */
-void
-getpathname(namebuf, curdir, ino)
- char *namebuf;
- ino_t curdir, ino;
-{
- int len;
- register char *cp;
- struct inodesc idesc;
- static int busy = 0;
-
- if (curdir == ino && ino == ROOTINO) {
- (void)strcpy(namebuf, "/");
- return;
- }
- if (busy ||
- (inoinfo(curdir)->ino_state != DSTATE &&
- inoinfo(curdir)->ino_state != DFOUND)) {
- (void)strcpy(namebuf, "?");
- return;
- }
- busy = 1;
- memset(&idesc, 0, sizeof(struct inodesc));
- idesc.id_type = DATA;
- idesc.id_fix = IGNORE;
- cp = &namebuf[MAXPATHLEN - 1];
- *cp = '\0';
- if (curdir != ino) {
- idesc.id_parent = curdir;
- goto namelookup;
- }
- while (ino != ROOTINO) {
- idesc.id_number = ino;
- idesc.id_func = findino;
- idesc.id_name = "..";
- if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
- break;
- namelookup:
- idesc.id_number = idesc.id_parent;
- idesc.id_parent = ino;
- idesc.id_func = findname;
- idesc.id_name = namebuf;
- if ((ckinode(ginode(idesc.id_number), &idesc)&FOUND) == 0)
- break;
- len = strlen(namebuf);
- cp -= len;
- memmove(cp, namebuf, (size_t)len);
- *--cp = '/';
- if (cp < &namebuf[MAXNAMLEN])
- break;
- ino = idesc.id_number;
- }
- busy = 0;
- if (ino != ROOTINO)
- *--cp = '?';
- memmove(namebuf, cp, (size_t)(&namebuf[MAXPATHLEN] - cp));
-}
-
-void
-catch(sig)
- int sig;
-{
- if (!doinglevel2)
- ckfini(0);
- exit(12);
-}
-
-/*
- * When preening, allow a single quit to signal
- * a special exit after filesystem checks complete
- * so that reboot sequence may be interrupted.
- */
-void
-catchquit(sig)
- int sig;
-{
- printf("returning to single-user after filesystem check\n");
- returntosingle = 1;
- (void)signal(SIGQUIT, SIG_DFL);
-}
-
-/*
- * Ignore a single quit signal; wait and flush just in case.
- * Used by child processes in preen.
- */
-void
-voidquit(sig)
- int sig;
-{
-
- sleep(1);
- (void)signal(SIGQUIT, SIG_IGN);
- (void)signal(SIGQUIT, SIG_DFL);
-}
-
-/*
- * determine whether an inode should be fixed.
- */
-int
-dofix(idesc, msg)
- register struct inodesc *idesc;
- char *msg;
-{
-
- switch (idesc->id_fix) {
-
- case DONTKNOW:
- if (idesc->id_type == DATA)
- direrror(idesc->id_number, msg);
- else
- pwarn("%s", msg);
- if (preen) {
- printf(" (SALVAGED)\n");
- idesc->id_fix = FIX;
- return (ALTERED);
- }
- if (reply("SALVAGE") == 0) {
- idesc->id_fix = NOFIX;
- return (0);
- }
- idesc->id_fix = FIX;
- return (ALTERED);
-
- case FIX:
- return (ALTERED);
-
- case NOFIX:
- case IGNORE:
- return (0);
-
- default:
- errx(EEXIT, "UNKNOWN INODESC FIX MODE %d", idesc->id_fix);
- }
- /* NOTREACHED */
- return (0);
-}
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-/*
- * An unexpected inconsistency occured.
- * Die if preening or filesystem is running with soft dependency protocol,
- * otherwise just print message and continue.
- */
-void
-#if __STDC__
-pfatal(const char *fmt, ...)
-#else
-pfatal(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- if (!preen) {
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- if (usedsoftdep)
- (void)fprintf(stderr,
- "\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
- return;
- }
- if (cdevname == NULL)
- cdevname = "fsck";
- (void)fprintf(stderr, "%s: ", cdevname);
- (void)vfprintf(stderr, fmt, ap);
- (void)fprintf(stderr,
- "\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
- cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
- ckfini(0);
- exit(EEXIT);
-}
-
-/*
- * Pwarn just prints a message when not preening or running soft dependency
- * protocol, or a warning (preceded by filename) when preening.
- */
-void
-#if __STDC__
-pwarn(const char *fmt, ...)
-#else
-pwarn(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- if (preen)
- (void)fprintf(stderr, "%s: ", cdevname);
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-
-/*
- * Stub for routines from kernel.
- */
-void
-#if __STDC__
-panic(const char *fmt, ...)
-#else
-panic(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-#if __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- pfatal("INTERNAL INCONSISTENCY:");
- (void)vfprintf(stderr, fmt, ap);
- va_end(ap);
- exit(EEXIT);
-}
diff --git a/sbin/fsdb/Makefile b/sbin/fsdb/Makefile
index ef842c9..972bf8e 100644
--- a/sbin/fsdb/Makefile
+++ b/sbin/fsdb/Makefile
@@ -5,11 +5,11 @@
PROG= fsdb
MAN8= fsdb.8
SRCS= fsdb.c fsdbutil.c \
- dir.c inode.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
+ dir.c fsutil.c inode.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
-CFLAGS+= -I${.CURDIR}/../fsck
+CFLAGS+= -I${.CURDIR}/../fsck_ffs
LDADD+= -ledit -ltermcap
DPADD+= ${LIBEDIT} ${LIBTERMCAP}
-.PATH: ${.CURDIR}/../fsck ${.CURDIR}/../../sys/ufs/ffs
+.PATH: ${.CURDIR}/../fsck_ffs ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk>
diff --git a/sbin/quotacheck/Makefile b/sbin/quotacheck/Makefile
index 7f929c8..7240fb9 100644
--- a/sbin/quotacheck/Makefile
+++ b/sbin/quotacheck/Makefile
@@ -1,8 +1,9 @@
+# $FreeBSD$
# @(#)Makefile 8.1 (Berkeley) 6/5/93
PROG= quotacheck
-SRCS= quotacheck.c preen.c
+SRCS= quotacheck.c preen.c utilities.c
MAN8= quotacheck.8
-.PATH: ${.CURDIR}/../fsck
+.PATH: ${.CURDIR}/../fsck_ffs
.include <bsd.prog.mk>
OpenPOWER on IntegriCloud