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*53703Smckusick static char sccsid[] = "@(#)pass4.c 5.12 (Berkeley) 05/27/92"; 1039976Smckusick #endif /* not lint */ 1116266Smckusick 1216266Smckusick #include <sys/param.h> 13*53703Smckusick #include <sys/time.h> 1451532Sbostic #include <ufs/ufs/dinode.h> 1551532Sbostic #include <ufs/ffs/fs.h> 1644933Smckusick #include <stdlib.h> 1744933Smckusick #include <string.h> 1816266Smckusick #include "fsck.h" 1916266Smckusick 2016266Smckusick int pass4check(); 2116266Smckusick 2216266Smckusick pass4() 2316266Smckusick { 2421759Smckusick register ino_t inumber; 2521759Smckusick register struct zlncnt *zlnp; 2641134Smckusick struct dinode *dp; 2721759Smckusick struct inodesc idesc; 2816266Smckusick int n; 2916266Smckusick 3016266Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 3116266Smckusick idesc.id_type = ADDR; 3216266Smckusick idesc.id_func = pass4check; 3316266Smckusick for (inumber = ROOTINO; inumber <= lastino; inumber++) { 3416266Smckusick idesc.id_number = inumber; 3516266Smckusick switch (statemap[inumber]) { 3616266Smckusick 3716266Smckusick case FSTATE: 3817937Smckusick case DFOUND: 3916266Smckusick n = lncntp[inumber]; 4016266Smckusick if (n) 4116266Smckusick adjust(&idesc, (short)n); 4216266Smckusick else { 4321759Smckusick for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 4421759Smckusick if (zlnp->zlncnt == inumber) { 4526479Smckusick zlnp->zlncnt = zlnhead->zlncnt; 4626479Smckusick zlnp = zlnhead; 4726479Smckusick zlnhead = zlnhead->next; 4839972Smckusick free((char *)zlnp); 4916266Smckusick clri(&idesc, "UNREF", 1); 5016266Smckusick break; 5116266Smckusick } 5216266Smckusick } 5316266Smckusick break; 5416266Smckusick 5516266Smckusick case DSTATE: 5616266Smckusick clri(&idesc, "UNREF", 1); 5716266Smckusick break; 5816266Smckusick 5917937Smckusick case DCLEAR: 6041134Smckusick dp = ginode(inumber); 6141134Smckusick if (dp->di_size == 0) { 6241134Smckusick clri(&idesc, "ZERO LENGTH", 1); 6341134Smckusick break; 6441134Smckusick } 6541134Smckusick /* fall through */ 6617937Smckusick case FCLEAR: 6716266Smckusick clri(&idesc, "BAD/DUP", 1); 6816266Smckusick break; 6926480Smckusick 7026480Smckusick case USTATE: 7126480Smckusick break; 7226480Smckusick 7326480Smckusick default: 7426480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 7526480Smckusick statemap[inumber], inumber); 7616266Smckusick } 7716266Smckusick } 7816266Smckusick } 7916266Smckusick 8016266Smckusick pass4check(idesc) 8116266Smckusick register struct inodesc *idesc; 8216266Smckusick { 8321744Smckusick register struct dups *dlp; 8416266Smckusick int nfrags, res = KEEPON; 8516266Smckusick daddr_t blkno = idesc->id_blkno; 8616266Smckusick 8716266Smckusick for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 8839972Smckusick if (chkrange(blkno, 1)) { 8916266Smckusick res = SKIP; 9039972Smckusick } else if (testbmap(blkno)) { 9121744Smckusick for (dlp = duplist; dlp; dlp = dlp->next) { 9221744Smckusick if (dlp->dup != blkno) 9321744Smckusick continue; 9421744Smckusick dlp->dup = duplist->dup; 9521744Smckusick dlp = duplist; 9621744Smckusick duplist = duplist->next; 9739972Smckusick free((char *)dlp); 9821744Smckusick break; 9921744Smckusick } 10021744Smckusick if (dlp == 0) { 10121744Smckusick clrbmap(blkno); 10221744Smckusick n_blks--; 10321744Smckusick } 10416266Smckusick } 10516266Smckusick } 10616266Smckusick return (res); 10716266Smckusick } 108