2 * Copyright (c) 1980, 1986 The Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 #include <afsconfig.h>
19 #include <afs/param.h>
27 #include <sys/vnode.h>
28 #include <sys/mount.h>
29 #include <ufs/inode.h>
36 #else /* AFS_OSF_ENV */
37 #ifdef AFS_VFSINCL_ENV
38 #include <sys/vnode.h>
40 #include <sys/fs/ufs_inode.h>
41 #include <sys/fs/ufs_fs.h>
43 #include <sys/fs/ufs_fsdir.h>
45 #include <sys/fs/ufs_mount.h>
47 #include <ufs/inode.h>
50 #else /* AFS_VFSINCL_ENV */
51 #include <sys/inode.h>
55 #define LONGFILENAMES 1
56 #include <sys/sysmacros.h>
60 #endif /* AFS_VFSINCL_ENV */
61 #endif /* AFS_OSF_ENV */
63 #include <afs/osi_inode.h>
66 static daddr_t badblk
;
67 static daddr_t dupblk
;
69 static int oldreported
;
81 * Set file system reserved blocks in used block map.
83 for (c
= 0; c
< sblock
.fs_ncg
; c
++) {
84 cgd
= cgdmin(&sblock
, c
);
86 i
= cgbase(&sblock
, c
);
87 cgd
+= howmany(sblock
.fs_cssize
, sblock
.fs_fsize
);
89 i
= cgsblock(&sblock
, c
);
94 * Find all allocated blocks.
96 memset(&idesc
, 0, sizeof(struct inodesc
));
98 idesc
.id_func
= pass1check
;
100 n_files
= n_blks
= 0;
104 for (c
= 0; c
< sblock
.fs_ncg
; c
++) {
105 for (i
= 0; i
< sblock
.fs_ipg
; i
++, inumber
++) {
106 if (inumber
< ROOTINO
)
108 dp
= ginode(inumber
);
109 if ((dp
->di_mode
& IFMT
) == 0) {
111 ((char *)dp
->di_db
, (char *)zino
.di_db
,
112 NDADDR
* sizeof(daddr_t
))
113 || memcmp((char *)dp
->di_ib
, (char *)zino
.di_ib
,
114 NIADDR
* sizeof(daddr_t
)) ||
115 #if defined(ACLS) && defined(AFS_HPUX_ENV)
116 dp
->di_mode
|| dp
->di_size
|| dp
->di_contin
) {
117 if (dp
->di_contin
!= 0)
118 pwarn("UNALLOCATED INODE HAS BAD ic_contin VALUE %d",
122 dp
->di_mode
|| dp
->di_size
) {
125 pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber
);
126 if (reply("CLEAR") == 1) {
135 statemap
[inumber
] = USTATE
;
139 #if defined(ACLS) && defined(AFS_HPUX_ENV)
141 * Don't check blocks and sizes of
142 * continuation inodes
145 statemap
[inumber
] = CSTATE
;
146 lncntp
[inumber
] = dp
->di_nlink
;
151 #if defined(AFS_SUN5_ENV)
152 if (dp
->di_size
< 0 || dp
->di_size
> (UOFF_T
) UFS_MAXOFFSET_T
) {
154 printf("bad size %llu:", dp
->di_size
);
158 if (dp
->di_size
< 0 || dp
->di_size
+ sblock
.fs_bsize
- 1 < 0) {
160 printf("bad size %d:", dp
->di_size
);
164 #if defined(AFS_HPUX_ENV)
165 /* initialize all R/W activities of FIFO file */
166 /* make sure FIFO is empty (everything is 0) */
167 if ((dp
->di_mode
& IFMT
) == IFIFO
168 && (dp
->di_frcnt
!= 0 || dp
->di_fwcnt
!= 0)) {
170 pwarn("NON-ZERO READER/WRITER COUNT(S) ON PIPE I=%u",
173 printf(" (CORRECTED)\n");
175 if (reply("CORRECT") == 0)
187 for (j
= ndb
; j
< NDADDR
; j
++)
193 * Fast symlink -- verify that the size is valid and that the length
194 * of the path is correct.
197 if (dp
->di_size
>= MAX_FASTLINK_SIZE
) {
199 printf("bad fastlink size %d:", dp
->di_size
);
202 dp
->di_symlink
[MAX_FASTLINK_SIZE
- 1] = '\0';
203 if (strlen(dp
->di_symlink
) != dp
->di_size
) {
204 int len
= strlen(dp
->di_symlink
);
205 pwarn("BAD SYMLINK SIZE, SHOULD BE %d: size = %d", len
,
208 printf(" (CORRECTED)\n");
212 if (reply("CORRECT") == 0)
218 goto ignore_direct_block_check
;
220 #endif /* IC_FASTLINK */
223 if (!preen
&& (dp
->di_mode
& IFMT
) == IFMT
224 && reply("HOLD BAD BLOCK") == 1) {
225 dp
->di_size
= sblock
.fs_fsize
;
226 dp
->di_mode
= IFREG
| 0600;
229 ndb
= howmany(dp
->di_size
, (UOFF_T
) sblock
.fs_bsize
);
231 if (dp
->di_oeftflag
== oEFT_MAGIC
) {
232 dp
->di_oeftflag
= 0; /* XXX migration aid */
239 #if defined(AFS_SUN5_ENV)
240 printf("bad size %" AFS_INT64_FMT
" ndb %d:",
242 printf("bad size %d ndb %d:",
247 if ((dp
->di_mode
& IFMT
) == IFBLK
248 || (dp
->di_mode
& IFMT
) == IFCHR
)
251 if ((dp
->di_flags
& IC_FASTLINK
) == 0) {
252 #endif /* AFS_OSF_ENV */
253 for (j
= ndb
; j
< NDADDR
; j
++) {
254 #if defined(AFS_HPUX_ENV) && (defined(DUX) || defined(CNODE_DEV))
256 * DUX uses db[2] on cnode-specific
257 * device files, so skip 'em
259 if (j
== 2 && SPECIAL
)
262 if (dp
->di_db
[j
] != 0) {
264 printf("bad direct addr: %d\n", dp
->di_db
[j
]);
268 for (j
= 0, ndb
-= NDADDR
; ndb
> 0; j
++)
269 ndb
/= NINDIR(&sblock
);
270 for (; j
< NIADDR
; j
++)
271 if (dp
->di_ib
[j
] != 0) {
273 if ((dp
->di_mode
& IFMT
) != IFIFO
) {
276 printf("bad indirect addr: %d\n",
284 #if defined(AFS_HPUX_ENV)
285 ignore_direct_block_check
:
289 #endif /* AFS_OSF_ENV */
290 if (ftypeok(dp
) == 0)
293 lncntp
[inumber
] = dp
->di_nlink
;
294 if (dp
->di_nlink
<= 0) {
295 zlnp
= malloc(sizeof *zlnp
);
297 pfatal("LINK COUNT TABLE OVERFLOW");
298 if (reply("CONTINUE") == 0)
301 zlnp
->zlncnt
= inumber
;
302 zlnp
->next
= zlnhead
;
306 #if defined(AFS_SUN5_ENV)
311 ("This vicep partition seems to contain pre Sol2.6 AFS inodes\n");
313 ("You should run the AFS file conversion utility before installing Sol 2.6\n");
314 printf("Continuing anyway.\n");
318 /* This looks like a sol 2.5 AFS inode */
320 ("This vicep partition seems to contain pre Sol2.6 AFS inodes\n");
322 ("You should run the AFS file conversion utility before installing Sol 2.6\n");
323 exit(100); /* unique return code? */
329 (dp
->di_mode
& IFMT
) ==
330 IFDIR
? DSTATE
: (VICEINODE
? VSTATE
: FSTATE
);
332 (dp
->di_mode
& IFMT
) == IFDIR
? DSTATE
: FSTATE
;
334 #if defined(ACLS) && defined(AFS_HPUX_ENV)
336 * keep track of associated contin inodes
338 if (dp
->di_contin
!= 0)
339 statemap
[inumber
] |= HASCINODE
;
342 idesc
.id_number
= inumber
;
343 idesc
.id_entryno
= 0;
345 idesc
.id_fix
= DONTKNOW
;
347 (void)ckinode(dp
, &idesc
);
349 idesc
.id_entryno
*= btodb(sblock
.fs_fsize
);
351 if (dp
->di_blocks
!= idesc
.id_entryno
) {
352 pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
353 inumber
, dp
->di_blocks
, idesc
.id_entryno
);
355 printf(" (CORRECTED)\n");
356 else if (reply("CORRECT") == 0)
359 dp
= ginode(inumber
);
361 dp
->di_blocks
= idesc
.id_entryno
;
365 if ((dp
->di_mode
& IFMT
) == IFDIR
)
366 if (dp
->di_blocks
== 0)
367 statemap
[inumber
] = DCLEAR
;
371 pfatal("UNKNOWN FILE TYPE I=%u", inumber
);
373 if ((dp
->di_mode
& IFMT
) == IFDIR
) {
374 statemap
[inumber
] = DCLEAR
;
376 cacheino(dp
, inumber
);
380 statemap
[inumber
] = FCLEAR
;
381 if (reply("CLEAR") == 1) {
382 statemap
[inumber
] = USTATE
;
395 struct inodesc
*idesc
;
399 daddr_t blkno
= idesc
->id_blkno
;
403 if ((anyout
= chkrange(blkno
, idesc
->id_numfrags
)) != 0) {
404 blkerror(idesc
->id_number
, "BAD", blkno
);
405 if (++badblk
>= MAXBAD
) {
406 pwarn("EXCESSIVE BAD BLKS I=%u", idesc
->id_number
);
408 printf(" (SKIPPING)\n");
409 else if (reply("CONTINUE") == 0)
417 for (nfrags
= idesc
->id_numfrags
; nfrags
> 0; blkno
++, nfrags
--) {
418 if (anyout
&& chkrange(blkno
, 1)) {
420 } else if (!testbmap(blkno
)) {
424 blkerror(idesc
->id_number
, "DUP", blkno
);
425 if (++dupblk
>= MAXDUP
) {
426 pwarn("EXCESSIVE DUP BLKS I=%u", idesc
->id_number
);
428 printf(" (SKIPPING)\n");
429 else if (reply("CONTINUE") == 0)
436 new = malloc(sizeof(struct dups
));
438 pfatal("DUP TABLE OVERFLOW.");
439 if (reply("CONTINUE") == 0)
445 duplist
= muldup
= new;
448 new->next
= muldup
->next
;
451 for (dlp
= duplist
; dlp
!= muldup
; dlp
= dlp
->next
)
452 if (dlp
->dup
== blkno
)
454 if (dlp
== muldup
&& dlp
->dup
!= blkno
)
458 * count the number of blocks found in id_entryno