/* * Copyright (c) 1980, 1986 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #define VICE #ifdef AFS_OSF_ENV #include #include #include #include #define _BSD #define _KERNEL #include #undef _KERNEL #undef _BSD #else /* AFS_OSF_ENV */ #ifdef AFS_VFSINCL_ENV #include #ifdef AFS_SUN5_ENV #include #include #define _KERNEL #include #undef _KERNEL #include #else #include #include #endif #else /* AFS_VFSINCL_ENV */ #include #ifdef AFS_HPUX_ENV #define LONGFILENAMES 1 #include #include #endif #include #endif /* AFS_VFSINCL_ENV */ #endif /* AFS_OSF_ENV */ #include #include "fsck.h" int pass4check(); pass4() { ino_t inumber; struct zlncnt *zlnp; struct inodesc idesc; int n; #if defined(ACLS) && defined(AFS_HPUX_ENV) struct dinode *dp; #endif /* ACLS */ memset(&idesc, 0, sizeof(struct inodesc)); idesc.id_type = ADDR; idesc.id_func = pass4check; for (inumber = ROOTINO; inumber <= lastino; inumber++) { idesc.id_number = inumber; #if defined(ACLS) && defined(AFS_HPUX_ENV) switch (statemap[inumber] & STATE) { #else /* no ACLS */ switch (statemap[inumber]) { #endif /* ACLS */ case FSTATE: case DFOUND: n = lncntp[inumber]; if (n) adjust(&idesc, (short)n); else { for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) if (zlnp->zlncnt == inumber) { zlnp->zlncnt = zlnhead->zlncnt; zlnp = zlnhead; zlnhead = zlnhead->next; free(zlnp); clri(&idesc, "UNREF", 1); break; } } break; #ifdef VICE case VSTATE: nViceFiles++; break; #endif /* VICE */ case DSTATE: clri(&idesc, "UNREF", 1); break; case DCLEAR: case FCLEAR: clri(&idesc, "BAD/DUP", 1); break; case USTATE: break; #if defined(ACLS) && defined(AFS_HPUX_ENV) /* * UNreferenced continuation inode */ case CSTATE: clri(&idesc, "UNREF", 2); break; /* * referenced continuation inode */ case CRSTATE: if ((dp = ginode(inumber)) == NULL) break; if (dp->di_nlink != 1) if (!qflag) { pwarn("BAD LINK COUNT IN CONTINUATION INODE "); pwarn("I=%u (%ld should be %ld)", inumber, dp->di_nlink, 1); if (preen) printf(" (CORRECTED)\n"); else { if (reply("CORRECT") == 0) continue; } dp->di_nlink = 1; inodirty(); } break; #endif /* ACLS */ default: errexit("BAD STATE %d FOR INODE I=%d", statemap[inumber], inumber); } } } pass4check(idesc) struct inodesc *idesc; { struct dups *dlp; int nfrags, res = KEEPON; 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(dlp); break; } if (dlp == 0) { clrbmap(blkno); n_blks--; } } } return (res); }