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>
25 #include <sys/param.h>
28 #include <sys/vnode.h>
29 #include <sys/mount.h>
30 #include <ufs/inode.h>
38 #else /* AFS_OSF_ENV */
39 #ifdef AFS_VFSINCL_ENV
40 #include <sys/vnode.h>
44 #include <sys/fs/ufs_inode.h>
45 #include <sys/fs/ufs_fs.h>
47 #include <sys/fs/ufs_fsdir.h>
49 #include <sys/fs/ufs_mount.h>
51 #include <ufs/inode.h>
54 #else /* AFS_VFSINCL_ENV */
55 #include <sys/inode.h>
60 #define LONGFILENAMES 1
61 #include <sys/sysmacros.h>
65 #endif /* AFS_VFSINCL_ENV */
66 #endif /* AFS_OSF_ENV */
68 #include <afs/osi_inode.h>
71 static daddr_t badblk;
72 static daddr_t dupblk;
74 static int oldreported;
79 register struct dinode *dp;
86 * Set file system reserved blocks in used block map.
88 for (c = 0; c < sblock.fs_ncg; c++) {
89 cgd = cgdmin(&sblock, c);
91 i = cgbase(&sblock, c);
92 cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
94 i = cgsblock(&sblock, c);
99 * Find all allocated blocks.
101 memset((char *)&idesc, 0, sizeof(struct inodesc));
102 idesc.id_type = ADDR;
103 idesc.id_func = pass1check;
105 n_files = n_blks = 0;
109 for (c = 0; c < sblock.fs_ncg; c++) {
110 for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
111 if (inumber < ROOTINO)
113 dp = ginode(inumber);
114 if ((dp->di_mode & IFMT) == 0) {
116 ((char *)dp->di_db, (char *)zino.di_db,
117 NDADDR * sizeof(daddr_t))
118 || memcmp((char *)dp->di_ib, (char *)zino.di_ib,
119 NIADDR * sizeof(daddr_t)) ||
120 #if defined(ACLS) && defined(AFS_HPUX_ENV)
121 dp->di_mode || dp->di_size || dp->di_contin) {
122 if (dp->di_contin != 0)
123 pwarn("UNALLOCATED INODE HAS BAD ic_contin VALUE %d",
127 dp->di_mode || dp->di_size) {
130 pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber);
131 if (reply("CLEAR") == 1) {
140 statemap[inumber] = USTATE;
144 #if defined(ACLS) && defined(AFS_HPUX_ENV)
146 * Don't check blocks and sizes of
147 * continuation inodes
150 statemap[inumber] = CSTATE;
151 lncntp[inumber] = dp->di_nlink;
156 #if defined(AFS_SUN56_ENV)
157 if (dp->di_size < 0 || dp->di_size > (UOFF_T) UFS_MAXOFFSET_T) {
159 printf("bad size %llu:", dp->di_size);
163 if (dp->di_size < 0 || dp->di_size + sblock.fs_bsize - 1 < 0) {
165 printf("bad size %d:", dp->di_size);
169 #if defined(AFS_HPUX_ENV)
170 /* initialize all R/W activities of FIFO file */
171 /* make sure FIFO is empty (everything is 0) */
172 if ((dp->di_mode & IFMT) == IFIFO
173 && (dp->di_frcnt != 0 || dp->di_fwcnt != 0)) {
175 pwarn("NON-ZERO READER/WRITER COUNT(S) ON PIPE I=%u",
178 printf(" (CORRECTED)\n");
180 if (reply("CORRECT") == 0)
192 for (j = ndb; j < NDADDR; j++)
198 * Fast symlink -- verify that the size is valid and that the length
199 * of the path is correct.
202 if (dp->di_size >= MAX_FASTLINK_SIZE) {
204 printf("bad fastlink size %d:", dp->di_size);
207 dp->di_symlink[MAX_FASTLINK_SIZE - 1] = '\0';
208 if (strlen(dp->di_symlink) != dp->di_size) {
209 int len = strlen(dp->di_symlink);
210 pwarn("BAD SYMLINK SIZE, SHOULD BE %d: size = %d", len,
213 printf(" (CORRECTED)\n");
217 if (reply("CORRECT") == 0)
223 goto ignore_direct_block_check;
225 #endif /* IC_FASTLINK */
228 if (!preen && (dp->di_mode & IFMT) == IFMT
229 && reply("HOLD BAD BLOCK") == 1) {
230 dp->di_size = sblock.fs_fsize;
231 dp->di_mode = IFREG | 0600;
234 ndb = howmany(dp->di_size, (UOFF_T) sblock.fs_bsize);
236 if (dp->di_oeftflag == oEFT_MAGIC) {
237 dp->di_oeftflag = 0; /* XXX migration aid */
244 #if defined(AFS_SUN56_ENV)
245 printf("bad size %lld ndb %d:",
247 printf("bad size %d ndb %d:",
252 if ((dp->di_mode & IFMT) == IFBLK
253 || (dp->di_mode & IFMT) == IFCHR)
256 if ((dp->di_flags & IC_FASTLINK) == 0) {
257 #endif /* AFS_OSF_ENV */
258 for (j = ndb; j < NDADDR; j++) {
259 #if defined(AFS_HPUX_ENV) && (defined(DUX) || defined(CNODE_DEV))
261 * DUX uses db[2] on cnode-specific
262 * device files, so skip 'em
264 if (j == 2 && SPECIAL)
267 if (dp->di_db[j] != 0) {
269 printf("bad direct addr: %d\n", dp->di_db[j]);
273 for (j = 0, ndb -= NDADDR; ndb > 0; j++)
274 ndb /= NINDIR(&sblock);
275 for (; j < NIADDR; j++)
276 if (dp->di_ib[j] != 0) {
278 if ((dp->di_mode & IFMT) != IFIFO) {
281 printf("bad indirect addr: %d\n",
289 #if defined(AFS_HPUX_ENV)
290 ignore_direct_block_check:
294 #endif /* AFS_OSF_ENV */
295 if (ftypeok(dp) == 0)
298 lncntp[inumber] = dp->di_nlink;
299 if (dp->di_nlink <= 0) {
300 zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
302 pfatal("LINK COUNT TABLE OVERFLOW");
303 if (reply("CONTINUE") == 0)
306 zlnp->zlncnt = inumber;
307 zlnp->next = zlnhead;
311 #if defined(AFS_SUN56_ENV)
316 ("This vicep partition seems to contain pre Sol2.6 AFS inodes\n");
318 ("You should run the AFS file conversion utility before installing Sol 2.6\n");
319 printf("Continuing anyway.\n");
323 /* This looks like a sol 2.5 AFS inode */
325 ("This vicep partition seems to contain pre Sol2.6 AFS inodes\n");
327 ("You should run the AFS file conversion utility before installing Sol 2.6\n");
328 exit(100); /* unique return code? */
334 (dp->di_mode & IFMT) ==
335 IFDIR ? DSTATE : (VICEINODE ? VSTATE : FSTATE);
337 (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
339 #if defined(ACLS) && defined(AFS_HPUX_ENV)
341 * keep track of associated contin inodes
343 if (dp->di_contin != 0)
344 statemap[inumber] |= HASCINODE;
347 idesc.id_number = inumber;
348 idesc.id_entryno = 0;
350 idesc.id_fix = DONTKNOW;
352 (void)ckinode(dp, &idesc);
354 idesc.id_entryno *= btodb(sblock.fs_fsize);
356 if (dp->di_blocks != idesc.id_entryno) {
357 pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
358 inumber, dp->di_blocks, idesc.id_entryno);
360 printf(" (CORRECTED)\n");
361 else if (reply("CORRECT") == 0)
364 dp = ginode(inumber);
366 dp->di_blocks = idesc.id_entryno;
370 if ((dp->di_mode & IFMT) == IFDIR)
371 if (dp->di_blocks == 0)
372 statemap[inumber] = DCLEAR;
376 pfatal("UNKNOWN FILE TYPE I=%u", inumber);
378 if ((dp->di_mode & IFMT) == IFDIR) {
379 statemap[inumber] = DCLEAR;
381 cacheino(dp, inumber);
385 statemap[inumber] = FCLEAR;
386 if (reply("CLEAR") == 1) {
387 statemap[inumber] = USTATE;
400 register struct inodesc *idesc;
404 daddr_t blkno = idesc->id_blkno;
405 register struct dups *dlp;
408 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
409 blkerror(idesc->id_number, "BAD", blkno);
410 if (++badblk >= MAXBAD) {
411 pwarn("EXCESSIVE BAD BLKS I=%u", idesc->id_number);
413 printf(" (SKIPPING)\n");
414 else if (reply("CONTINUE") == 0)
422 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
423 if (anyout && chkrange(blkno, 1)) {
425 } else if (!testbmap(blkno)) {
429 blkerror(idesc->id_number, "DUP", blkno);
430 if (++dupblk >= MAXDUP) {
431 pwarn("EXCESSIVE DUP BLKS I=%u", idesc->id_number);
433 printf(" (SKIPPING)\n");
434 else if (reply("CONTINUE") == 0)
441 new = (struct dups *)malloc(sizeof(struct dups));
443 pfatal("DUP TABLE OVERFLOW.");
444 if (reply("CONTINUE") == 0)
450 duplist = muldup = new;
453 new->next = muldup->next;
456 for (dlp = duplist; dlp != muldup; dlp = dlp->next)
457 if (dlp->dup == blkno)
459 if (dlp == muldup && dlp->dup != blkno)
463 * count the number of blocks found in id_entryno