Home | History | Annotate | Line # | Download | only in fsck_lfs
pass4.c revision 1.17.6.1
      1  1.17.6.1      yamt /* $NetBSD: pass4.c,v 1.17.6.1 2013/01/23 00:05:30 yamt Exp $	 */
      2       1.1  perseant 
      3       1.1  perseant /*
      4       1.1  perseant  * Copyright (c) 1980, 1986, 1993
      5       1.1  perseant  *	The Regents of the University of California.  All rights reserved.
      6       1.1  perseant  *
      7       1.1  perseant  * Redistribution and use in source and binary forms, with or without
      8       1.1  perseant  * modification, are permitted provided that the following conditions
      9       1.1  perseant  * are met:
     10       1.1  perseant  * 1. Redistributions of source code must retain the above copyright
     11       1.1  perseant  *    notice, this list of conditions and the following disclaimer.
     12       1.1  perseant  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  perseant  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  perseant  *    documentation and/or other materials provided with the distribution.
     15       1.9       agc  * 3. Neither the name of the University nor the names of its contributors
     16       1.1  perseant  *    may be used to endorse or promote products derived from this software
     17       1.1  perseant  *    without specific prior written permission.
     18       1.1  perseant  *
     19       1.1  perseant  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20       1.1  perseant  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21       1.1  perseant  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22       1.1  perseant  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23       1.1  perseant  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24       1.1  perseant  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25       1.1  perseant  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26       1.1  perseant  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27       1.1  perseant  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28       1.1  perseant  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29       1.1  perseant  * SUCH DAMAGE.
     30       1.1  perseant  */
     31       1.1  perseant 
     32       1.1  perseant #include <sys/param.h>
     33       1.1  perseant #include <sys/time.h>
     34       1.1  perseant #include <sys/mount.h>
     35       1.6  perseant #include <ufs/ufs/inode.h>
     36       1.6  perseant 
     37       1.6  perseant #define vnode uvnode
     38       1.6  perseant #define buf ubuf
     39       1.6  perseant #define panic call_panic
     40       1.1  perseant #include <ufs/lfs/lfs.h>
     41       1.6  perseant 
     42       1.6  perseant #include <err.h>
     43       1.1  perseant #include <stdlib.h>
     44       1.1  perseant #include <string.h>
     45       1.1  perseant 
     46       1.6  perseant #include "bufcache.h"
     47       1.6  perseant #include "vnode.h"
     48      1.13  christos #include "lfs_user.h"
     49       1.6  perseant 
     50       1.1  perseant #include "fsutil.h"
     51       1.1  perseant #include "fsck.h"
     52       1.1  perseant #include "extern.h"
     53       1.1  perseant 
     54       1.6  perseant extern SEGUSE *seg_table;
     55       1.6  perseant 
     56      1.15  perseant static int check_orphan(struct inodesc *idp);
     57      1.15  perseant 
     58      1.15  perseant static int
     59      1.15  perseant check_orphan(struct inodesc *idp)
     60      1.15  perseant {
     61      1.15  perseant 	struct zlncnt *zlnp;
     62      1.15  perseant 	ino_t inumber = idp->id_number;
     63      1.15  perseant 
     64      1.15  perseant 	for (zlnp = orphead; zlnp; zlnp = zlnp->next) {
     65      1.15  perseant 		if (zlnp->zlncnt == inumber) {
     66      1.15  perseant 			/* Swap this with head */
     67      1.15  perseant 			zlnp->zlncnt = orphead->zlncnt;
     68      1.15  perseant 			zlnp = orphead;
     69      1.15  perseant 			orphead = orphead->next;
     70      1.15  perseant 			/* Free old head */
     71      1.15  perseant 			free((char *) zlnp);
     72      1.15  perseant 			clri(idp, "PROPERLY ORPHANED", 1);
     73      1.15  perseant 			return 1;
     74      1.15  perseant 		}
     75      1.15  perseant 	}
     76      1.15  perseant 	return 0;
     77      1.15  perseant }
     78      1.15  perseant 
     79       1.1  perseant void
     80      1.10   xtraeme pass4(void)
     81       1.1  perseant {
     82      1.11     perry 	ino_t inumber;
     83      1.11     perry 	struct zlncnt *zlnp;
     84       1.8      fvdl 	struct ufs1_dinode *dp;
     85       1.6  perseant 	struct inodesc idesc;
     86       1.6  perseant 	int n;
     87       1.1  perseant 
     88       1.1  perseant 	memset(&idesc, 0, sizeof(struct inodesc));
     89       1.1  perseant 	idesc.id_type = ADDR;
     90       1.1  perseant 	idesc.id_func = pass4check;
     91  1.17.6.1      yamt 	for (inumber = UFS_ROOTINO; inumber <= lastino; inumber++) {
     92       1.1  perseant 		idesc.id_number = inumber;
     93       1.1  perseant 		switch (statemap[inumber]) {
     94       1.1  perseant 
     95       1.1  perseant 		case FSTATE:
     96       1.1  perseant 		case DFOUND:
     97       1.1  perseant 			n = lncntp[inumber];
     98       1.1  perseant 			if (n)
     99       1.6  perseant 				adjust(&idesc, (short) n);
    100       1.1  perseant 			else {
    101       1.1  perseant 				for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
    102       1.1  perseant 					if (zlnp->zlncnt == inumber) {
    103       1.1  perseant 						zlnp->zlncnt = zlnhead->zlncnt;
    104       1.1  perseant 						zlnp = zlnhead;
    105       1.1  perseant 						zlnhead = zlnhead->next;
    106       1.6  perseant 						free((char *) zlnp);
    107       1.1  perseant 						clri(&idesc, "UNREF", 1);
    108       1.1  perseant 						break;
    109       1.1  perseant 					}
    110       1.1  perseant 			}
    111       1.1  perseant 			break;
    112       1.1  perseant 
    113       1.1  perseant 		case DSTATE:
    114       1.1  perseant 			clri(&idesc, "UNREF", 1);
    115       1.1  perseant 			break;
    116       1.1  perseant 
    117       1.1  perseant 		case DCLEAR:
    118      1.15  perseant 			if (check_orphan(&idesc))
    119      1.15  perseant 				break;
    120       1.1  perseant 			dp = ginode(inumber);
    121       1.1  perseant 			if (dp->di_size == 0) {
    122      1.15  perseant 				const char * msg = (lncntp[inumber] ?
    123      1.15  perseant 					"ZERO LENGTH" : "UNREF ZERO LENGTH");
    124      1.15  perseant 				clri(&idesc, msg, 1);
    125       1.1  perseant 				break;
    126       1.1  perseant 			}
    127      1.15  perseant 			clri(&idesc, "BAD/DUP", 1);
    128      1.15  perseant 			break;
    129      1.15  perseant 
    130       1.1  perseant 		case FCLEAR:
    131      1.15  perseant 			if (check_orphan(&idesc))
    132      1.15  perseant 				break;
    133       1.1  perseant 			clri(&idesc, "BAD/DUP", 1);
    134       1.1  perseant 			break;
    135       1.1  perseant 
    136       1.1  perseant 		case USTATE:
    137       1.1  perseant 			break;
    138       1.1  perseant 
    139       1.1  perseant 		default:
    140      1.16  christos 			err(EEXIT, "BAD STATE %d FOR INODE I=%llu\n",
    141      1.12  christos 			    statemap[inumber], (unsigned long long)inumber);
    142       1.1  perseant 		}
    143       1.1  perseant 	}
    144       1.1  perseant }
    145       1.1  perseant 
    146       1.1  perseant int
    147       1.3  perseant pass4check(struct inodesc * idesc)
    148       1.1  perseant {
    149      1.11     perry 	struct dups *dlp;
    150       1.6  perseant 	int ndblks, res = KEEPON;
    151       1.6  perseant 	daddr_t blkno = idesc->id_blkno;
    152       1.6  perseant 	SEGUSE *sup;
    153       1.6  perseant 	struct ubuf *bp;
    154      1.14  perseant 	int sn;
    155       1.1  perseant 
    156       1.7  perseant 	sn = dtosn(fs, blkno);
    157      1.17   mlelstv 	for (ndblks = idesc->id_numfrags; ndblks > 0; blkno++, ndblks--) {
    158       1.1  perseant 		if (chkrange(blkno, 1)) {
    159       1.1  perseant 			res = SKIP;
    160      1.14  perseant 		} else if (testbmap(blkno) || preen) {
    161       1.1  perseant 			for (dlp = duplist; dlp; dlp = dlp->next) {
    162       1.1  perseant 				if (dlp->dup != blkno)
    163       1.1  perseant 					continue;
    164       1.1  perseant 				dlp->dup = duplist->dup;
    165       1.1  perseant 				dlp = duplist;
    166       1.1  perseant 				duplist = duplist->next;
    167       1.6  perseant 				free((char *) dlp);
    168       1.1  perseant 				break;
    169       1.1  perseant 			}
    170       1.1  perseant 			if (dlp == 0) {
    171       1.1  perseant 				clrbmap(blkno);
    172       1.6  perseant 				LFS_SEGENTRY(sup, fs, sn, bp);
    173       1.6  perseant 				sup->su_nbytes -= fsbtob(fs, 1);
    174       1.6  perseant 				VOP_BWRITE(bp);
    175       1.6  perseant 				seg_table[sn].su_nbytes -= fsbtob(fs, 1);
    176       1.6  perseant 				++fs->lfs_bfree;
    177       1.1  perseant 				n_blks--;
    178       1.1  perseant 			}
    179       1.1  perseant 		}
    180       1.1  perseant 	}
    181       1.1  perseant 	return (res);
    182       1.1  perseant }
    183