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.7 (Berkeley) 02/01/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 inodesc idesc; 34 int n; 35 36 bzero((char *)&idesc, sizeof(struct inodesc)); 37 idesc.id_type = ADDR; 38 idesc.id_func = pass4check; 39 for (inumber = ROOTINO; inumber <= lastino; inumber++) { 40 idesc.id_number = inumber; 41 switch (statemap[inumber]) { 42 43 case FSTATE: 44 case DFOUND: 45 n = lncntp[inumber]; 46 if (n) 47 adjust(&idesc, (short)n); 48 else { 49 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 50 if (zlnp->zlncnt == inumber) { 51 zlnp->zlncnt = zlnhead->zlncnt; 52 zlnp = zlnhead; 53 zlnhead = zlnhead->next; 54 free((char *)zlnp); 55 clri(&idesc, "UNREF", 1); 56 break; 57 } 58 } 59 break; 60 61 case DSTATE: 62 clri(&idesc, "UNREF", 1); 63 break; 64 65 case DCLEAR: 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 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