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