inode.c (96483) | inode.c (98542) |
---|---|
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 --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35#if 0 36static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; 37#endif 38static const char rcsid[] = | 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 --- 22 unchanged lines hidden (view full) --- 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35#if 0 36static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; 37#endif 38static const char rcsid[] = |
39 "$FreeBSD: head/sbin/fsck_ffs/inode.c 96483 2002-05-12 23:44:15Z phk $"; | 39 "$FreeBSD: head/sbin/fsck_ffs/inode.c 98542 2002-06-21 06:18:05Z mckusick $"; |
40#endif /* not lint */ 41 42#include <sys/param.h> | 40#endif /* not lint */ 41 42#include <sys/param.h> |
43#include <sys/stdint.h> |
|
43#include <sys/time.h> 44#include <sys/sysctl.h> 45 46#include <ufs/ufs/dinode.h> 47#include <ufs/ufs/dir.h> 48#include <ufs/ffs/fs.h> 49 50#include <err.h> 51#include <pwd.h> 52#include <string.h> 53 54#include "fsck.h" 55 56static ino_t startinum; 57 | 44#include <sys/time.h> 45#include <sys/sysctl.h> 46 47#include <ufs/ufs/dinode.h> 48#include <ufs/ufs/dir.h> 49#include <ufs/ffs/fs.h> 50 51#include <err.h> 52#include <pwd.h> 53#include <string.h> 54 55#include "fsck.h" 56 57static ino_t startinum; 58 |
58static int iblock(struct inodesc *, long ilevel, quad_t isize); | 59static int iblock(struct inodesc *, long ilevel, off_t isize); |
59 60int | 60 61int |
61ckinode(struct dinode *dp, struct inodesc *idesc) | 62ckinode(union dinode *dp, struct inodesc *idesc) |
62{ | 63{ |
63 ufs_daddr_t *ap; 64 int ret; 65 long n, ndb, offset; 66 struct dinode dino; 67 quad_t remsize, sizepb; | 64 off_t remsize, sizepb; 65 int i, offset, ret; 66 union dinode dino; 67 ufs2_daddr_t ndb; |
68 mode_t mode; 69 char pathbuf[MAXPATHLEN + 1]; 70 71 if (idesc->id_fix != IGNORE) 72 idesc->id_fix = DONTKNOW; 73 idesc->id_lbn = -1; 74 idesc->id_entryno = 0; | 68 mode_t mode; 69 char pathbuf[MAXPATHLEN + 1]; 70 71 if (idesc->id_fix != IGNORE) 72 idesc->id_fix = DONTKNOW; 73 idesc->id_lbn = -1; 74 idesc->id_entryno = 0; |
75 idesc->id_filesize = dp->di_size; 76 mode = dp->di_mode & IFMT; | 75 idesc->id_filesize = DIP(dp, di_size); 76 mode = DIP(dp, di_mode) & IFMT; |
77 if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && | 77 if (mode == IFBLK || mode == IFCHR || (mode == IFLNK && |
78 dp->di_size < (unsigned)sblock.fs_maxsymlinklen)) | 78 DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen)) |
79 return (KEEPON); | 79 return (KEEPON); |
80 dino = *dp; 81 ndb = howmany(dino.di_size, sblock.fs_bsize); 82 for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { | 80 if (sblock.fs_magic == FS_UFS1_MAGIC) 81 dino.dp1 = dp->dp1; 82 else 83 dino.dp2 = dp->dp2; 84 ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize); 85 for (i = 0; i < NDADDR; i++) { |
83 idesc->id_lbn++; | 86 idesc->id_lbn++; |
84 if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) | 87 if (--ndb == 0 && 88 (offset = blkoff(&sblock, DIP(&dino, di_size))) != 0) |
85 idesc->id_numfrags = 86 numfrags(&sblock, fragroundup(&sblock, offset)); 87 else 88 idesc->id_numfrags = sblock.fs_frag; | 89 idesc->id_numfrags = 90 numfrags(&sblock, fragroundup(&sblock, offset)); 91 else 92 idesc->id_numfrags = sblock.fs_frag; |
89 if (*ap == 0) { | 93 if (DIP(&dino, di_db[i]) == 0) { |
90 if (idesc->id_type == DATA && ndb >= 0) { 91 /* An empty block in a directory XXX */ 92 getpathname(pathbuf, idesc->id_number, 93 idesc->id_number); 94 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 95 pathbuf); 96 if (reply("ADJUST LENGTH") == 1) { 97 dp = ginode(idesc->id_number); | 94 if (idesc->id_type == DATA && ndb >= 0) { 95 /* An empty block in a directory XXX */ 96 getpathname(pathbuf, idesc->id_number, 97 idesc->id_number); 98 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 99 pathbuf); 100 if (reply("ADJUST LENGTH") == 1) { 101 dp = ginode(idesc->id_number); |
98 dp->di_size = (ap - &dino.di_db[0]) * 99 sblock.fs_bsize; | 102 DIP(dp, di_size) = i * sblock.fs_bsize; |
100 printf( 101 "YOU MUST RERUN FSCK AFTERWARDS\n"); 102 rerun = 1; 103 inodirty(); 104 105 } 106 } 107 continue; 108 } | 103 printf( 104 "YOU MUST RERUN FSCK AFTERWARDS\n"); 105 rerun = 1; 106 inodirty(); 107 108 } 109 } 110 continue; 111 } |
109 idesc->id_blkno = *ap; | 112 idesc->id_blkno = DIP(&dino, di_db[i]); |
110 if (idesc->id_type != DATA) 111 ret = (*idesc->id_func)(idesc); 112 else 113 ret = dirscan(idesc); 114 if (ret & STOP) 115 return (ret); 116 } 117 idesc->id_numfrags = sblock.fs_frag; | 113 if (idesc->id_type != DATA) 114 ret = (*idesc->id_func)(idesc); 115 else 116 ret = dirscan(idesc); 117 if (ret & STOP) 118 return (ret); 119 } 120 idesc->id_numfrags = sblock.fs_frag; |
118 remsize = dino.di_size - sblock.fs_bsize * NDADDR; | 121 remsize = DIP(&dino, di_size) - sblock.fs_bsize * NDADDR; |
119 sizepb = sblock.fs_bsize; | 122 sizepb = sblock.fs_bsize; |
120 for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { | 123 for (i = 0; i < NIADDR; i++) { |
121 sizepb *= NINDIR(&sblock); | 124 sizepb *= NINDIR(&sblock); |
122 if (*ap) { 123 idesc->id_blkno = *ap; 124 ret = iblock(idesc, n, remsize); | 125 if (DIP(&dino, di_ib[i])) { 126 idesc->id_blkno = DIP(&dino, di_ib[i]); 127 ret = iblock(idesc, i + 1, remsize); |
125 if (ret & STOP) 126 return (ret); 127 } else { 128 idesc->id_lbn += sizepb / sblock.fs_bsize; 129 if (idesc->id_type == DATA && remsize > 0) { 130 /* An empty block in a directory XXX */ 131 getpathname(pathbuf, idesc->id_number, 132 idesc->id_number); 133 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 134 pathbuf); 135 if (reply("ADJUST LENGTH") == 1) { 136 dp = ginode(idesc->id_number); | 128 if (ret & STOP) 129 return (ret); 130 } else { 131 idesc->id_lbn += sizepb / sblock.fs_bsize; 132 if (idesc->id_type == DATA && remsize > 0) { 133 /* An empty block in a directory XXX */ 134 getpathname(pathbuf, idesc->id_number, 135 idesc->id_number); 136 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 137 pathbuf); 138 if (reply("ADJUST LENGTH") == 1) { 139 dp = ginode(idesc->id_number); |
137 dp->di_size -= remsize; | 140 DIP(dp, di_size) -= remsize; |
138 remsize = 0; 139 printf( 140 "YOU MUST RERUN FSCK AFTERWARDS\n"); 141 rerun = 1; 142 inodirty(); 143 break; 144 } 145 } 146 } 147 remsize -= sizepb; 148 } 149 return (KEEPON); 150} 151 152static int | 141 remsize = 0; 142 printf( 143 "YOU MUST RERUN FSCK AFTERWARDS\n"); 144 rerun = 1; 145 inodirty(); 146 break; 147 } 148 } 149 } 150 remsize -= sizepb; 151 } 152 return (KEEPON); 153} 154 155static int |
153iblock(struct inodesc *idesc, long ilevel, quad_t isize) | 156iblock(struct inodesc *idesc, long ilevel, off_t isize) |
154{ | 157{ |
155 ufs_daddr_t *ap; 156 ufs_daddr_t *aplim; | |
157 struct bufarea *bp; 158 int i, n, (*func)(), nif; | 158 struct bufarea *bp; 159 int i, n, (*func)(), nif; |
159 quad_t sizepb; | 160 off_t sizepb; |
160 char buf[BUFSIZ]; 161 char pathbuf[MAXPATHLEN + 1]; | 161 char buf[BUFSIZ]; 162 char pathbuf[MAXPATHLEN + 1]; |
162 struct dinode *dp; | 163 union dinode *dp; |
163 164 if (idesc->id_type != DATA) { 165 func = idesc->id_func; 166 if (((n = (*func)(idesc)) & KEEPON) == 0) 167 return (n); 168 } else 169 func = dirscan; 170 if (chkrange(idesc->id_blkno, idesc->id_numfrags)) 171 return (SKIP); 172 bp = getdatablk(idesc->id_blkno, sblock.fs_bsize); 173 ilevel--; 174 for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) 175 sizepb *= NINDIR(&sblock); | 164 165 if (idesc->id_type != DATA) { 166 func = idesc->id_func; 167 if (((n = (*func)(idesc)) & KEEPON) == 0) 168 return (n); 169 } else 170 func = dirscan; 171 if (chkrange(idesc->id_blkno, idesc->id_numfrags)) 172 return (SKIP); 173 bp = getdatablk(idesc->id_blkno, sblock.fs_bsize); 174 ilevel--; 175 for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) 176 sizepb *= NINDIR(&sblock); |
176 nif = howmany(isize , sizepb); 177 if (nif > NINDIR(&sblock)) | 177 if (howmany(isize, sizepb) > NINDIR(&sblock)) |
178 nif = NINDIR(&sblock); | 178 nif = NINDIR(&sblock); |
179 else 180 nif = howmany(isize, sizepb); |
|
179 if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) { | 181 if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) { |
180 aplim = &bp->b_un.b_indir[NINDIR(&sblock)]; 181 for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) { 182 if (*ap == 0) | 182 for (i = nif; i < NINDIR(&sblock); i++) { 183 if (IBLK(bp, i) == 0) |
183 continue; 184 (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu", 185 (u_long)idesc->id_number); 186 if (preen) { 187 pfatal("%s", buf); 188 } else if (dofix(idesc, buf)) { | 184 continue; 185 (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu", 186 (u_long)idesc->id_number); 187 if (preen) { 188 pfatal("%s", buf); 189 } else if (dofix(idesc, buf)) { |
189 *ap = 0; | 190 IBLK(bp, i) = 0; |
190 dirty(bp); 191 } 192 } 193 flush(fswritefd, bp); 194 } | 191 dirty(bp); 192 } 193 } 194 flush(fswritefd, bp); 195 } |
195 aplim = &bp->b_un.b_indir[nif]; 196 for (ap = bp->b_un.b_indir; ap < aplim; ap++) { | 196 for (i = 0; i < nif; i++) { |
197 if (ilevel == 0) 198 idesc->id_lbn++; | 197 if (ilevel == 0) 198 idesc->id_lbn++; |
199 if (*ap) { 200 idesc->id_blkno = *ap; | 199 if (IBLK(bp, i)) { 200 idesc->id_blkno = IBLK(bp, i); |
201 if (ilevel == 0) 202 n = (*func)(idesc); 203 else 204 n = iblock(idesc, ilevel, isize); 205 if (n & STOP) { 206 bp->b_flags &= ~B_INUSE; 207 return (n); 208 } 209 } else { 210 if (idesc->id_type == DATA && isize > 0) { 211 /* An empty block in a directory XXX */ 212 getpathname(pathbuf, idesc->id_number, 213 idesc->id_number); 214 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 215 pathbuf); 216 if (reply("ADJUST LENGTH") == 1) { 217 dp = ginode(idesc->id_number); | 201 if (ilevel == 0) 202 n = (*func)(idesc); 203 else 204 n = iblock(idesc, ilevel, isize); 205 if (n & STOP) { 206 bp->b_flags &= ~B_INUSE; 207 return (n); 208 } 209 } else { 210 if (idesc->id_type == DATA && isize > 0) { 211 /* An empty block in a directory XXX */ 212 getpathname(pathbuf, idesc->id_number, 213 idesc->id_number); 214 pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS", 215 pathbuf); 216 if (reply("ADJUST LENGTH") == 1) { 217 dp = ginode(idesc->id_number); |
218 dp->di_size -= isize; | 218 DIP(dp, di_size) -= isize; |
219 isize = 0; 220 printf( 221 "YOU MUST RERUN FSCK AFTERWARDS\n"); 222 rerun = 1; 223 inodirty(); 224 bp->b_flags &= ~B_INUSE; 225 return(STOP); 226 } --- 5 unchanged lines hidden (view full) --- 232 return (KEEPON); 233} 234 235/* 236 * Check that a block in a legal block number. 237 * Return 0 if in range, 1 if out of range. 238 */ 239int | 219 isize = 0; 220 printf( 221 "YOU MUST RERUN FSCK AFTERWARDS\n"); 222 rerun = 1; 223 inodirty(); 224 bp->b_flags &= ~B_INUSE; 225 return(STOP); 226 } --- 5 unchanged lines hidden (view full) --- 232 return (KEEPON); 233} 234 235/* 236 * Check that a block in a legal block number. 237 * Return 0 if in range, 1 if out of range. 238 */ 239int |
240chkrange(ufs_daddr_t blk, int cnt) | 240chkrange(ufs2_daddr_t blk, int cnt) |
241{ 242 int c; 243 244 if (cnt <= 0 || blk <= 0 || blk > maxfsblock || 245 cnt - 1 > maxfsblock - blk) 246 return (1); 247 if (cnt > sblock.fs_frag || 248 fragnum(&sblock, blk) + cnt > sblock.fs_frag) { --- 26 unchanged lines hidden (view full) --- 275 } 276 } 277 return (0); 278} 279 280/* 281 * General purpose interface for reading inodes. 282 */ | 241{ 242 int c; 243 244 if (cnt <= 0 || blk <= 0 || blk > maxfsblock || 245 cnt - 1 > maxfsblock - blk) 246 return (1); 247 if (cnt > sblock.fs_frag || 248 fragnum(&sblock, blk) + cnt > sblock.fs_frag) { --- 26 unchanged lines hidden (view full) --- 275 } 276 } 277 return (0); 278} 279 280/* 281 * General purpose interface for reading inodes. 282 */ |
283struct dinode * | 283union dinode * |
284ginode(ino_t inumber) 285{ | 284ginode(ino_t inumber) 285{ |
286 ufs_daddr_t iblk; | 286 ufs2_daddr_t iblk; |
287 288 if (inumber < ROOTINO || inumber > maxino) 289 errx(EEXIT, "bad inode number %d to ginode", inumber); 290 if (startinum == 0 || 291 inumber < startinum || inumber >= startinum + INOPB(&sblock)) { 292 iblk = ino_to_fsba(&sblock, inumber); 293 if (pbp != 0) 294 pbp->b_flags &= ~B_INUSE; 295 pbp = getdatablk(iblk, sblock.fs_bsize); 296 startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); 297 } | 287 288 if (inumber < ROOTINO || inumber > maxino) 289 errx(EEXIT, "bad inode number %d to ginode", inumber); 290 if (startinum == 0 || 291 inumber < startinum || inumber >= startinum + INOPB(&sblock)) { 292 iblk = ino_to_fsba(&sblock, inumber); 293 if (pbp != 0) 294 pbp->b_flags &= ~B_INUSE; 295 pbp = getdatablk(iblk, sblock.fs_bsize); 296 startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); 297 } |
298 return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]); | 298 if (sblock.fs_magic == FS_UFS1_MAGIC) 299 return ((union dinode *) 300 &pbp->b_un.b_dinode1[inumber % INOPB(&sblock)]); 301 return ((union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)]); |
299} 300 301/* 302 * Special purpose version of ginode used to optimize first pass 303 * over all the inodes in numerical order. 304 */ 305static ino_t nextino, lastinum, lastvalidinum; 306static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; | 302} 303 304/* 305 * Special purpose version of ginode used to optimize first pass 306 * over all the inodes in numerical order. 307 */ 308static ino_t nextino, lastinum, lastvalidinum; 309static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; |
307static struct dinode *inodebuf; | 310static caddr_t inodebuf; |
308 | 311 |
309struct dinode * | 312union dinode * |
310getnextinode(ino_t inumber) 311{ 312 long size; | 313getnextinode(ino_t inumber) 314{ 315 long size; |
313 ufs_daddr_t dblk; 314 static struct dinode *dp; | 316 ufs2_daddr_t dblk; 317 union dinode *dp; 318 static caddr_t nextinop; |
315 316 if (inumber != nextino++ || inumber > lastvalidinum) 317 errx(EEXIT, "bad inode number %d to nextinode", inumber); 318 if (inumber >= lastinum) { 319 readcnt++; 320 dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); 321 if (readcnt % readpercg == 0) { 322 size = partialsize; 323 lastinum += partialcnt; 324 } else { 325 size = inobufsize; 326 lastinum += fullcnt; 327 } 328 /* 329 * If bread returns an error, it will already have zeroed 330 * out the buffer, so we do not need to do so here. 331 */ | 319 320 if (inumber != nextino++ || inumber > lastvalidinum) 321 errx(EEXIT, "bad inode number %d to nextinode", inumber); 322 if (inumber >= lastinum) { 323 readcnt++; 324 dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); 325 if (readcnt % readpercg == 0) { 326 size = partialsize; 327 lastinum += partialcnt; 328 } else { 329 size = inobufsize; 330 lastinum += fullcnt; 331 } 332 /* 333 * If bread returns an error, it will already have zeroed 334 * out the buffer, so we do not need to do so here. 335 */ |
332 (void)bread(fsreadfd, (char *)inodebuf, dblk, size); 333 dp = inodebuf; | 336 (void)bread(fsreadfd, inodebuf, dblk, size); 337 nextinop = inodebuf; |
334 } | 338 } |
335 return (dp++); | 339 dp = (union dinode *)nextinop; 340 if (sblock.fs_magic == FS_UFS1_MAGIC) 341 nextinop += sizeof(struct ufs1_dinode); 342 else 343 nextinop += sizeof(struct ufs2_dinode); 344 return (dp); |
336} 337 338void 339setinodebuf(ino_t inum) 340{ 341 342 if (inum % sblock.fs_ipg != 0) 343 errx(EEXIT, "bad inode number %d to setinodebuf", inum); 344 lastvalidinum = inum + sblock.fs_ipg - 1; 345 startinum = 0; 346 nextino = inum; 347 lastinum = inum; 348 readcnt = 0; 349 if (inodebuf != NULL) 350 return; 351 inobufsize = blkroundup(&sblock, INOBUFSIZE); | 345} 346 347void 348setinodebuf(ino_t inum) 349{ 350 351 if (inum % sblock.fs_ipg != 0) 352 errx(EEXIT, "bad inode number %d to setinodebuf", inum); 353 lastvalidinum = inum + sblock.fs_ipg - 1; 354 startinum = 0; 355 nextino = inum; 356 lastinum = inum; 357 readcnt = 0; 358 if (inodebuf != NULL) 359 return; 360 inobufsize = blkroundup(&sblock, INOBUFSIZE); |
352 fullcnt = inobufsize / sizeof(struct dinode); | 361 fullcnt = inobufsize / ((sblock.fs_magic == FS_UFS1_MAGIC) ? 362 sizeof(struct ufs1_dinode) : sizeof(struct ufs2_dinode)); |
353 readpercg = sblock.fs_ipg / fullcnt; 354 partialcnt = sblock.fs_ipg % fullcnt; | 363 readpercg = sblock.fs_ipg / fullcnt; 364 partialcnt = sblock.fs_ipg % fullcnt; |
355 partialsize = partialcnt * sizeof(struct dinode); | 365 partialsize = partialcnt * ((sblock.fs_magic == FS_UFS1_MAGIC) ? 366 sizeof(struct ufs1_dinode) : sizeof(struct ufs2_dinode)); |
356 if (partialcnt != 0) { 357 readpercg++; 358 } else { 359 partialcnt = fullcnt; 360 partialsize = inobufsize; 361 } | 367 if (partialcnt != 0) { 368 readpercg++; 369 } else { 370 partialcnt = fullcnt; 371 partialsize = inobufsize; 372 } |
362 if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL) | 373 if ((inodebuf = malloc((unsigned)inobufsize)) == NULL) |
363 errx(EEXIT, "cannot allocate space for inode buffer"); 364} 365 366void 367freeinodebuf(void) 368{ 369 370 if (inodebuf != NULL) --- 4 unchanged lines hidden (view full) --- 375/* 376 * Routines to maintain information about directory inodes. 377 * This is built during the first pass and used during the 378 * second and third passes. 379 * 380 * Enter inodes into the cache. 381 */ 382void | 374 errx(EEXIT, "cannot allocate space for inode buffer"); 375} 376 377void 378freeinodebuf(void) 379{ 380 381 if (inodebuf != NULL) --- 4 unchanged lines hidden (view full) --- 386/* 387 * Routines to maintain information about directory inodes. 388 * This is built during the first pass and used during the 389 * second and third passes. 390 * 391 * Enter inodes into the cache. 392 */ 393void |
383cacheino(struct dinode *dp, ino_t inumber) | 394cacheino(union dinode *dp, ino_t inumber) |
384{ | 395{ |
385 struct inoinfo *inp; 386 struct inoinfo **inpp; 387 int blks; | 396 struct inoinfo *inp, **inpp; 397 int i, blks; |
388 | 398 |
389 blks = howmany(dp->di_size, sblock.fs_bsize); 390 if (blks > NDADDR) | 399 if (howmany(DIP(dp, di_size), sblock.fs_bsize) > NDADDR) |
391 blks = NDADDR + NIADDR; | 400 blks = NDADDR + NIADDR; |
401 else 402 blks = howmany(DIP(dp, di_size), sblock.fs_bsize); |
|
392 inp = (struct inoinfo *) | 403 inp = (struct inoinfo *) |
393 malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t)); | 404 malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t)); |
394 if (inp == NULL) 395 errx(EEXIT, "cannot increase directory list"); 396 inpp = &inphead[inumber % dirhash]; 397 inp->i_nexthash = *inpp; 398 *inpp = inp; 399 inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0; 400 inp->i_dotdot = (ino_t)0; 401 inp->i_number = inumber; | 405 if (inp == NULL) 406 errx(EEXIT, "cannot increase directory list"); 407 inpp = &inphead[inumber % dirhash]; 408 inp->i_nexthash = *inpp; 409 *inpp = inp; 410 inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0; 411 inp->i_dotdot = (ino_t)0; 412 inp->i_number = inumber; |
402 inp->i_isize = dp->di_size; 403 inp->i_numblks = blks * sizeof(ufs_daddr_t); 404 memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks); | 413 inp->i_isize = DIP(dp, di_size); 414 inp->i_numblks = blks; 415 for (i = 0; i < (blks < NDADDR ? blks : NDADDR); i++) 416 inp->i_blks[i] = DIP(dp, di_db[i]); 417 if (blks > NDADDR) 418 for (i = 0; i < NIADDR; i++) 419 inp->i_blks[NDADDR + i] = DIP(dp, di_ib[i]); |
405 if (inplast == listmax) { 406 listmax += 100; 407 inpsort = (struct inoinfo **)realloc((char *)inpsort, 408 (unsigned)listmax * sizeof(struct inoinfo *)); 409 if (inpsort == NULL) 410 errx(EEXIT, "cannot increase directory list"); 411 } 412 inpsort[inplast++] = inp; --- 38 unchanged lines hidden (view full) --- 451{ 452 453 dirty(pbp); 454} 455 456void 457clri(struct inodesc *idesc, char *type, int flag) 458{ | 420 if (inplast == listmax) { 421 listmax += 100; 422 inpsort = (struct inoinfo **)realloc((char *)inpsort, 423 (unsigned)listmax * sizeof(struct inoinfo *)); 424 if (inpsort == NULL) 425 errx(EEXIT, "cannot increase directory list"); 426 } 427 inpsort[inplast++] = inp; --- 38 unchanged lines hidden (view full) --- 466{ 467 468 dirty(pbp); 469} 470 471void 472clri(struct inodesc *idesc, char *type, int flag) 473{ |
459 struct dinode *dp; | 474 union dinode *dp; |
460 461 dp = ginode(idesc->id_number); 462 if (flag == 1) { 463 pwarn("%s %s", type, | 475 476 dp = ginode(idesc->id_number); 477 if (flag == 1) { 478 pwarn("%s %s", type, |
464 (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE"); | 479 (DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"); |
465 pinode(idesc->id_number); 466 } 467 if (preen || reply("CLEAR") == 1) { 468 if (preen) 469 printf(" (CLEARED)\n"); 470 n_files--; 471 if (bkgrdflag == 0) { 472 (void)ckinode(dp, idesc); 473 inoinfo(idesc->id_number)->ino_state = USTATE; 474 clearinode(dp); 475 inodirty(); 476 } else { 477 cmd.value = idesc->id_number; | 480 pinode(idesc->id_number); 481 } 482 if (preen || reply("CLEAR") == 1) { 483 if (preen) 484 printf(" (CLEARED)\n"); 485 n_files--; 486 if (bkgrdflag == 0) { 487 (void)ckinode(dp, idesc); 488 inoinfo(idesc->id_number)->ino_state = USTATE; 489 clearinode(dp); 490 inodirty(); 491 } else { 492 cmd.value = idesc->id_number; |
478 cmd.size = -dp->di_nlink; | 493 cmd.size = -DIP(dp, di_nlink); |
479 if (debug) 480 printf("adjrefcnt ino %ld amt %ld\n", 481 (long)cmd.value, cmd.size); 482 if (sysctl(adjrefcnt, MIBSIZE, 0, 0, 483 &cmd, sizeof cmd) == -1) 484 rwerror("ADJUST INODE", cmd.value); 485 } 486 } --- 38 unchanged lines hidden (view full) --- 525 } 526 dirp->d_ino = 0; 527 return (STOP|FOUND|ALTERED); 528} 529 530void 531pinode(ino_t ino) 532{ | 494 if (debug) 495 printf("adjrefcnt ino %ld amt %ld\n", 496 (long)cmd.value, cmd.size); 497 if (sysctl(adjrefcnt, MIBSIZE, 0, 0, 498 &cmd, sizeof cmd) == -1) 499 rwerror("ADJUST INODE", cmd.value); 500 } 501 } --- 38 unchanged lines hidden (view full) --- 540 } 541 dirp->d_ino = 0; 542 return (STOP|FOUND|ALTERED); 543} 544 545void 546pinode(ino_t ino) 547{ |
533 struct dinode *dp; | 548 union dinode *dp; |
534 char *p; 535 struct passwd *pw; 536 time_t t; 537 538 printf(" I=%lu ", (u_long)ino); 539 if (ino < ROOTINO || ino > maxino) 540 return; 541 dp = ginode(ino); 542 printf(" OWNER="); | 549 char *p; 550 struct passwd *pw; 551 time_t t; 552 553 printf(" I=%lu ", (u_long)ino); 554 if (ino < ROOTINO || ino > maxino) 555 return; 556 dp = ginode(ino); 557 printf(" OWNER="); |
543 if ((pw = getpwuid((int)dp->di_uid)) != 0) | 558 if ((pw = getpwuid((int)DIP(dp, di_uid))) != 0) |
544 printf("%s ", pw->pw_name); 545 else | 559 printf("%s ", pw->pw_name); 560 else |
546 printf("%u ", (unsigned)dp->di_uid); 547 printf("MODE=%o\n", dp->di_mode); | 561 printf("%u ", (unsigned)DIP(dp, di_uid)); 562 printf("MODE=%o\n", DIP(dp, di_mode)); |
548 if (preen) 549 printf("%s: ", cdevname); | 563 if (preen) 564 printf("%s: ", cdevname); |
550 printf("SIZE=%qu ", dp->di_size); 551 t = dp->di_mtime; | 565 printf("SIZE=%qu ", DIP(dp, di_size)); 566 t = DIP(dp, di_mtime); |
552 p = ctime(&t); 553 printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); 554} 555 556void | 567 p = ctime(&t); 568 printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); 569} 570 571void |
557blkerror(ino_t ino, char *type, ufs_daddr_t blk) | 572blkerror(ino_t ino, char *type, ufs2_daddr_t blk) |
558{ 559 | 573{ 574 |
560 pfatal("%ld %s I=%lu", (long)blk, type, (u_long)ino); | 575 pfatal("%lld %s I=%lu", (intmax_t)blk, type, (u_long)ino); |
561 printf("\n"); 562 switch (inoinfo(ino)->ino_state) { 563 564 case FSTATE: 565 inoinfo(ino)->ino_state = FCLEAR; 566 return; 567 568 case DSTATE: --- 12 unchanged lines hidden (view full) --- 581 582/* 583 * allocate an unused inode 584 */ 585ino_t 586allocino(ino_t request, int type) 587{ 588 ino_t ino; | 576 printf("\n"); 577 switch (inoinfo(ino)->ino_state) { 578 579 case FSTATE: 580 inoinfo(ino)->ino_state = FCLEAR; 581 return; 582 583 case DSTATE: --- 12 unchanged lines hidden (view full) --- 596 597/* 598 * allocate an unused inode 599 */ 600ino_t 601allocino(ino_t request, int type) 602{ 603 ino_t ino; |
589 struct dinode *dp; | 604 union dinode *dp; |
590 struct cg *cgp = &cgrp; 591 int cg; 592 593 if (request == 0) 594 request = ROOTINO; 595 else if (inoinfo(request)->ino_state != USTATE) 596 return (0); 597 for (ino = request; ino < maxino; ino++) --- 16 unchanged lines hidden (view full) --- 614 case IFLNK: 615 inoinfo(ino)->ino_state = FSTATE; 616 break; 617 default: 618 return (0); 619 } 620 cgdirty(); 621 dp = ginode(ino); | 605 struct cg *cgp = &cgrp; 606 int cg; 607 608 if (request == 0) 609 request = ROOTINO; 610 else if (inoinfo(request)->ino_state != USTATE) 611 return (0); 612 for (ino = request; ino < maxino; ino++) --- 16 unchanged lines hidden (view full) --- 629 case IFLNK: 630 inoinfo(ino)->ino_state = FSTATE; 631 break; 632 default: 633 return (0); 634 } 635 cgdirty(); 636 dp = ginode(ino); |
622 dp->di_db[0] = allocblk((long)1); 623 if (dp->di_db[0] == 0) { | 637 DIP(dp, di_db[0]) = allocblk((long)1); 638 if (DIP(dp, di_db[0]) == 0) { |
624 inoinfo(ino)->ino_state = USTATE; 625 return (0); 626 } | 639 inoinfo(ino)->ino_state = USTATE; 640 return (0); 641 } |
627 dp->di_mode = type; 628 dp->di_flags = 0; 629 dp->di_atime = time(NULL); 630 dp->di_mtime = dp->di_ctime = dp->di_atime; 631 dp->di_mtimensec = dp->di_ctimensec = dp->di_atimensec = 0; 632 dp->di_size = sblock.fs_fsize; 633 dp->di_blocks = btodb(sblock.fs_fsize); | 642 DIP(dp, di_mode) = type; 643 DIP(dp, di_flags) = 0; 644 DIP(dp, di_atime) = time(NULL); 645 DIP(dp, di_mtime) = DIP(dp, di_ctime) = DIP(dp, di_atime); 646 DIP(dp, di_mtimensec) = 0; 647 DIP(dp, di_ctimensec) = 0; 648 DIP(dp, di_atimensec) = 0; 649 DIP(dp, di_size) = sblock.fs_fsize; 650 DIP(dp, di_blocks) = btodb(sblock.fs_fsize); |
634 n_files++; 635 inodirty(); 636 inoinfo(ino)->ino_type = IFTODT(type); 637 return (ino); 638} 639 640/* 641 * deallocate an inode 642 */ 643void 644freeino(ino_t ino) 645{ 646 struct inodesc idesc; | 651 n_files++; 652 inodirty(); 653 inoinfo(ino)->ino_type = IFTODT(type); 654 return (ino); 655} 656 657/* 658 * deallocate an inode 659 */ 660void 661freeino(ino_t ino) 662{ 663 struct inodesc idesc; |
647 struct dinode *dp; | 664 union dinode *dp; |
648 649 memset(&idesc, 0, sizeof(struct inodesc)); 650 idesc.id_type = ADDR; 651 idesc.id_func = pass4check; 652 idesc.id_number = ino; 653 dp = ginode(ino); 654 (void)ckinode(dp, &idesc); 655 clearinode(dp); 656 inodirty(); 657 inoinfo(ino)->ino_state = USTATE; 658 n_files--; 659} | 665 666 memset(&idesc, 0, sizeof(struct inodesc)); 667 idesc.id_type = ADDR; 668 idesc.id_func = pass4check; 669 idesc.id_number = ino; 670 dp = ginode(ino); 671 (void)ckinode(dp, &idesc); 672 clearinode(dp); 673 inodirty(); 674 inoinfo(ino)->ino_state = USTATE; 675 n_files--; 676} |