2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * @(#)pass1.c 8.6 (Berkeley) 4/28/95
30 * $FreeBSD: src/sbin/fsck/pass1.c,v 1.16.2.5 2002/06/23 22:34:58 iedowse Exp $
33 #include <sys/param.h>
35 #include <vfs/ufs/dinode.h>
36 #include <vfs/ufs/dir.h>
37 #include <vfs/ufs/fs.h>
44 struct inostatlist
*inostathead
; /* A list of inode state information */
45 struct dups
*muldup
; /* end of unique duplicate dup block numbers */
46 long countdirs
; /* number of directories we actually found */
47 ufs_daddr_t n_blks
; /* number of blocks in use */
48 ufs_daddr_t n_files
; /* number of files in use */
50 static ufs_daddr_t badblk
;
51 static ufs_daddr_t dupblk
;
52 static ufs1_ino_t lastino
; /* last inode in use */
54 static void checkinode(ufs1_ino_t inumber
, struct inodesc
*);
61 int c
, i
, cgd
, inosused
;
66 * Set file system reserved blocks in used block map.
68 for (c
= 0; c
< sblock
.fs_ncg
; c
++) {
69 cgd
= cgdmin(&sblock
, c
);
71 i
= cgbase(&sblock
, c
);
73 i
= cgsblock(&sblock
, c
);
78 cgd
= i
+ howmany(sblock
.fs_cssize
, sblock
.fs_fsize
);
82 * Find all allocated blocks.
84 memset(&idesc
, 0, sizeof(struct inodesc
));
86 idesc
.id_func
= pass1check
;
88 for (c
= 0; c
< sblock
.fs_ncg
; c
++) {
89 inumber
= c
* sblock
.fs_ipg
;
91 inosused
= sblock
.fs_ipg
;
93 printf("%s: phase 1: cyl group %d of %d (%d%%)\n",
94 cdevname
, c
, sblock
.fs_ncg
,
95 c
* 100 / sblock
.fs_ncg
);
99 * If we are using soft updates, then we can trust the
100 * cylinder group inode allocation maps to tell us which
101 * inodes are allocated. We will scan the used inode map
102 * to find the inodes that are really in use, and then
103 * read only those inodes in from disk.
105 if (preen
&& usedsoftdep
) {
106 getblk(&cgblk
, cgtod(&sblock
, c
), sblock
.fs_cgsize
);
107 if (!cg_chkmagic(&cgrp
))
108 pfatal("CG %d: BAD MAGIC NUMBER\n", c
);
109 cp
= &cg_inosused(&cgrp
)[(sblock
.fs_ipg
- 1) / NBBY
];
110 for ( ; inosused
> 0; inosused
-= NBBY
, cp
--) {
113 for (i
= 1 << (NBBY
- 1); i
> 0; i
>>= 1) {
124 * Allocate inoinfo structures for the allocated inodes.
126 inostathead
[c
].il_numalloced
= inosused
;
128 inostathead
[c
].il_stat
= 0;
131 info
= calloc((unsigned)inosused
, sizeof(struct inostat
));
133 pfatal("cannot alloc %u bytes for inoinfo\n",
134 (unsigned)(sizeof(struct inostat
) * inosused
));
135 inostathead
[c
].il_stat
= info
;
137 * Scan the allocated inodes.
139 for (i
= 0; i
< inosused
; i
++, inumber
++) {
140 if (inumber
< UFS_ROOTINO
) {
141 getnextinode(inumber
);
144 checkinode(inumber
, &idesc
);
147 if (inosused
< sblock
.fs_ipg
|| inumber
== lastino
)
150 * If we were not able to determine in advance which inodes
151 * were in use, then reduce the size of the inoinfo structure
152 * to the size necessary to describe the inodes that we
155 inosused
= lastino
- (c
* sblock
.fs_ipg
);
158 inostathead
[c
].il_numalloced
= inosused
;
160 free(inostathead
[c
].il_stat
);
161 inostathead
[c
].il_stat
= 0;
164 info
= calloc((unsigned)inosused
, sizeof(struct inostat
));
166 pfatal("cannot alloc %u bytes for inoinfo\n",
167 (unsigned)(sizeof(struct inostat
) * inosused
));
168 memmove(info
, inostathead
[c
].il_stat
, inosused
* sizeof(*info
));
169 free(inostathead
[c
].il_stat
);
170 inostathead
[c
].il_stat
= info
;
176 checkinode(ufs1_ino_t inumber
, struct inodesc
*idesc
)
178 struct ufs1_dinode
*dp
;
180 u_int64_t kernmaxfilesize
;
185 dp
= getnextinode(inumber
);
186 mode
= dp
->di_mode
& IFMT
;
188 if (memcmp(dp
->di_db
, zino
.di_db
,
189 UFS_NDADDR
* sizeof(ufs_daddr_t
)) ||
190 memcmp(dp
->di_ib
, zino
.di_ib
,
191 UFS_NIADDR
* sizeof(ufs_daddr_t
)) ||
192 dp
->di_mode
|| dp
->di_size
) {
193 pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber
);
194 if (reply("CLEAR") == 1) {
195 dp
= ginode(inumber
);
200 inoinfo(inumber
)->ino_state
= USTATE
;
204 /* This should match the file size limit in ffs_mountfs(). */
205 kernmaxfilesize
= (u_int64_t
)0x40000000 * sblock
.fs_bsize
- 1;
206 if (kernmaxfilesize
> (u_int64_t
)0x80000000u
* PAGE_SIZE
- 1)
207 kernmaxfilesize
= (u_int64_t
)0x80000000u
* PAGE_SIZE
- 1;
208 if (dp
->di_size
> kernmaxfilesize
||
209 dp
->di_size
> sblock
.fs_maxfilesize
||
210 (mode
== IFDIR
&& dp
->di_size
> MAXDIRSIZE
)) {
212 printf("bad size %ju:", (uintmax_t)dp
->di_size
);
215 if (!preen
&& mode
== IFMT
&& reply("HOLD BAD BLOCK") == 1) {
216 dp
= ginode(inumber
);
217 dp
->di_size
= sblock
.fs_fsize
;
218 dp
->di_mode
= IFREG
|0600;
221 if ((mode
== IFBLK
|| mode
== IFCHR
|| mode
== IFIFO
||
222 mode
== IFSOCK
) && dp
->di_size
!= 0) {
224 printf("bad special-file size %ju:", (uintmax_t)dp
->di_size
);
227 ndb
= howmany(dp
->di_size
, sblock
.fs_bsize
);
230 printf("bad size %ju ndb %d:",
231 (uintmax_t)dp
->di_size
, ndb
);
234 if (mode
== IFBLK
|| mode
== IFCHR
)
238 dp
->di_size
> 0 && dp
->di_size
< UFS1_MAXSYMLINKLEN
&&
239 dp
->di_blocks
!= 0) {
240 symbuf
= alloca(secsize
);
241 if (bread(fsreadfd
, symbuf
,
242 fsbtodb(&sblock
, dp
->di_db
[0]),
244 errx(EEXIT
, "cannot read symlink");
246 symbuf
[dp
->di_size
] = 0;
247 printf("convert symlink %lu(%s) of size %ld\n",
248 (u_long
)inumber
, symbuf
, (long)dp
->di_size
);
250 dp
= ginode(inumber
);
251 memmove(dp
->di_shortlink
, symbuf
, (long)dp
->di_size
);
256 * Fake ndb value so direct/indirect block checks below
257 * will detect any garbage after symlink string.
259 if (dp
->di_size
< sblock
.fs_maxsymlinklen
) {
260 ndb
= howmany(dp
->di_size
, sizeof(ufs_daddr_t
));
261 if (ndb
> UFS_NDADDR
) {
262 j
= ndb
- UFS_NDADDR
;
263 for (ndb
= 1; j
> 1; j
--)
264 ndb
*= NINDIR(&sblock
);
269 for (j
= ndb
; j
< UFS_NDADDR
; j
++)
270 if (dp
->di_db
[j
] != 0) {
272 printf("bad direct addr: %ld\n",
276 for (j
= 0, ndb
-= UFS_NDADDR
; ndb
> 0; j
++)
277 ndb
/= NINDIR(&sblock
);
278 for (; j
< UFS_NIADDR
; j
++)
279 if (dp
->di_ib
[j
] != 0) {
281 printf("bad indirect addr: %ld\n",
285 if (ftypeok(dp
) == 0)
288 inoinfo(inumber
)->ino_linkcnt
= dp
->di_nlink
;
289 if (dp
->di_nlink
<= 0) {
290 zlnp
= (struct zlncnt
*)malloc(sizeof *zlnp
);
292 pfatal("LINK COUNT TABLE OVERFLOW");
293 if (reply("CONTINUE") == 0) {
298 zlnp
->zlncnt
= inumber
;
299 zlnp
->next
= zlnhead
;
304 if (dp
->di_size
== 0)
305 inoinfo(inumber
)->ino_state
= DCLEAR
;
307 inoinfo(inumber
)->ino_state
= DSTATE
;
308 cacheino(dp
, inumber
);
311 inoinfo(inumber
)->ino_state
= FSTATE
;
312 inoinfo(inumber
)->ino_type
= IFTODT(mode
);
314 (dp
->di_ouid
!= (u_short
)-1 || dp
->di_ogid
!= (u_short
)-1)) {
315 dp
= ginode(inumber
);
316 dp
->di_uid
= dp
->di_ouid
;
318 dp
->di_gid
= dp
->di_ogid
;
323 idesc
->id_number
= inumber
;
325 idesc
->id_entryno
*= btodb(sblock
.fs_fsize
);
326 if (dp
->di_blocks
!= idesc
->id_entryno
) {
327 pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)",
328 inumber
, dp
->di_blocks
, idesc
->id_entryno
);
330 printf(" (CORRECTED)\n");
331 else if (reply("CORRECT") == 0)
333 dp
= ginode(inumber
);
334 dp
->di_blocks
= idesc
->id_entryno
;
339 pfatal("UNKNOWN FILE TYPE I=%u", inumber
);
340 inoinfo(inumber
)->ino_state
= FCLEAR
;
341 if (reply("CLEAR") == 1) {
342 inoinfo(inumber
)->ino_state
= USTATE
;
343 dp
= ginode(inumber
);
350 pass1check(struct inodesc
*idesc
)
354 ufs_daddr_t blkno
= idesc
->id_blkno
;
358 if ((anyout
= chkrange(blkno
, idesc
->id_numfrags
)) != 0) {
359 blkerror(idesc
->id_number
, "BAD", blkno
);
360 if (badblk
++ >= MAXBAD
) {
361 pwarn("EXCESSIVE BAD BLKS I=%u",
364 printf(" (SKIPPING)\n");
365 else if (reply("CONTINUE") == 0) {
372 for (nfrags
= idesc
->id_numfrags
; nfrags
> 0; blkno
++, nfrags
--) {
373 if (anyout
&& chkrange(blkno
, 1)) {
375 } else if (!testbmap(blkno
)) {
379 blkerror(idesc
->id_number
, "DUP", blkno
);
380 if (dupblk
++ >= MAXDUP
) {
381 pwarn("EXCESSIVE DUP BLKS I=%u",
384 printf(" (SKIPPING)\n");
385 else if (reply("CONTINUE") == 0) {
391 new = (struct dups
*)malloc(sizeof(struct dups
));
393 pfatal("DUP TABLE OVERFLOW.");
394 if (reply("CONTINUE") == 0) {
402 duplist
= muldup
= new;
405 new->next
= muldup
->next
;
408 for (dlp
= duplist
; dlp
!= muldup
; dlp
= dlp
->next
)
409 if (dlp
->dup
== blkno
)
411 if (dlp
== muldup
&& dlp
->dup
!= blkno
)
415 * count the number of blocks found in id_entryno