1/* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint
| 1/* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint
|
35#if 0
| |
36static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
| 35static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
|
37#endif 38static const char rcsid[] = 39 "$Id: pass1.c,v 1.11 1998/06/15 07:07:16 charnier Exp $";
| |
40#endif /* not lint */ 41 42#include <sys/param.h>
| 36#endif /* not lint */ 37 38#include <sys/param.h>
|
| 39#include <sys/time.h>
|
43 44#include <ufs/ufs/dinode.h> 45#include <ufs/ufs/dir.h> 46#include <ufs/ffs/fs.h> 47 48#include <err.h> 49#include <string.h> 50 51#include "fsck.h" 52 53static ufs_daddr_t badblk; 54static ufs_daddr_t dupblk;
| 40 41#include <ufs/ufs/dinode.h> 42#include <ufs/ufs/dir.h> 43#include <ufs/ffs/fs.h> 44 45#include <err.h> 46#include <string.h> 47 48#include "fsck.h" 49 50static ufs_daddr_t badblk; 51static ufs_daddr_t dupblk;
|
| 52static ino_t lastino; /* last inode in use */
|
55 56static void checkinode __P((ino_t inumber, struct inodesc *)); 57 58void 59pass1() 60{
| 53 54static void checkinode __P((ino_t inumber, struct inodesc *)); 55 56void 57pass1() 58{
|
| 59 u_int8_t *cp;
|
61 ino_t inumber;
| 60 ino_t inumber;
|
62 int c, i, cgd;
| 61 int c, i, cgd, inosused; 62 struct inostat *info;
|
63 struct inodesc idesc; 64 65 /* 66 * Set file system reserved blocks in used block map. 67 */ 68 for (c = 0; c < sblock.fs_ncg; c++) { 69 cgd = cgdmin(&sblock, c); 70 if (c == 0) { 71 i = cgbase(&sblock, c); 72 cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); 73 } else 74 i = cgsblock(&sblock, c); 75 for (; i < cgd; i++) 76 setbmap(i); 77 } 78 /* 79 * Find all allocated blocks. 80 */ 81 memset(&idesc, 0, sizeof(struct inodesc)); 82 idesc.id_type = ADDR; 83 idesc.id_func = pass1check;
| 63 struct inodesc idesc; 64 65 /* 66 * Set file system reserved blocks in used block map. 67 */ 68 for (c = 0; c < sblock.fs_ncg; c++) { 69 cgd = cgdmin(&sblock, c); 70 if (c == 0) { 71 i = cgbase(&sblock, c); 72 cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); 73 } else 74 i = cgsblock(&sblock, c); 75 for (; i < cgd; i++) 76 setbmap(i); 77 } 78 /* 79 * Find all allocated blocks. 80 */ 81 memset(&idesc, 0, sizeof(struct inodesc)); 82 idesc.id_type = ADDR; 83 idesc.id_func = pass1check;
|
84 inumber = 0;
| |
85 n_files = n_blks = 0;
| 84 n_files = n_blks = 0;
|
86 resetinodebuf();
| |
87 for (c = 0; c < sblock.fs_ncg; c++) {
| 85 for (c = 0; c < sblock.fs_ncg; c++) {
|
88 for (i = 0; i < sblock.fs_ipg; i++, inumber++) { 89 if (inumber < ROOTINO)
| 86 inumber = c * sblock.fs_ipg; 87 setinodebuf(inumber); 88 inosused = sblock.fs_ipg; 89 /* 90 * If we are using soft updates, then we can trust the 91 * cylinder group inode allocation maps to tell us which 92 * inodes are allocated. We will scan the used inode map 93 * to find the inodes that are really in use, and then 94 * read only those inodes in from disk. 95 */ 96 if (preen && usedsoftdep) { 97 getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); 98 if (!cg_chkmagic(&cgrp)) 99 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 100 cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY]; 101 for ( ; inosused > 0; inosused -= NBBY, cp--) { 102 if (*cp == 0) 103 continue; 104 for (i = 1 << (NBBY - 1); i > 0; i >>= 1) { 105 if (*cp & i) 106 break; 107 inosused--; 108 } 109 break; 110 } 111 if (inosused < 0) 112 inosused = 0; 113 } 114 /* 115 * Allocate inoinfo structures for the allocated inodes. 116 */ 117 inostathead[c].il_numalloced = inosused; 118 if (inosused == 0) { 119 inostathead[c].il_stat = 0; 120 continue; 121 } 122 info = calloc((unsigned)inosused, sizeof(struct inostat)); 123 if (info == NULL) 124 pfatal("cannot alloc %u bytes for inoinfo\n", 125 (unsigned)(sizeof(struct inostat) * inosused)); 126 inostathead[c].il_stat = info; 127 /* 128 * Scan the allocated inodes. 129 */ 130 for (i = 0; i < inosused; i++, inumber++) { 131 if (inumber < ROOTINO) { 132 (void)getnextinode(inumber);
|
90 continue;
| 133 continue;
|
| 134 }
|
91 checkinode(inumber, &idesc); 92 }
| 135 checkinode(inumber, &idesc); 136 }
|
| 137 lastino += 1; 138 if (inosused < sblock.fs_ipg || inumber == lastino) 139 continue; 140 /* 141 * If we were not able to determine in advance which inodes 142 * were in use, then reduce the size of the inoinfo structure 143 * to the size necessary to describe the inodes that we 144 * really found. 145 */ 146 inosused = lastino - (c * sblock.fs_ipg); 147 if (inosused < 0) 148 inosused = 0; 149 inostathead[c].il_numalloced = inosused; 150 if (inosused == 0) { 151 free(inostathead[c].il_stat); 152 inostathead[c].il_stat = 0; 153 continue; 154 } 155 info = calloc((unsigned)inosused, sizeof(struct inostat)); 156 if (info == NULL) 157 pfatal("cannot alloc %u bytes for inoinfo\n", 158 (unsigned)(sizeof(struct inostat) * inosused)); 159 memmove(info, inostathead[c].il_stat, inosused * sizeof(*info)); 160 free(inostathead[c].il_stat); 161 inostathead[c].il_stat = info;
|
93 } 94 freeinodebuf(); 95} 96 97static void 98checkinode(inumber, idesc) 99 ino_t inumber; 100 register struct inodesc *idesc; 101{ 102 register struct dinode *dp; 103 struct zlncnt *zlnp; 104 int ndb, j; 105 mode_t mode; 106 char *symbuf; 107 108 dp = getnextinode(inumber); 109 mode = dp->di_mode & IFMT; 110 if (mode == 0) { 111 if (memcmp(dp->di_db, zino.di_db, 112 NDADDR * sizeof(ufs_daddr_t)) || 113 memcmp(dp->di_ib, zino.di_ib, 114 NIADDR * sizeof(ufs_daddr_t)) || 115 dp->di_mode || dp->di_size) { 116 pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); 117 if (reply("CLEAR") == 1) { 118 dp = ginode(inumber); 119 clearinode(dp); 120 inodirty(); 121 } 122 }
| 162 } 163 freeinodebuf(); 164} 165 166static void 167checkinode(inumber, idesc) 168 ino_t inumber; 169 register struct inodesc *idesc; 170{ 171 register struct dinode *dp; 172 struct zlncnt *zlnp; 173 int ndb, j; 174 mode_t mode; 175 char *symbuf; 176 177 dp = getnextinode(inumber); 178 mode = dp->di_mode & IFMT; 179 if (mode == 0) { 180 if (memcmp(dp->di_db, zino.di_db, 181 NDADDR * sizeof(ufs_daddr_t)) || 182 memcmp(dp->di_ib, zino.di_ib, 183 NIADDR * sizeof(ufs_daddr_t)) || 184 dp->di_mode || dp->di_size) { 185 pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); 186 if (reply("CLEAR") == 1) { 187 dp = ginode(inumber); 188 clearinode(dp); 189 inodirty(); 190 } 191 }
|
123 statemap[inumber] = USTATE;
| 192 inoinfo(inumber)->ino_state = USTATE;
|
124 return; 125 } 126 lastino = inumber; 127 if (/* dp->di_size < 0 || */ 128 dp->di_size + sblock.fs_bsize - 1 < dp->di_size || 129 (mode == IFDIR && dp->di_size > MAXDIRSIZE)) { 130 if (debug) 131 printf("bad size %qu:", dp->di_size); 132 goto unknown; 133 } 134 if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { 135 dp = ginode(inumber); 136 dp->di_size = sblock.fs_fsize; 137 dp->di_mode = IFREG|0600; 138 inodirty(); 139 } 140 ndb = howmany(dp->di_size, sblock.fs_bsize); 141 if (ndb < 0) { 142 if (debug) 143 printf("bad size %qu ndb %d:", 144 dp->di_size, ndb); 145 goto unknown; 146 } 147 if (mode == IFBLK || mode == IFCHR) 148 ndb++; 149 if (mode == IFLNK) { 150 if (doinglevel2 && 151 dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && 152 dp->di_blocks != 0) { 153 symbuf = alloca(secsize); 154 if (bread(fsreadfd, symbuf, 155 fsbtodb(&sblock, dp->di_db[0]), 156 (long)secsize) != 0) 157 errx(EEXIT, "cannot read symlink"); 158 if (debug) { 159 symbuf[dp->di_size] = 0; 160 printf("convert symlink %lu(%s) of size %ld\n",
| 193 return; 194 } 195 lastino = inumber; 196 if (/* dp->di_size < 0 || */ 197 dp->di_size + sblock.fs_bsize - 1 < dp->di_size || 198 (mode == IFDIR && dp->di_size > MAXDIRSIZE)) { 199 if (debug) 200 printf("bad size %qu:", dp->di_size); 201 goto unknown; 202 } 203 if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { 204 dp = ginode(inumber); 205 dp->di_size = sblock.fs_fsize; 206 dp->di_mode = IFREG|0600; 207 inodirty(); 208 } 209 ndb = howmany(dp->di_size, sblock.fs_bsize); 210 if (ndb < 0) { 211 if (debug) 212 printf("bad size %qu ndb %d:", 213 dp->di_size, ndb); 214 goto unknown; 215 } 216 if (mode == IFBLK || mode == IFCHR) 217 ndb++; 218 if (mode == IFLNK) { 219 if (doinglevel2 && 220 dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && 221 dp->di_blocks != 0) { 222 symbuf = alloca(secsize); 223 if (bread(fsreadfd, symbuf, 224 fsbtodb(&sblock, dp->di_db[0]), 225 (long)secsize) != 0) 226 errx(EEXIT, "cannot read symlink"); 227 if (debug) { 228 symbuf[dp->di_size] = 0; 229 printf("convert symlink %lu(%s) of size %ld\n",
|
161 (u_long)inumber, symbuf, 162 (long)dp->di_size);
| 230 (u_long)inumber, symbuf, (long)dp->di_size);
|
163 } 164 dp = ginode(inumber); 165 memmove(dp->di_shortlink, symbuf, (long)dp->di_size); 166 dp->di_blocks = 0; 167 inodirty(); 168 } 169 /* 170 * Fake ndb value so direct/indirect block checks below 171 * will detect any garbage after symlink string. 172 */
| 231 } 232 dp = ginode(inumber); 233 memmove(dp->di_shortlink, symbuf, (long)dp->di_size); 234 dp->di_blocks = 0; 235 inodirty(); 236 } 237 /* 238 * Fake ndb value so direct/indirect block checks below 239 * will detect any garbage after symlink string. 240 */
|
173 if (dp->di_size < sblock.fs_maxsymlinklen || 174 dp->di_blocks == 0) {
| 241 if (dp->di_size < sblock.fs_maxsymlinklen) {
|
175 ndb = howmany(dp->di_size, sizeof(ufs_daddr_t)); 176 if (ndb > NDADDR) { 177 j = ndb - NDADDR; 178 for (ndb = 1; j > 1; j--) 179 ndb *= NINDIR(&sblock); 180 ndb += NDADDR; 181 } 182 } 183 } 184 for (j = ndb; j < NDADDR; j++) 185 if (dp->di_db[j] != 0) { 186 if (debug) 187 printf("bad direct addr: %ld\n", 188 (long)dp->di_db[j]); 189 goto unknown; 190 } 191 for (j = 0, ndb -= NDADDR; ndb > 0; j++) 192 ndb /= NINDIR(&sblock); 193 for (; j < NIADDR; j++) 194 if (dp->di_ib[j] != 0) { 195 if (debug) 196 printf("bad indirect addr: %ld\n", 197 (long)dp->di_ib[j]); 198 goto unknown; 199 } 200 if (ftypeok(dp) == 0) 201 goto unknown; 202 n_files++;
| 242 ndb = howmany(dp->di_size, sizeof(ufs_daddr_t)); 243 if (ndb > NDADDR) { 244 j = ndb - NDADDR; 245 for (ndb = 1; j > 1; j--) 246 ndb *= NINDIR(&sblock); 247 ndb += NDADDR; 248 } 249 } 250 } 251 for (j = ndb; j < NDADDR; j++) 252 if (dp->di_db[j] != 0) { 253 if (debug) 254 printf("bad direct addr: %ld\n", 255 (long)dp->di_db[j]); 256 goto unknown; 257 } 258 for (j = 0, ndb -= NDADDR; ndb > 0; j++) 259 ndb /= NINDIR(&sblock); 260 for (; j < NIADDR; j++) 261 if (dp->di_ib[j] != 0) { 262 if (debug) 263 printf("bad indirect addr: %ld\n", 264 (long)dp->di_ib[j]); 265 goto unknown; 266 } 267 if (ftypeok(dp) == 0) 268 goto unknown; 269 n_files++;
|
203 lncntp[inumber] = dp->di_nlink;
| 270 inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
|
204 if (dp->di_nlink <= 0) { 205 zlnp = (struct zlncnt *)malloc(sizeof *zlnp); 206 if (zlnp == NULL) { 207 pfatal("LINK COUNT TABLE OVERFLOW"); 208 if (reply("CONTINUE") == 0) { 209 ckfini(0); 210 exit(EEXIT); 211 } 212 } else { 213 zlnp->zlncnt = inumber; 214 zlnp->next = zlnhead; 215 zlnhead = zlnp; 216 } 217 } 218 if (mode == IFDIR) { 219 if (dp->di_size == 0)
| 271 if (dp->di_nlink <= 0) { 272 zlnp = (struct zlncnt *)malloc(sizeof *zlnp); 273 if (zlnp == NULL) { 274 pfatal("LINK COUNT TABLE OVERFLOW"); 275 if (reply("CONTINUE") == 0) { 276 ckfini(0); 277 exit(EEXIT); 278 } 279 } else { 280 zlnp->zlncnt = inumber; 281 zlnp->next = zlnhead; 282 zlnhead = zlnp; 283 } 284 } 285 if (mode == IFDIR) { 286 if (dp->di_size == 0)
|
220 statemap[inumber] = DCLEAR;
| 287 inoinfo(inumber)->ino_state = DCLEAR;
|
221 else
| 288 else
|
222 statemap[inumber] = DSTATE;
| 289 inoinfo(inumber)->ino_state = DSTATE;
|
223 cacheino(dp, inumber);
| 290 cacheino(dp, inumber);
|
| 291 countdirs++;
|
224 } else
| 292 } else
|
225 statemap[inumber] = FSTATE; 226 typemap[inumber] = IFTODT(mode);
| 293 inoinfo(inumber)->ino_state = FSTATE; 294 inoinfo(inumber)->ino_type = IFTODT(mode);
|
227 if (doinglevel2 && 228 (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) { 229 dp = ginode(inumber); 230 dp->di_uid = dp->di_ouid; 231 dp->di_ouid = -1; 232 dp->di_gid = dp->di_ogid; 233 dp->di_ogid = -1; 234 inodirty(); 235 } 236 badblk = dupblk = 0; 237 idesc->id_number = inumber; 238 (void)ckinode(dp, idesc); 239 idesc->id_entryno *= btodb(sblock.fs_fsize); 240 if (dp->di_blocks != idesc->id_entryno) { 241 pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)", 242 inumber, dp->di_blocks, idesc->id_entryno); 243 if (preen) 244 printf(" (CORRECTED)\n"); 245 else if (reply("CORRECT") == 0) 246 return; 247 dp = ginode(inumber); 248 dp->di_blocks = idesc->id_entryno; 249 inodirty(); 250 } 251 return; 252unknown: 253 pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
| 295 if (doinglevel2 && 296 (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) { 297 dp = ginode(inumber); 298 dp->di_uid = dp->di_ouid; 299 dp->di_ouid = -1; 300 dp->di_gid = dp->di_ogid; 301 dp->di_ogid = -1; 302 inodirty(); 303 } 304 badblk = dupblk = 0; 305 idesc->id_number = inumber; 306 (void)ckinode(dp, idesc); 307 idesc->id_entryno *= btodb(sblock.fs_fsize); 308 if (dp->di_blocks != idesc->id_entryno) { 309 pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)", 310 inumber, dp->di_blocks, idesc->id_entryno); 311 if (preen) 312 printf(" (CORRECTED)\n"); 313 else if (reply("CORRECT") == 0) 314 return; 315 dp = ginode(inumber); 316 dp->di_blocks = idesc->id_entryno; 317 inodirty(); 318 } 319 return; 320unknown: 321 pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
254 statemap[inumber] = FCLEAR;
| 322 inoinfo(inumber)->ino_state = FCLEAR;
|
255 if (reply("CLEAR") == 1) {
| 323 if (reply("CLEAR") == 1) {
|
256 statemap[inumber] = USTATE;
| 324 inoinfo(inumber)->ino_state = USTATE;
|
257 dp = ginode(inumber); 258 clearinode(dp); 259 inodirty(); 260 } 261} 262 263int 264pass1check(idesc) 265 register struct inodesc *idesc; 266{ 267 int res = KEEPON; 268 int anyout, nfrags; 269 ufs_daddr_t blkno = idesc->id_blkno; 270 register struct dups *dlp; 271 struct dups *new; 272 273 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { 274 blkerror(idesc->id_number, "BAD", blkno); 275 if (badblk++ >= MAXBAD) { 276 pwarn("EXCESSIVE BAD BLKS I=%lu", 277 idesc->id_number); 278 if (preen) 279 printf(" (SKIPPING)\n"); 280 else if (reply("CONTINUE") == 0) { 281 ckfini(0); 282 exit(EEXIT); 283 } 284 return (STOP); 285 } 286 } 287 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 288 if (anyout && chkrange(blkno, 1)) { 289 res = SKIP; 290 } else if (!testbmap(blkno)) { 291 n_blks++; 292 setbmap(blkno); 293 } else { 294 blkerror(idesc->id_number, "DUP", blkno); 295 if (dupblk++ >= MAXDUP) { 296 pwarn("EXCESSIVE DUP BLKS I=%lu", 297 idesc->id_number); 298 if (preen) 299 printf(" (SKIPPING)\n"); 300 else if (reply("CONTINUE") == 0) { 301 ckfini(0); 302 exit(EEXIT); 303 } 304 return (STOP); 305 } 306 new = (struct dups *)malloc(sizeof(struct dups)); 307 if (new == NULL) { 308 pfatal("DUP TABLE OVERFLOW."); 309 if (reply("CONTINUE") == 0) { 310 ckfini(0); 311 exit(EEXIT); 312 } 313 return (STOP); 314 } 315 new->dup = blkno; 316 if (muldup == 0) { 317 duplist = muldup = new; 318 new->next = 0; 319 } else { 320 new->next = muldup->next; 321 muldup->next = new; 322 } 323 for (dlp = duplist; dlp != muldup; dlp = dlp->next) 324 if (dlp->dup == blkno) 325 break; 326 if (dlp == muldup && dlp->dup != blkno) 327 muldup = new; 328 } 329 /* 330 * count the number of blocks found in id_entryno 331 */ 332 idesc->id_entryno++; 333 } 334 return (res); 335}
| 325 dp = ginode(inumber); 326 clearinode(dp); 327 inodirty(); 328 } 329} 330 331int 332pass1check(idesc) 333 register struct inodesc *idesc; 334{ 335 int res = KEEPON; 336 int anyout, nfrags; 337 ufs_daddr_t blkno = idesc->id_blkno; 338 register struct dups *dlp; 339 struct dups *new; 340 341 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { 342 blkerror(idesc->id_number, "BAD", blkno); 343 if (badblk++ >= MAXBAD) { 344 pwarn("EXCESSIVE BAD BLKS I=%lu", 345 idesc->id_number); 346 if (preen) 347 printf(" (SKIPPING)\n"); 348 else if (reply("CONTINUE") == 0) { 349 ckfini(0); 350 exit(EEXIT); 351 } 352 return (STOP); 353 } 354 } 355 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 356 if (anyout && chkrange(blkno, 1)) { 357 res = SKIP; 358 } else if (!testbmap(blkno)) { 359 n_blks++; 360 setbmap(blkno); 361 } else { 362 blkerror(idesc->id_number, "DUP", blkno); 363 if (dupblk++ >= MAXDUP) { 364 pwarn("EXCESSIVE DUP BLKS I=%lu", 365 idesc->id_number); 366 if (preen) 367 printf(" (SKIPPING)\n"); 368 else if (reply("CONTINUE") == 0) { 369 ckfini(0); 370 exit(EEXIT); 371 } 372 return (STOP); 373 } 374 new = (struct dups *)malloc(sizeof(struct dups)); 375 if (new == NULL) { 376 pfatal("DUP TABLE OVERFLOW."); 377 if (reply("CONTINUE") == 0) { 378 ckfini(0); 379 exit(EEXIT); 380 } 381 return (STOP); 382 } 383 new->dup = blkno; 384 if (muldup == 0) { 385 duplist = muldup = new; 386 new->next = 0; 387 } else { 388 new->next = muldup->next; 389 muldup->next = new; 390 } 391 for (dlp = duplist; dlp != muldup; dlp = dlp->next) 392 if (dlp->dup == blkno) 393 break; 394 if (dlp == muldup && dlp->dup != blkno) 395 muldup = new; 396 } 397 /* 398 * count the number of blocks found in id_entryno 399 */ 400 idesc->id_entryno++; 401 } 402 return (res); 403}
|