1 /* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 04/28/95"; 10 #endif /* not lint */ 11 12 #include <sys/param.h> 13 #include <sys/time.h> 14 15 #include <ufs/ufs/dinode.h> 16 #include <ufs/ffs/fs.h> 17 18 #include <err.h> 19 #include <string.h> 20 21 #include "fsck.h" 22 23 void 24 pass4() 25 { 26 register ino_t inumber; 27 register struct zlncnt *zlnp; 28 struct dinode *dp; 29 struct inodesc idesc; 30 int n; 31 32 memset(&idesc, 0, sizeof(struct inodesc)); 33 idesc.id_type = ADDR; 34 idesc.id_func = pass4check; 35 for (inumber = ROOTINO; inumber <= lastino; inumber++) { 36 idesc.id_number = inumber; 37 switch (statemap[inumber]) { 38 39 case FSTATE: 40 case DFOUND: 41 n = lncntp[inumber]; 42 if (n) 43 adjust(&idesc, (short)n); 44 else { 45 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 46 if (zlnp->zlncnt == inumber) { 47 zlnp->zlncnt = zlnhead->zlncnt; 48 zlnp = zlnhead; 49 zlnhead = zlnhead->next; 50 free((char *)zlnp); 51 clri(&idesc, "UNREF", 1); 52 break; 53 } 54 } 55 break; 56 57 case DSTATE: 58 clri(&idesc, "UNREF", 1); 59 break; 60 61 case DCLEAR: 62 dp = ginode(inumber); 63 if (dp->di_size == 0) { 64 clri(&idesc, "ZERO LENGTH", 1); 65 break; 66 } 67 /* fall through */ 68 case FCLEAR: 69 clri(&idesc, "BAD/DUP", 1); 70 break; 71 72 case USTATE: 73 break; 74 75 default: 76 errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 77 statemap[inumber], inumber); 78 } 79 } 80 } 81 82 int 83 pass4check(idesc) 84 register struct inodesc *idesc; 85 { 86 register struct dups *dlp; 87 int nfrags, res = KEEPON; 88 ufs_daddr_t blkno = idesc->id_blkno; 89 90 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 91 if (chkrange(blkno, 1)) { 92 res = SKIP; 93 } else if (testbmap(blkno)) { 94 for (dlp = duplist; dlp; dlp = dlp->next) { 95 if (dlp->dup != blkno) 96 continue; 97 dlp->dup = duplist->dup; 98 dlp = duplist; 99 duplist = duplist->next; 100 free((char *)dlp); 101 break; 102 } 103 if (dlp == 0) { 104 clrbmap(blkno); 105 n_blks--; 106 } 107 } 108 } 109 return (res); 110 } 111