1 1.28 joerg /* $NetBSD: pass4.c,v 1.28 2020/04/03 19:36:33 joerg 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 36 1.6 perseant #define vnode uvnode 37 1.6 perseant #define buf ubuf 38 1.6 perseant #define panic call_panic 39 1.1 perseant #include <ufs/lfs/lfs.h> 40 1.25 dholland #include <ufs/lfs/lfs_accessors.h> 41 1.21 dholland #include <ufs/lfs/lfs_inode.h> 42 1.6 perseant 43 1.6 perseant #include <err.h> 44 1.1 perseant #include <stdlib.h> 45 1.1 perseant #include <string.h> 46 1.1 perseant 47 1.6 perseant #include "bufcache.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.15 perseant static int check_orphan(struct inodesc *idp); 55 1.15 perseant 56 1.15 perseant static int 57 1.15 perseant check_orphan(struct inodesc *idp) 58 1.15 perseant { 59 1.15 perseant struct zlncnt *zlnp; 60 1.15 perseant ino_t inumber = idp->id_number; 61 1.15 perseant 62 1.15 perseant for (zlnp = orphead; zlnp; zlnp = zlnp->next) { 63 1.15 perseant if (zlnp->zlncnt == inumber) { 64 1.15 perseant /* Swap this with head */ 65 1.15 perseant zlnp->zlncnt = orphead->zlncnt; 66 1.15 perseant zlnp = orphead; 67 1.15 perseant orphead = orphead->next; 68 1.15 perseant /* Free old head */ 69 1.15 perseant free((char *) zlnp); 70 1.15 perseant clri(idp, "PROPERLY ORPHANED", 1); 71 1.15 perseant return 1; 72 1.15 perseant } 73 1.15 perseant } 74 1.15 perseant return 0; 75 1.15 perseant } 76 1.15 perseant 77 1.1 perseant void 78 1.10 xtraeme pass4(void) 79 1.1 perseant { 80 1.11 perry ino_t inumber; 81 1.11 perry struct zlncnt *zlnp; 82 1.26 dholland union lfs_dinode *dp; 83 1.6 perseant struct inodesc idesc; 84 1.6 perseant int n; 85 1.1 perseant 86 1.1 perseant memset(&idesc, 0, sizeof(struct inodesc)); 87 1.1 perseant idesc.id_type = ADDR; 88 1.1 perseant idesc.id_func = pass4check; 89 1.19 dholland for (inumber = ULFS_ROOTINO; inumber <= lastino; inumber++) { 90 1.1 perseant idesc.id_number = inumber; 91 1.1 perseant switch (statemap[inumber]) { 92 1.1 perseant 93 1.1 perseant case FSTATE: 94 1.1 perseant case DFOUND: 95 1.1 perseant n = lncntp[inumber]; 96 1.1 perseant if (n) 97 1.6 perseant adjust(&idesc, (short) n); 98 1.1 perseant else { 99 1.1 perseant for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) 100 1.1 perseant if (zlnp->zlncnt == inumber) { 101 1.1 perseant zlnp->zlncnt = zlnhead->zlncnt; 102 1.1 perseant zlnp = zlnhead; 103 1.1 perseant zlnhead = zlnhead->next; 104 1.6 perseant free((char *) zlnp); 105 1.1 perseant clri(&idesc, "UNREF", 1); 106 1.1 perseant break; 107 1.1 perseant } 108 1.1 perseant } 109 1.1 perseant break; 110 1.1 perseant 111 1.1 perseant case DSTATE: 112 1.1 perseant clri(&idesc, "UNREF", 1); 113 1.1 perseant break; 114 1.1 perseant 115 1.1 perseant case DCLEAR: 116 1.15 perseant if (check_orphan(&idesc)) 117 1.15 perseant break; 118 1.1 perseant dp = ginode(inumber); 119 1.26 dholland if (lfs_dino_getsize(fs, dp) == 0) { 120 1.15 perseant const char * msg = (lncntp[inumber] ? 121 1.15 perseant "ZERO LENGTH" : "UNREF ZERO LENGTH"); 122 1.15 perseant clri(&idesc, msg, 1); 123 1.1 perseant break; 124 1.1 perseant } 125 1.15 perseant clri(&idesc, "BAD/DUP", 1); 126 1.15 perseant break; 127 1.15 perseant 128 1.1 perseant case FCLEAR: 129 1.15 perseant if (check_orphan(&idesc)) 130 1.15 perseant break; 131 1.1 perseant clri(&idesc, "BAD/DUP", 1); 132 1.1 perseant break; 133 1.1 perseant 134 1.1 perseant case USTATE: 135 1.1 perseant break; 136 1.1 perseant 137 1.1 perseant default: 138 1.23 christos err(EEXIT, "BAD STATE %d FOR INODE I=%llu", 139 1.12 christos statemap[inumber], (unsigned long long)inumber); 140 1.1 perseant } 141 1.1 perseant } 142 1.1 perseant } 143 1.1 perseant 144 1.1 perseant int 145 1.3 perseant pass4check(struct inodesc * idesc) 146 1.1 perseant { 147 1.11 perry struct dups *dlp; 148 1.6 perseant int ndblks, res = KEEPON; 149 1.6 perseant daddr_t blkno = idesc->id_blkno; 150 1.6 perseant SEGUSE *sup; 151 1.6 perseant struct ubuf *bp; 152 1.14 perseant int sn; 153 1.1 perseant 154 1.22 christos sn = lfs_dtosn(fs, blkno); 155 1.17 mlelstv for (ndblks = idesc->id_numfrags; ndblks > 0; blkno++, ndblks--) { 156 1.1 perseant if (chkrange(blkno, 1)) { 157 1.1 perseant res = SKIP; 158 1.14 perseant } else if (testbmap(blkno) || preen) { 159 1.1 perseant for (dlp = duplist; dlp; dlp = dlp->next) { 160 1.1 perseant if (dlp->dup != blkno) 161 1.1 perseant continue; 162 1.1 perseant dlp->dup = duplist->dup; 163 1.1 perseant dlp = duplist; 164 1.1 perseant duplist = duplist->next; 165 1.6 perseant free((char *) dlp); 166 1.1 perseant break; 167 1.1 perseant } 168 1.1 perseant if (dlp == 0) { 169 1.1 perseant clrbmap(blkno); 170 1.6 perseant LFS_SEGENTRY(sup, fs, sn, bp); 171 1.22 christos sup->su_nbytes -= lfs_fsbtob(fs, 1); 172 1.6 perseant VOP_BWRITE(bp); 173 1.22 christos seg_table[sn].su_nbytes -= lfs_fsbtob(fs, 1); 174 1.24 dholland lfs_sb_addbfree(fs, 1); 175 1.1 perseant n_blks--; 176 1.1 perseant } 177 1.1 perseant } 178 1.1 perseant } 179 1.1 perseant return (res); 180 1.1 perseant } 181