xref: /csrg-svn/sbin/fsck/pass4.c (revision 51532)
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