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*68992Sbostic static char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 04/28/95";
1039976Smckusick #endif /* not lint */
1116266Smckusick
1216266Smckusick #include <sys/param.h>
1353703Smckusick #include <sys/time.h>
1468908Smckusick
1551532Sbostic #include <ufs/ufs/dinode.h>
1651532Sbostic #include <ufs/ffs/fs.h>
1768908Smckusick
1868908Smckusick #include <err.h>
1944933Smckusick #include <string.h>
2068908Smckusick
2116266Smckusick #include "fsck.h"
2216266Smckusick
2368908Smckusick void
pass4()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
32*68992Sbostic memset(&idesc, 0, 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:
7668908Smckusick errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
7726480Smckusick statemap[inumber], inumber);
7816266Smckusick }
7916266Smckusick }
8016266Smckusick }
8116266Smckusick
8268908Smckusick int
pass4check(idesc)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