122052Sdist /* 261492Sbostic * Copyright (c) 1980, 1986, 1993 361492Sbostic * The Regents of the University of California. All rights reserved. 439976Smckusick * 542702Sbostic * %sccs.include.redist.c% 622052Sdist */ 722052Sdist 816266Smckusick #ifndef lint 9*68908Smckusick static char sccsid[] = "@(#)pass4.c 8.3 (Berkeley) 04/27/95"; 1039976Smckusick #endif /* not lint */ 1116266Smckusick 1216266Smckusick #include <sys/param.h> 1353703Smckusick #include <sys/time.h> 14*68908Smckusick 1551532Sbostic #include <ufs/ufs/dinode.h> 1651532Sbostic #include <ufs/ffs/fs.h> 17*68908Smckusick 18*68908Smckusick #include <err.h> 1944933Smckusick #include <string.h> 20*68908Smckusick 2116266Smckusick #include "fsck.h" 2216266Smckusick 23*68908Smckusick void 2416266Smckusick pass4() 2516266Smckusick { 2621759Smckusick register ino_t inumber; 2721759Smckusick register struct zlncnt *zlnp; 2841134Smckusick struct dinode *dp; 2921759Smckusick struct inodesc idesc; 3016266Smckusick int n; 3116266Smckusick 3216266Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 3316266Smckusick idesc.id_type = ADDR; 3416266Smckusick idesc.id_func = pass4check; 3516266Smckusick for (inumber = ROOTINO; inumber <= lastino; inumber++) { 3616266Smckusick idesc.id_number = inumber; 3716266Smckusick switch (statemap[inumber]) { 3816266Smckusick 3916266Smckusick case FSTATE: 4017937Smckusick case DFOUND: 4116266Smckusick n = lncntp[inumber]; 4216266Smckusick if (n) 4316266Smckusick adjust(&idesc, (short)n); 4416266Smckusick else { 4521759Smckusick for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 4621759Smckusick if (zlnp->zlncnt == inumber) { 4726479Smckusick zlnp->zlncnt = zlnhead->zlncnt; 4826479Smckusick zlnp = zlnhead; 4926479Smckusick zlnhead = zlnhead->next; 5039972Smckusick free((char *)zlnp); 5116266Smckusick clri(&idesc, "UNREF", 1); 5216266Smckusick break; 5316266Smckusick } 5416266Smckusick } 5516266Smckusick break; 5616266Smckusick 5716266Smckusick case DSTATE: 5816266Smckusick clri(&idesc, "UNREF", 1); 5916266Smckusick break; 6016266Smckusick 6117937Smckusick case DCLEAR: 6241134Smckusick dp = ginode(inumber); 6341134Smckusick if (dp->di_size == 0) { 6441134Smckusick clri(&idesc, "ZERO LENGTH", 1); 6541134Smckusick break; 6641134Smckusick } 6741134Smckusick /* fall through */ 6817937Smckusick case FCLEAR: 6916266Smckusick clri(&idesc, "BAD/DUP", 1); 7016266Smckusick break; 7126480Smckusick 7226480Smckusick case USTATE: 7326480Smckusick break; 7426480Smckusick 7526480Smckusick default: 76*68908Smckusick errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 7726480Smckusick statemap[inumber], inumber); 7816266Smckusick } 7916266Smckusick } 8016266Smckusick } 8116266Smckusick 82*68908Smckusick int 8316266Smckusick pass4check(idesc) 8416266Smckusick register struct inodesc *idesc; 8516266Smckusick { 8621744Smckusick register struct dups *dlp; 8716266Smckusick int nfrags, res = KEEPON; 8868548Smckusick ufs_daddr_t blkno = idesc->id_blkno; 8916266Smckusick 9016266Smckusick for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 9139972Smckusick if (chkrange(blkno, 1)) { 9216266Smckusick res = SKIP; 9339972Smckusick } else if (testbmap(blkno)) { 9421744Smckusick for (dlp = duplist; dlp; dlp = dlp->next) { 9521744Smckusick if (dlp->dup != blkno) 9621744Smckusick continue; 9721744Smckusick dlp->dup = duplist->dup; 9821744Smckusick dlp = duplist; 9921744Smckusick duplist = duplist->next; 10039972Smckusick free((char *)dlp); 10121744Smckusick break; 10221744Smckusick } 10321744Smckusick if (dlp == 0) { 10421744Smckusick clrbmap(blkno); 10521744Smckusick n_blks--; 10621744Smckusick } 10716266Smckusick } 10816266Smckusick } 10916266Smckusick return (res); 11016266Smckusick } 111