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 <afs/param.h>
19 #include <afsconfig.h>
24 #include <sys/param.h>
27 #include <sys/vnode.h>
28 #include <sys/mount.h>
29 #include <ufs/inode.h>
37 #else /* AFS_OSF_ENV */
38 #ifdef AFS_VFSINCL_ENV
39 #include <sys/vnode.h>
43 #include <sys/fs/ufs_inode.h>
44 #include <sys/fs/ufs_fs.h>
46 #include <sys/fs/ufs_fsdir.h>
48 #include <sys/fs/ufs_mount.h>
50 #include <ufs/inode.h>
53 #else /* AFS_VFSINCL_ENV */
54 #include <sys/inode.h>
59 #define LONGFILENAMES 1
60 #include <sys/sysmacros.h>
64 #endif /* AFS_VFSINCL_ENV */
65 #endif /* AFS_OSF_ENV */
67 #include <afs/osi_inode.h>
70 static daddr_t badblk;
71 static daddr_t dupblk;
77 register struct dinode *dp;
84 * Set file system reserved blocks in used block map.
86 for (c = 0; c < sblock.fs_ncg; c++) {
87 cgd = cgdmin(&sblock, c);
89 i = cgbase(&sblock, c);
90 cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
92 i = cgsblock(&sblock, c);
97 * Find all allocated blocks.
99 bzero((char *)&idesc, sizeof(struct inodesc));
100 idesc.id_type = ADDR;
101 idesc.id_func = pass1check;
103 n_files = n_blks = 0;
107 for (c = 0; c < sblock.fs_ncg; c++) {
108 for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
109 if (inumber < ROOTINO)
111 dp = ginode(inumber);
112 if ((dp->di_mode & IFMT) == 0) {
113 if (bcmp((char *)dp->di_db, (char *)zino.di_db,
114 NDADDR * sizeof(daddr_t)) ||
115 bcmp((char *)dp->di_ib, (char *)zino.di_ib,
116 NIADDR * sizeof(daddr_t)) ||
117 #if defined(ACLS) && defined(AFS_HPUX_ENV)
118 dp->di_mode || dp->di_size || dp->di_contin) {
119 if (dp->di_contin != 0)
120 pwarn("UNALLOCATED INODE HAS BAD ic_contin VALUE %d", dp->di_contin);
123 dp->di_mode || dp->di_size) {
126 pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber);
127 if (reply("CLEAR") == 1) {
136 statemap[inumber] = USTATE;
140 #if defined(ACLS) && defined(AFS_HPUX_ENV)
142 * Don't check blocks and sizes of
143 * continuation inodes
146 statemap[inumber] = CSTATE;
147 lncntp[inumber] = dp->di_nlink;
152 #if defined(AFS_SUN56_ENV)
153 if (dp->di_size < 0 ||
154 dp->di_size > (UOFF_T)UFS_MAXOFFSET_T) {
156 printf("bad size %llu:", dp->di_size);
160 if (dp->di_size < 0 ||
161 dp->di_size + sblock.fs_bsize - 1 < 0) {
163 printf("bad size %d:", dp->di_size);
167 #if defined(AFS_HPUX_ENV)
168 /* initialize all R/W activities of FIFO file */
169 /* make sure FIFO is empty (everything is 0) */
170 if ((dp->di_mode & IFMT) == IFIFO && (dp->di_frcnt!=0 || dp->di_fwcnt!=0)) {
172 pwarn("NON-ZERO READER/WRITER COUNT(S) ON PIPE I=%u",inumber);
174 printf(" (CORRECTED)\n");
176 if (reply("CORRECT") == 0)
188 for (j = ndb; j < NDADDR; j++)
194 * Fast symlink -- verify that the size is valid and that the length
195 * of the path is correct.
198 if (dp->di_size >= MAX_FASTLINK_SIZE) {
200 printf("bad fastlink size %d:", dp->di_size);
203 dp->di_symlink[MAX_FASTLINK_SIZE-1] = '\0';
204 if (strlen(dp->di_symlink) != dp->di_size) {
205 int len = strlen(dp->di_symlink);
206 pwarn("BAD SYMLINK SIZE, SHOULD BE %d: size = %d", len, dp->di_size);
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_SUN56_ENV)
240 printf("bad size %lld 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",
269 for (j = 0, ndb -= NDADDR; ndb > 0; j++)
270 ndb /= NINDIR(&sblock);
271 for (; j < NIADDR; j++)
272 if (dp->di_ib[j] != 0) {
274 if ((dp->di_mode & IFMT) != IFIFO) {
277 printf("bad indirect addr: %d\n",
285 #if defined(AFS_HPUX_ENV)
286 ignore_direct_block_check:
290 #endif /* AFS_OSF_ENV */
291 if (ftypeok(dp) == 0)
294 lncntp[inumber] = dp->di_nlink;
295 if (dp->di_nlink <= 0) {
296 zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
298 pfatal("LINK COUNT TABLE OVERFLOW");
299 if (reply("CONTINUE") == 0)
302 zlnp->zlncnt = inumber;
303 zlnp->next = zlnhead;
307 #if defined(AFS_SUN56_ENV)
310 /* This looks like a sol 2.5 AFS inode */
311 printf("This vicep partition seems to contain pre Sol2.6 AFS inodes\n");
312 printf("You should run the AFS file conversion utility before installing Sol 2.6\n");
313 exit(100); /* unique return code? */
318 (dp->di_mode & IFMT) == IFDIR ? DSTATE : (VICEINODE? VSTATE : FSTATE);
320 (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE;
322 #if defined(ACLS) && defined(AFS_HPUX_ENV)
324 * keep track of associated contin inodes
326 if (dp->di_contin != 0)
327 statemap[inumber] |= HASCINODE;
330 idesc.id_number = inumber;
331 idesc.id_entryno = 0;
333 idesc.id_fix = DONTKNOW;
335 (void)ckinode(dp, &idesc);
337 idesc.id_entryno *= btodb(sblock.fs_fsize);
339 if (dp->di_blocks != idesc.id_entryno) {
340 pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
341 inumber, dp->di_blocks, idesc.id_entryno);
343 printf(" (CORRECTED)\n");
344 else if (reply("CORRECT") == 0)
347 dp = ginode(inumber);
349 dp->di_blocks = idesc.id_entryno;
353 if ((dp->di_mode & IFMT) == IFDIR)
354 if (dp->di_blocks == 0)
355 statemap[inumber] = DCLEAR;
359 pfatal("UNKNOWN FILE TYPE I=%u", inumber);
361 if ((dp->di_mode & IFMT) == IFDIR) {
362 statemap[inumber] = DCLEAR;
364 cacheino(dp, inumber);
368 statemap[inumber] = FCLEAR;
369 if (reply("CLEAR") == 1) {
370 statemap[inumber] = USTATE;
383 register struct inodesc *idesc;
387 daddr_t blkno = idesc->id_blkno;
388 register struct dups *dlp;
391 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
392 blkerror(idesc->id_number, "BAD", blkno);
393 if (++badblk >= MAXBAD) {
394 pwarn("EXCESSIVE BAD BLKS I=%u",
397 printf(" (SKIPPING)\n");
398 else if (reply("CONTINUE") == 0)
406 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
407 if (anyout && chkrange(blkno, 1)) {
409 } else if (!testbmap(blkno)) {
413 blkerror(idesc->id_number, "DUP", blkno);
414 if (++dupblk >= MAXDUP) {
415 pwarn("EXCESSIVE DUP BLKS I=%u",
418 printf(" (SKIPPING)\n");
419 else if (reply("CONTINUE") == 0)
426 new = (struct dups *)malloc(sizeof(struct dups));
428 pfatal("DUP TABLE OVERFLOW.");
429 if (reply("CONTINUE") == 0)
435 duplist = muldup = new;
438 new->next = muldup->next;
441 for (dlp = duplist; dlp != muldup; dlp = dlp->next)
442 if (dlp->dup == blkno)
444 if (dlp == muldup && dlp->dup != blkno)
448 * count the number of blocks found in id_entryno