pass1.c (8871) | pass1.c (23675) |
---|---|
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 --- 18 unchanged lines hidden (view full) --- 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 --- 18 unchanged lines hidden (view full) --- 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 |
35static const char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; | 35static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95"; |
36#endif /* not lint */ 37 38#include <sys/param.h> 39#include <sys/time.h> | 36#endif /* not lint */ 37 38#include <sys/param.h> 39#include <sys/time.h> |
40 |
|
40#include <ufs/ufs/dinode.h> 41#include <ufs/ufs/dir.h> 42#include <ufs/ffs/fs.h> | 41#include <ufs/ufs/dinode.h> 42#include <ufs/ufs/dir.h> 43#include <ufs/ffs/fs.h> |
44 |
|
43#include <stdio.h> 44#include <stdlib.h> | 45#include <stdio.h> 46#include <stdlib.h> |
47#include <err.h> |
|
45#include <string.h> | 48#include <string.h> |
49 |
|
46#include "fsck.h" 47 | 50#include "fsck.h" 51 |
48static daddr_t badblk; 49static daddr_t dupblk; | 52static ufs_daddr_t badblk; 53static ufs_daddr_t dupblk; |
50 | 54 |
51static void checkinode __P((ino_t inumber, struct inodesc *idesc)); | 55static void checkinode __P((ino_t inumber, struct inodesc *)); |
52 53void 54pass1() 55{ 56 ino_t inumber; 57 int c, i, cgd; 58 struct inodesc idesc; 59 --- 8 unchanged lines hidden (view full) --- 68 } else 69 i = cgsblock(&sblock, c); 70 for (; i < cgd; i++) 71 setbmap(i); 72 } 73 /* 74 * Find all allocated blocks. 75 */ | 56 57void 58pass1() 59{ 60 ino_t inumber; 61 int c, i, cgd; 62 struct inodesc idesc; 63 --- 8 unchanged lines hidden (view full) --- 72 } else 73 i = cgsblock(&sblock, c); 74 for (; i < cgd; i++) 75 setbmap(i); 76 } 77 /* 78 * Find all allocated blocks. 79 */ |
76 bzero((char *)&idesc, sizeof(struct inodesc)); | 80 memset(&idesc, 0, sizeof(struct inodesc)); |
77 idesc.id_type = ADDR; 78 idesc.id_func = pass1check; 79 inumber = 0; 80 n_files = n_blks = 0; 81 resetinodebuf(); 82 for (c = 0; c < sblock.fs_ncg; c++) { 83 for (i = 0; i < sblock.fs_ipg; i++, inumber++) { 84 if (inumber < ROOTINO) 85 continue; 86 checkinode(inumber, &idesc); 87 } 88 } 89 freeinodebuf(); 90} 91 | 81 idesc.id_type = ADDR; 82 idesc.id_func = pass1check; 83 inumber = 0; 84 n_files = n_blks = 0; 85 resetinodebuf(); 86 for (c = 0; c < sblock.fs_ncg; c++) { 87 for (i = 0; i < sblock.fs_ipg; i++, inumber++) { 88 if (inumber < ROOTINO) 89 continue; 90 checkinode(inumber, &idesc); 91 } 92 } 93 freeinodebuf(); 94} 95 |
92void | 96static void |
93checkinode(inumber, idesc) 94 ino_t inumber; 95 register struct inodesc *idesc; 96{ 97 register struct dinode *dp; 98 struct zlncnt *zlnp; 99 int ndb, j; 100 mode_t mode; 101 char *symbuf; 102 103 dp = getnextinode(inumber); 104 mode = dp->di_mode & IFMT; 105 if (mode == 0) { | 97checkinode(inumber, idesc) 98 ino_t inumber; 99 register struct inodesc *idesc; 100{ 101 register struct dinode *dp; 102 struct zlncnt *zlnp; 103 int ndb, j; 104 mode_t mode; 105 char *symbuf; 106 107 dp = getnextinode(inumber); 108 mode = dp->di_mode & IFMT; 109 if (mode == 0) { |
106 if (bcmp((char *)dp->di_db, (char *)zino.di_db, 107 NDADDR * sizeof(daddr_t)) || 108 bcmp((char *)dp->di_ib, (char *)zino.di_ib, 109 NIADDR * sizeof(daddr_t)) || | 110 if (memcmp(dp->di_db, zino.di_db, 111 NDADDR * sizeof(ufs_daddr_t)) || 112 memcmp(dp->di_ib, zino.di_ib, 113 NIADDR * sizeof(ufs_daddr_t)) || |
110 dp->di_mode || dp->di_size) { 111 pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); 112 if (reply("CLEAR") == 1) { 113 dp = ginode(inumber); 114 clearinode(dp); 115 inodirty(); 116 } 117 } 118 statemap[inumber] = USTATE; 119 return; 120 } 121 lastino = inumber; 122 if (/* dp->di_size < 0 || */ | 114 dp->di_mode || dp->di_size) { 115 pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber); 116 if (reply("CLEAR") == 1) { 117 dp = ginode(inumber); 118 clearinode(dp); 119 inodirty(); 120 } 121 } 122 statemap[inumber] = USTATE; 123 return; 124 } 125 lastino = inumber; 126 if (/* dp->di_size < 0 || */ |
123 dp->di_size + sblock.fs_bsize - 1 < dp->di_size) { | 127 dp->di_size + sblock.fs_bsize - 1 < dp->di_size /* || 128 (mode == IFDIR && dp->di_size > MAXDIRSIZE) */) { |
124 if (debug) 125 printf("bad size %qu:", dp->di_size); 126 goto unknown; 127 } 128 if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { 129 dp = ginode(inumber); 130 dp->di_size = sblock.fs_fsize; 131 dp->di_mode = IFREG|0600; --- 11 unchanged lines hidden (view full) --- 143 if (mode == IFLNK) { 144 if (doinglevel2 && 145 dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && 146 dp->di_blocks != 0) { 147 symbuf = alloca(secsize); 148 if (bread(fsreadfd, symbuf, 149 fsbtodb(&sblock, dp->di_db[0]), 150 (long)secsize) != 0) | 129 if (debug) 130 printf("bad size %qu:", dp->di_size); 131 goto unknown; 132 } 133 if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) { 134 dp = ginode(inumber); 135 dp->di_size = sblock.fs_fsize; 136 dp->di_mode = IFREG|0600; --- 11 unchanged lines hidden (view full) --- 148 if (mode == IFLNK) { 149 if (doinglevel2 && 150 dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN && 151 dp->di_blocks != 0) { 152 symbuf = alloca(secsize); 153 if (bread(fsreadfd, symbuf, 154 fsbtodb(&sblock, dp->di_db[0]), 155 (long)secsize) != 0) |
151 errexit("cannot read symlink"); | 156 errx(EEXIT, "cannot read symlink"); |
152 if (debug) { 153 symbuf[dp->di_size] = 0; 154 printf("convert symlink %ld(%s) of size %ld\n", 155 inumber, symbuf, (long)dp->di_size); 156 } 157 dp = ginode(inumber); | 157 if (debug) { 158 symbuf[dp->di_size] = 0; 159 printf("convert symlink %ld(%s) of size %ld\n", 160 inumber, symbuf, (long)dp->di_size); 161 } 162 dp = ginode(inumber); |
158 bcopy(symbuf, (caddr_t)dp->di_shortlink, 159 (long)dp->di_size); | 163 memmove(dp->di_shortlink, symbuf, (long)dp->di_size); |
160 dp->di_blocks = 0; 161 inodirty(); 162 } 163 /* 164 * Fake ndb value so direct/indirect block checks below 165 * will detect any garbage after symlink string. 166 */ 167 if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { | 164 dp->di_blocks = 0; 165 inodirty(); 166 } 167 /* 168 * Fake ndb value so direct/indirect block checks below 169 * will detect any garbage after symlink string. 170 */ 171 if ((dp->di_size < sblock.fs_maxsymlinklen) || dp->di_blocks == 0) { |
168 ndb = howmany(dp->di_size, sizeof(daddr_t)); | 172 ndb = howmany(dp->di_size, sizeof(ufs_daddr_t)); |
169 if (ndb > NDADDR) { 170 j = ndb - NDADDR; 171 for (ndb = 1; j > 1; j--) 172 ndb *= NINDIR(&sblock); 173 ndb += NDADDR; 174 } 175 } 176 } --- 16 unchanged lines hidden (view full) --- 193 goto unknown; 194 n_files++; 195 lncntp[inumber] = dp->di_nlink; 196 if (dp->di_nlink <= 0) { 197 zlnp = (struct zlncnt *)malloc(sizeof *zlnp); 198 if (zlnp == NULL) { 199 pfatal("LINK COUNT TABLE OVERFLOW"); 200 if (reply("CONTINUE") == 0) | 173 if (ndb > NDADDR) { 174 j = ndb - NDADDR; 175 for (ndb = 1; j > 1; j--) 176 ndb *= NINDIR(&sblock); 177 ndb += NDADDR; 178 } 179 } 180 } --- 16 unchanged lines hidden (view full) --- 197 goto unknown; 198 n_files++; 199 lncntp[inumber] = dp->di_nlink; 200 if (dp->di_nlink <= 0) { 201 zlnp = (struct zlncnt *)malloc(sizeof *zlnp); 202 if (zlnp == NULL) { 203 pfatal("LINK COUNT TABLE OVERFLOW"); 204 if (reply("CONTINUE") == 0) |
201 errexit(""); | 205 exit(EEXIT); |
202 } else { 203 zlnp->zlncnt = inumber; 204 zlnp->next = zlnhead; 205 zlnhead = zlnp; 206 } 207 } 208 if (mode == IFDIR) { 209 if (dp->di_size == 0) --- 41 unchanged lines hidden (view full) --- 251} 252 253int 254pass1check(idesc) 255 register struct inodesc *idesc; 256{ 257 int res = KEEPON; 258 int anyout, nfrags; | 206 } else { 207 zlnp->zlncnt = inumber; 208 zlnp->next = zlnhead; 209 zlnhead = zlnp; 210 } 211 } 212 if (mode == IFDIR) { 213 if (dp->di_size == 0) --- 41 unchanged lines hidden (view full) --- 255} 256 257int 258pass1check(idesc) 259 register struct inodesc *idesc; 260{ 261 int res = KEEPON; 262 int anyout, nfrags; |
259 daddr_t blkno = idesc->id_blkno; | 263 ufs_daddr_t blkno = idesc->id_blkno; |
260 register struct dups *dlp; 261 struct dups *new; 262 263 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { 264 blkerror(idesc->id_number, "BAD", blkno); 265 if (badblk++ >= MAXBAD) { 266 pwarn("EXCESSIVE BAD BLKS I=%lu", 267 idesc->id_number); 268 if (preen) 269 printf(" (SKIPPING)\n"); 270 else if (reply("CONTINUE") == 0) | 264 register struct dups *dlp; 265 struct dups *new; 266 267 if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) { 268 blkerror(idesc->id_number, "BAD", blkno); 269 if (badblk++ >= MAXBAD) { 270 pwarn("EXCESSIVE BAD BLKS I=%lu", 271 idesc->id_number); 272 if (preen) 273 printf(" (SKIPPING)\n"); 274 else if (reply("CONTINUE") == 0) |
271 errexit(""); | 275 exit(EEXIT); |
272 return (STOP); 273 } 274 } 275 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 276 if (anyout && chkrange(blkno, 1)) { 277 res = SKIP; 278 } else if (!testbmap(blkno)) { 279 n_blks++; 280 setbmap(blkno); 281 } else { 282 blkerror(idesc->id_number, "DUP", blkno); 283 if (dupblk++ >= MAXDUP) { 284 pwarn("EXCESSIVE DUP BLKS I=%lu", 285 idesc->id_number); 286 if (preen) 287 printf(" (SKIPPING)\n"); 288 else if (reply("CONTINUE") == 0) | 276 return (STOP); 277 } 278 } 279 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 280 if (anyout && chkrange(blkno, 1)) { 281 res = SKIP; 282 } else if (!testbmap(blkno)) { 283 n_blks++; 284 setbmap(blkno); 285 } else { 286 blkerror(idesc->id_number, "DUP", blkno); 287 if (dupblk++ >= MAXDUP) { 288 pwarn("EXCESSIVE DUP BLKS I=%lu", 289 idesc->id_number); 290 if (preen) 291 printf(" (SKIPPING)\n"); 292 else if (reply("CONTINUE") == 0) |
289 errexit(""); | 293 exit(EEXIT); |
290 return (STOP); 291 } 292 new = (struct dups *)malloc(sizeof(struct dups)); 293 if (new == NULL) { 294 pfatal("DUP TABLE OVERFLOW."); 295 if (reply("CONTINUE") == 0) | 294 return (STOP); 295 } 296 new = (struct dups *)malloc(sizeof(struct dups)); 297 if (new == NULL) { 298 pfatal("DUP TABLE OVERFLOW."); 299 if (reply("CONTINUE") == 0) |
296 errexit(""); | 300 exit(EEXIT); |
297 return (STOP); 298 } 299 new->dup = blkno; 300 if (muldup == 0) { 301 duplist = muldup = new; 302 new->next = 0; 303 } else { 304 new->next = muldup->next; --- 15 unchanged lines hidden --- | 301 return (STOP); 302 } 303 new->dup = blkno; 304 if (muldup == 0) { 305 duplist = muldup = new; 306 new->next = 0; 307 } else { 308 new->next = muldup->next; --- 15 unchanged lines hidden --- |