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[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95"; |
36#endif /* not lint */ 37 38#include <sys/param.h> 39#include <sys/time.h> |
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 <pwd.h> 47#include <stdio.h> 48#include <stdlib.h> 49#include <string.h> |
50 |
51#include "fsck.h" 52 53static ino_t startinum; 54 |
55static int iblock __P((struct inodesc *, long ilevel, quad_t isize)); |
56 57int 58ckinode(dp, idesc) 59 struct dinode *dp; 60 register struct inodesc *idesc; 61{ |
62 ufs_daddr_t *ap; 63 long ret, n, ndb, offset; |
64 struct dinode dino; 65 quad_t remsize, sizepb; 66 mode_t mode; 67 char pathbuf[MAXPATHLEN + 1]; 68 69 if (idesc->id_fix != IGNORE) 70 idesc->id_fix = DONTKNOW; 71 idesc->id_entryno = 0; --- 73 unchanged lines hidden (view full) --- 145} 146 147static int 148iblock(idesc, ilevel, isize) 149 struct inodesc *idesc; 150 long ilevel; 151 quad_t isize; 152{ |
153 ufs_daddr_t *ap; 154 ufs_daddr_t *aplim; 155 struct bufarea *bp; |
156 int i, n, (*func)(), nif; 157 quad_t sizepb; 158 char buf[BUFSIZ]; 159 char pathbuf[MAXPATHLEN + 1]; 160 struct dinode *dp; 161 162 if (idesc->id_type == ADDR) { 163 func = idesc->id_func; --- 63 unchanged lines hidden (view full) --- 227} 228 229/* 230 * Check that a block in a legal block number. 231 * Return 0 if in range, 1 if out of range. 232 */ 233int 234chkrange(blk, cnt) |
235 ufs_daddr_t blk; |
236 int cnt; 237{ 238 register int c; 239 240 if ((unsigned)(blk + cnt) > maxfsblock) 241 return (1); 242 c = dtog(&sblock, blk); 243 if (blk < cgdmin(&sblock, c)) { --- 22 unchanged lines hidden (view full) --- 266 267/* 268 * General purpose interface for reading inodes. 269 */ 270struct dinode * 271ginode(inumber) 272 ino_t inumber; 273{ |
274 ufs_daddr_t iblk; |
275 276 if (inumber < ROOTINO || inumber > maxino) |
277 errx(EEXIT, "bad inode number %d to ginode", inumber); |
278 if (startinum == 0 || 279 inumber < startinum || inumber >= startinum + INOPB(&sblock)) { 280 iblk = ino_to_fsba(&sblock, inumber); 281 if (pbp != 0) 282 pbp->b_flags &= ~B_INUSE; 283 pbp = getdatablk(iblk, sblock.fs_bsize); 284 startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); 285 } --- 8 unchanged lines hidden (view full) --- 294long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; 295struct dinode *inodebuf; 296 297struct dinode * 298getnextinode(inumber) 299 ino_t inumber; 300{ 301 long size; |
302 ufs_daddr_t dblk; |
303 static struct dinode *dp; 304 305 if (inumber != nextino++ || inumber > maxino) |
306 errx(EEXIT, "bad inode number %d to nextinode", inumber); |
307 if (inumber >= lastinum) { 308 readcnt++; 309 dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum)); 310 if (readcnt % readpercg == 0) { 311 size = partialsize; 312 lastinum += partialcnt; 313 } else { 314 size = inobufsize; --- 21 unchanged lines hidden (view full) --- 336 if (partialcnt != 0) { 337 readpercg++; 338 } else { 339 partialcnt = fullcnt; 340 partialsize = inobufsize; 341 } 342 if (inodebuf == NULL && 343 (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL) |
344 errx(EEXIT, "Cannot allocate space for inode buffer"); |
345 while (nextino < ROOTINO) 346 (void)getnextinode(nextino); 347} 348 349void 350freeinodebuf() 351{ 352 --- 17 unchanged lines hidden (view full) --- 370 register struct inoinfo *inp; 371 struct inoinfo **inpp; 372 unsigned int blks; 373 374 blks = howmany(dp->di_size, sblock.fs_bsize); 375 if (blks > NDADDR) 376 blks = NDADDR + NIADDR; 377 inp = (struct inoinfo *) |
378 malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t)); |
379 if (inp == NULL) 380 return; 381 inpp = &inphead[inumber % numdirs]; 382 inp->i_nexthash = *inpp; 383 *inpp = inp; 384 if (inumber == ROOTINO) 385 inp->i_parent = ROOTINO; 386 else 387 inp->i_parent = (ino_t)0; 388 inp->i_dotdot = (ino_t)0; 389 inp->i_number = inumber; 390 inp->i_isize = dp->di_size; |
391 inp->i_numblks = blks * sizeof(ufs_daddr_t); 392 memmove(&inp->i_blks[0], &dp->di_db[0], (size_t)inp->i_numblks); |
393 if (inplast == listmax) { 394 listmax += 100; 395 inpsort = (struct inoinfo **)realloc((char *)inpsort, 396 (unsigned)listmax * sizeof(struct inoinfo *)); 397 if (inpsort == NULL) |
398 errx(EEXIT, "cannot increase directory list"); |
399 } 400 inpsort[inplast++] = inp; 401} 402 403/* 404 * Look up an inode cache structure. 405 */ 406struct inoinfo * 407getinoinfo(inumber) 408 ino_t inumber; 409{ 410 register struct inoinfo *inp; 411 412 for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) { 413 if (inp->i_number != inumber) 414 continue; 415 return (inp); 416 } |
417 errx(EEXIT, "cannot find inode %d", inumber); |
418 return ((struct inoinfo *)0); 419} 420 421/* 422 * Clean up all the inode cache structure. 423 */ 424void 425inocleanup() --- 43 unchanged lines hidden (view full) --- 469int 470findname(idesc) 471 struct inodesc *idesc; 472{ 473 register struct direct *dirp = idesc->id_dirp; 474 475 if (dirp->d_ino != idesc->id_parent) 476 return (KEEPON); |
477 memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1); |
478 return (STOP|FOUND); 479} 480 481int 482findino(idesc) 483 struct inodesc *idesc; 484{ 485 register struct direct *dirp = idesc->id_dirp; --- 25 unchanged lines hidden (view full) --- 511 if ((pw = getpwuid((int)dp->di_uid)) != 0) 512 printf("%s ", pw->pw_name); 513 else 514 printf("%u ", (unsigned)dp->di_uid); 515 printf("MODE=%o\n", dp->di_mode); 516 if (preen) 517 printf("%s: ", cdevname); 518 printf("SIZE=%qu ", dp->di_size); |
519 p = ctime(&dp->di_mtime); |
520 printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]); 521} 522 523void 524blkerror(ino, type, blk) 525 ino_t ino; 526 char *type; |
527 ufs_daddr_t blk; |
528{ 529 530 pfatal("%ld %s I=%lu", blk, type, ino); 531 printf("\n"); 532 switch (statemap[ino]) { 533 534 case FSTATE: 535 statemap[ino] = FCLEAR; 536 return; 537 538 case DSTATE: 539 statemap[ino] = DCLEAR; 540 return; 541 542 case FCLEAR: 543 case DCLEAR: 544 return; 545 546 default: |
547 errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]); |
548 /* NOTREACHED */ 549 } 550} 551 552/* 553 * allocate an unused inode 554 */ 555ino_t --- 26 unchanged lines hidden (view full) --- 582 } 583 dp = ginode(ino); 584 dp->di_db[0] = allocblk((long)1); 585 if (dp->di_db[0] == 0) { 586 statemap[ino] = USTATE; 587 return (0); 588 } 589 dp->di_mode = type; |
590 (void)time(&dp->di_atime); |
591 dp->di_mtime = dp->di_ctime = dp->di_atime; 592 dp->di_size = sblock.fs_fsize; 593 dp->di_blocks = btodb(sblock.fs_fsize); 594 n_files++; 595 inodirty(); 596 if (newinofmt) 597 typemap[ino] = IFTODT(type); 598 return (ino); --- 4 unchanged lines hidden (view full) --- 603 */ 604void 605freeino(ino) 606 ino_t ino; 607{ 608 struct inodesc idesc; 609 struct dinode *dp; 610 |
611 memset(&idesc, 0, sizeof(struct inodesc)); |
612 idesc.id_type = ADDR; 613 idesc.id_func = pass4check; 614 idesc.id_number = ino; 615 dp = ginode(ino); 616 (void)ckinode(dp, &idesc); 617 clearinode(dp); 618 inodirty(); 619 statemap[ino] = USTATE; 620 n_files--; 621} |