1 /* 2 * Copyright (c) 1980, 1986 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)pass4.c 5.8 (Berkeley) 04/29/90"; 20 #endif /* not lint */ 21 22 #include <sys/param.h> 23 #include <ufs/dinode.h> 24 #include <ufs/fs.h> 25 #include "fsck.h" 26 27 int pass4check(); 28 29 pass4() 30 { 31 register ino_t inumber; 32 register struct zlncnt *zlnp; 33 struct dinode *dp; 34 struct inodesc idesc; 35 int n; 36 37 bzero((char *)&idesc, sizeof(struct inodesc)); 38 idesc.id_type = ADDR; 39 idesc.id_func = pass4check; 40 for (inumber = ROOTINO; inumber <= lastino; inumber++) { 41 idesc.id_number = inumber; 42 switch (statemap[inumber]) { 43 44 case FSTATE: 45 case DFOUND: 46 n = lncntp[inumber]; 47 if (n) 48 adjust(&idesc, (short)n); 49 else { 50 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 51 if (zlnp->zlncnt == inumber) { 52 zlnp->zlncnt = zlnhead->zlncnt; 53 zlnp = zlnhead; 54 zlnhead = zlnhead->next; 55 free((char *)zlnp); 56 clri(&idesc, "UNREF", 1); 57 break; 58 } 59 } 60 break; 61 62 case DSTATE: 63 clri(&idesc, "UNREF", 1); 64 break; 65 66 case DCLEAR: 67 dp = ginode(inumber); 68 if (dp->di_size == 0) { 69 clri(&idesc, "ZERO LENGTH", 1); 70 break; 71 } 72 /* fall through */ 73 case FCLEAR: 74 clri(&idesc, "BAD/DUP", 1); 75 break; 76 77 case USTATE: 78 break; 79 80 default: 81 errexit("BAD STATE %d FOR INODE I=%d", 82 statemap[inumber], inumber); 83 } 84 } 85 } 86 87 pass4check(idesc) 88 register struct inodesc *idesc; 89 { 90 register struct dups *dlp; 91 int nfrags, res = KEEPON; 92 daddr_t blkno = idesc->id_blkno; 93 94 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 95 if (chkrange(blkno, 1)) { 96 res = SKIP; 97 } else if (testbmap(blkno)) { 98 for (dlp = duplist; dlp; dlp = dlp->next) { 99 if (dlp->dup != blkno) 100 continue; 101 dlp->dup = duplist->dup; 102 dlp = duplist; 103 duplist = duplist->next; 104 free((char *)dlp); 105 break; 106 } 107 if (dlp == 0) { 108 clrbmap(blkno); 109 n_blks--; 110 } 111 } 112 } 113 return (res); 114 } 115