pass4.c revision 41477
169408Sache/* 259243Sobrien * Copyright (c) 1980, 1986, 1993 359243Sobrien * The Regents of the University of California. All rights reserved. 459243Sobrien * 559243Sobrien * Redistribution and use in source and binary forms, with or without 659243Sobrien * modification, are permitted provided that the following conditions 759243Sobrien * are met: 859243Sobrien * 1. Redistributions of source code must retain the above copyright 959243Sobrien * notice, this list of conditions and the following disclaimer. 1059243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1159243Sobrien * notice, this list of conditions and the following disclaimer in the 1259243Sobrien * documentation and/or other materials provided with the distribution. 1359243Sobrien * 3. All advertising materials mentioning features or use of this software 1459243Sobrien * must display the following acknowledgement: 1559243Sobrien * This product includes software developed by the University of 1659243Sobrien * California, Berkeley and its contributors. 1759243Sobrien * 4. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien 3459243Sobrien#ifndef lint 3559243Sobrien#if 0 3659243Sobrienstatic const char sccsid[] = "@(#)pass4.c 8.4 (Berkeley) 4/28/95"; 3759243Sobrien#endif 3859243Sobrienstatic const char rcsid[] = 3969408Sache "$Id: pass4.c,v 1.4 1998/06/15 07:07:19 charnier Exp $"; 4059243Sobrien#endif /* not lint */ 4159243Sobrien 4259243Sobrien#include <sys/param.h> 4359243Sobrien 4459243Sobrien#include <ufs/ufs/dinode.h> 4559243Sobrien#include <ufs/ffs/fs.h> 4659243Sobrien 4759243Sobrien#include <err.h> 4859243Sobrien#include <string.h> 4959243Sobrien 5059243Sobrien#include "fsck.h" 5159243Sobrien 5259243Sobrienvoid 5359243Sobrienpass4() 5459243Sobrien{ 5559243Sobrien register ino_t inumber; 5659243Sobrien register struct zlncnt *zlnp; 5759243Sobrien struct dinode *dp; 5859243Sobrien struct inodesc idesc; 5959243Sobrien int i, n, cg; 6059243Sobrien 6159243Sobrien memset(&idesc, 0, sizeof(struct inodesc)); 6259243Sobrien idesc.id_type = ADDR; 6359243Sobrien idesc.id_func = pass4check; 6459243Sobrien for (cg = 0; cg < sblock.fs_ncg; cg++) { 6559243Sobrien inumber = cg * sblock.fs_ipg; 6659243Sobrien for (i = 0; i < inostathead[cg].il_numalloced; i++, inumber++) { 6759243Sobrien if (inumber < ROOTINO) 6859243Sobrien continue; 6959243Sobrien idesc.id_number = inumber; 7059243Sobrien switch (inoinfo(inumber)->ino_state) { 7159243Sobrien 7259243Sobrien case FSTATE: 7359243Sobrien case DFOUND: 7459243Sobrien n = inoinfo(inumber)->ino_linkcnt; 7559243Sobrien if (n) { 7659243Sobrien adjust(&idesc, (short)n); 7759243Sobrien break; 7859243Sobrien } 7959243Sobrien for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) { 8059243Sobrien if (zlnp->zlncnt == inumber) { 8159243Sobrien zlnp->zlncnt = zlnhead->zlncnt; 8259243Sobrien zlnp = zlnhead; 8359243Sobrien zlnhead = zlnhead->next; 8459243Sobrien free((char *)zlnp); 8559243Sobrien clri(&idesc, "UNREF", 1); 8659243Sobrien break; 8759243Sobrien } 8859243Sobrien } 8959243Sobrien break; 9059243Sobrien 9159243Sobrien case DSTATE: 9259243Sobrien clri(&idesc, "UNREF", 1); 9359243Sobrien break; 9459243Sobrien 9559243Sobrien case DCLEAR: 9659243Sobrien dp = ginode(inumber); 9759243Sobrien if (dp->di_size == 0) { 9859243Sobrien clri(&idesc, "ZERO LENGTH", 1); 9959243Sobrien break; 10059243Sobrien } 10159243Sobrien /* fall through */ 10259243Sobrien case FCLEAR: 10359243Sobrien clri(&idesc, "BAD/DUP", 1); 10459243Sobrien break; 10559243Sobrien 10659243Sobrien case USTATE: 10759243Sobrien break; 10859243Sobrien 10959243Sobrien default: 11059243Sobrien errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 11159243Sobrien inoinfo(inumber)->ino_state, inumber); 11259243Sobrien } 11359243Sobrien } 11459243Sobrien } 11559243Sobrien} 11659243Sobrien 11759243Sobrienint 11859243Sobrienpass4check(idesc) 11959243Sobrien register struct inodesc *idesc; 12059243Sobrien{ 12159243Sobrien register struct dups *dlp; 12259243Sobrien int nfrags, res = KEEPON; 12359243Sobrien ufs_daddr_t blkno = idesc->id_blkno; 12459243Sobrien 12559243Sobrien for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 12659243Sobrien if (chkrange(blkno, 1)) { 12759243Sobrien res = SKIP; 12859243Sobrien } else if (testbmap(blkno)) { 12959243Sobrien for (dlp = duplist; dlp; dlp = dlp->next) { 13059243Sobrien if (dlp->dup != blkno) 13159243Sobrien continue; 13259243Sobrien dlp->dup = duplist->dup; 13359243Sobrien dlp = duplist; 13459243Sobrien duplist = duplist->next; 13559243Sobrien free((char *)dlp); 13659243Sobrien break; 13759243Sobrien } 13859243Sobrien if (dlp == 0) { 13959243Sobrien clrbmap(blkno); 14059243Sobrien n_blks--; 14159243Sobrien } 14259243Sobrien } 14359243Sobrien } 14459243Sobrien return (res); 14559243Sobrien} 14659243Sobrien