122052Sdist /* 239976Smckusick * Copyright (c) 1980, 1986 The Regents of the University of California. 339976Smckusick * All rights reserved. 439976Smckusick * 542702Sbostic * %sccs.include.redist.c% 622052Sdist */ 722052Sdist 816266Smckusick #ifndef lint 9*51532Sbostic static char sccsid[] = "@(#)pass4.c 5.11 (Berkeley) 11/04/91"; 1039976Smckusick #endif /* not lint */ 1116266Smckusick 1216266Smckusick #include <sys/param.h> 13*51532Sbostic #include <ufs/ufs/dinode.h> 14*51532Sbostic #include <ufs/ffs/fs.h> 1544933Smckusick #include <stdlib.h> 1644933Smckusick #include <string.h> 1716266Smckusick #include "fsck.h" 1816266Smckusick 1916266Smckusick int pass4check(); 2016266Smckusick 2116266Smckusick pass4() 2216266Smckusick { 2321759Smckusick register ino_t inumber; 2421759Smckusick register struct zlncnt *zlnp; 2541134Smckusick struct dinode *dp; 2621759Smckusick struct inodesc idesc; 2716266Smckusick int n; 2816266Smckusick 2916266Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 3016266Smckusick idesc.id_type = ADDR; 3116266Smckusick idesc.id_func = pass4check; 3216266Smckusick for (inumber = ROOTINO; inumber <= lastino; inumber++) { 3316266Smckusick idesc.id_number = inumber; 3416266Smckusick switch (statemap[inumber]) { 3516266Smckusick 3616266Smckusick case FSTATE: 3717937Smckusick case DFOUND: 3816266Smckusick n = lncntp[inumber]; 3916266Smckusick if (n) 4016266Smckusick adjust(&idesc, (short)n); 4116266Smckusick else { 4221759Smckusick for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 4321759Smckusick if (zlnp->zlncnt == inumber) { 4426479Smckusick zlnp->zlncnt = zlnhead->zlncnt; 4526479Smckusick zlnp = zlnhead; 4626479Smckusick zlnhead = zlnhead->next; 4739972Smckusick free((char *)zlnp); 4816266Smckusick clri(&idesc, "UNREF", 1); 4916266Smckusick break; 5016266Smckusick } 5116266Smckusick } 5216266Smckusick break; 5316266Smckusick 5416266Smckusick case DSTATE: 5516266Smckusick clri(&idesc, "UNREF", 1); 5616266Smckusick break; 5716266Smckusick 5817937Smckusick case DCLEAR: 5941134Smckusick dp = ginode(inumber); 6041134Smckusick if (dp->di_size == 0) { 6141134Smckusick clri(&idesc, "ZERO LENGTH", 1); 6241134Smckusick break; 6341134Smckusick } 6441134Smckusick /* fall through */ 6517937Smckusick case FCLEAR: 6616266Smckusick clri(&idesc, "BAD/DUP", 1); 6716266Smckusick break; 6826480Smckusick 6926480Smckusick case USTATE: 7026480Smckusick break; 7126480Smckusick 7226480Smckusick default: 7326480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 7426480Smckusick statemap[inumber], inumber); 7516266Smckusick } 7616266Smckusick } 7716266Smckusick } 7816266Smckusick 7916266Smckusick pass4check(idesc) 8016266Smckusick register struct inodesc *idesc; 8116266Smckusick { 8221744Smckusick register struct dups *dlp; 8316266Smckusick int nfrags, res = KEEPON; 8416266Smckusick daddr_t blkno = idesc->id_blkno; 8516266Smckusick 8616266Smckusick for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 8739972Smckusick if (chkrange(blkno, 1)) { 8816266Smckusick res = SKIP; 8939972Smckusick } else if (testbmap(blkno)) { 9021744Smckusick for (dlp = duplist; dlp; dlp = dlp->next) { 9121744Smckusick if (dlp->dup != blkno) 9221744Smckusick continue; 9321744Smckusick dlp->dup = duplist->dup; 9421744Smckusick dlp = duplist; 9521744Smckusick duplist = duplist->next; 9639972Smckusick free((char *)dlp); 9721744Smckusick break; 9821744Smckusick } 9921744Smckusick if (dlp == 0) { 10021744Smckusick clrbmap(blkno); 10121744Smckusick n_blks--; 10221744Smckusick } 10316266Smckusick } 10416266Smckusick } 10516266Smckusick return (res); 10616266Smckusick } 107