dir.c (92806) | dir.c (92839) |
---|---|
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[] = "@(#)dir.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[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95"; 37#endif 38static const char rcsid[] = |
39 "$FreeBSD: head/sbin/fsck_ffs/dir.c 92806 2002-03-20 17:55:10Z obrien $"; | 39 "$FreeBSD: head/sbin/fsck_ffs/dir.c 92839 2002-03-20 22:57:10Z imp $"; |
40#endif /* not lint */ 41 42#include <sys/param.h> 43#include <sys/time.h> 44#include <sys/sysctl.h> 45 46#include <ufs/ufs/dinode.h> 47#include <ufs/ufs/dir.h> --- 14 unchanged lines hidden (view full) --- 62 0, 12, DT_DIR, 1, ".", 63 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." 64}; 65struct odirtemplate odirhead = { 66 0, 12, 1, ".", 67 0, DIRBLKSIZ - 12, 2, ".." 68}; 69 | 40#endif /* not lint */ 41 42#include <sys/param.h> 43#include <sys/time.h> 44#include <sys/sysctl.h> 45 46#include <ufs/ufs/dinode.h> 47#include <ufs/ufs/dir.h> --- 14 unchanged lines hidden (view full) --- 62 0, 12, DT_DIR, 1, ".", 63 0, DIRBLKSIZ - 12, DT_DIR, 2, ".." 64}; 65struct odirtemplate odirhead = { 66 0, 12, 1, ".", 67 0, DIRBLKSIZ - 12, 2, ".." 68}; 69 |
70static int chgino __P((struct inodesc *)); 71static int dircheck __P((struct inodesc *, struct direct *)); 72static int expanddir __P((struct dinode *dp, char *name)); 73static void freedir __P((ino_t ino, ino_t parent)); 74static struct direct *fsck_readdir __P((struct inodesc *)); 75static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size)); 76static int lftempname __P((char *bufp, ino_t ino)); 77static int mkentry __P((struct inodesc *)); | 70static int chgino(struct inodesc *); 71static int dircheck(struct inodesc *, struct direct *); 72static int expanddir(struct dinode *dp, char *name); 73static void freedir(ino_t ino, ino_t parent); 74static struct direct *fsck_readdir(struct inodesc *); 75static struct bufarea *getdirblk(ufs_daddr_t blkno, long size); 76static int lftempname(char *bufp, ino_t ino); 77static int mkentry(struct inodesc *); |
78 79/* 80 * Propagate connected state through the tree. 81 */ 82void | 78 79/* 80 * Propagate connected state through the tree. 81 */ 82void |
83propagate() | 83propagate(void) |
84{ 85 struct inoinfo **inpp, *inp; 86 struct inoinfo **inpend; 87 long change; 88 89 inpend = &inpsort[inplast]; 90 do { 91 change = 0; --- 9 unchanged lines hidden (view full) --- 101 } 102 } while (change > 0); 103} 104 105/* 106 * Scan each entry in a directory block. 107 */ 108int | 84{ 85 struct inoinfo **inpp, *inp; 86 struct inoinfo **inpend; 87 long change; 88 89 inpend = &inpsort[inplast]; 90 do { 91 change = 0; --- 9 unchanged lines hidden (view full) --- 101 } 102 } while (change > 0); 103} 104 105/* 106 * Scan each entry in a directory block. 107 */ 108int |
109dirscan(idesc) 110 struct inodesc *idesc; | 109dirscan(struct inodesc *idesc) |
111{ 112 struct direct *dp; 113 struct bufarea *bp; 114 u_int dsize, n; 115 long blksiz; 116 char dbuf[DIRBLKSIZ]; 117 118 if (idesc->id_type != DATA) --- 46 unchanged lines hidden (view full) --- 165 } 166 return (idesc->id_filesize > 0 ? KEEPON : STOP); 167} 168 169/* 170 * get next entry in a directory. 171 */ 172static struct direct * | 110{ 111 struct direct *dp; 112 struct bufarea *bp; 113 u_int dsize, n; 114 long blksiz; 115 char dbuf[DIRBLKSIZ]; 116 117 if (idesc->id_type != DATA) --- 46 unchanged lines hidden (view full) --- 164 } 165 return (idesc->id_filesize > 0 ? KEEPON : STOP); 166} 167 168/* 169 * get next entry in a directory. 170 */ 171static struct direct * |
173fsck_readdir(idesc) 174 struct inodesc *idesc; | 172fsck_readdir(struct inodesc *idesc) |
175{ 176 struct direct *dp, *ndp; 177 struct bufarea *bp; 178 long size, blksiz, fix, dploc; 179 180 blksiz = idesc->id_numfrags * sblock.fs_fsize; 181 bp = getdirblk(idesc->id_blkno, blksiz); 182 if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 && --- 44 unchanged lines hidden (view full) --- 227 return (dp); 228} 229 230/* 231 * Verify that a directory entry is valid. 232 * This is a superset of the checks made in the kernel. 233 */ 234static int | 173{ 174 struct direct *dp, *ndp; 175 struct bufarea *bp; 176 long size, blksiz, fix, dploc; 177 178 blksiz = idesc->id_numfrags * sblock.fs_fsize; 179 bp = getdirblk(idesc->id_blkno, blksiz); 180 if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 && --- 44 unchanged lines hidden (view full) --- 225 return (dp); 226} 227 228/* 229 * Verify that a directory entry is valid. 230 * This is a superset of the checks made in the kernel. 231 */ 232static int |
235dircheck(idesc, dp) 236 struct inodesc *idesc; 237 struct direct *dp; | 233dircheck(struct inodesc *idesc, struct direct *dp) |
238{ 239 int size; 240 char *cp; 241 u_char namlen, type; 242 int spaceleft; 243 244 spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 245 if (dp->d_reclen == 0 || --- 30 unchanged lines hidden (view full) --- 276 if (debug) 277 printf("Bad dir: ino %d reclen %d namlen %d type %d name %s\n", 278 dp->d_ino, dp->d_reclen, dp->d_namlen, dp->d_type, 279 dp->d_name); 280 return (0); 281} 282 283void | 234{ 235 int size; 236 char *cp; 237 u_char namlen, type; 238 int spaceleft; 239 240 spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ); 241 if (dp->d_reclen == 0 || --- 30 unchanged lines hidden (view full) --- 272 if (debug) 273 printf("Bad dir: ino %d reclen %d namlen %d type %d name %s\n", 274 dp->d_ino, dp->d_reclen, dp->d_namlen, dp->d_type, 275 dp->d_name); 276 return (0); 277} 278 279void |
284direrror(ino, errmesg) 285 ino_t ino; 286 char *errmesg; | 280direrror(ino_t ino, char *errmesg) |
287{ 288 289 fileerror(ino, ino, errmesg); 290} 291 292void | 281{ 282 283 fileerror(ino, ino, errmesg); 284} 285 286void |
293fileerror(cwd, ino, errmesg) 294 ino_t cwd, ino; 295 char *errmesg; | 287fileerror(ino_t cwd, ino_t ino, char *errmesg) |
296{ 297 struct dinode *dp; 298 char pathbuf[MAXPATHLEN + 1]; 299 300 pwarn("%s ", errmesg); 301 pinode(ino); 302 printf("\n"); 303 getpathname(pathbuf, cwd, ino); --- 5 unchanged lines hidden (view full) --- 309 if (ftypeok(dp)) 310 pfatal("%s=%s\n", 311 (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); 312 else 313 pfatal("NAME=%s\n", pathbuf); 314} 315 316void | 288{ 289 struct dinode *dp; 290 char pathbuf[MAXPATHLEN + 1]; 291 292 pwarn("%s ", errmesg); 293 pinode(ino); 294 printf("\n"); 295 getpathname(pathbuf, cwd, ino); --- 5 unchanged lines hidden (view full) --- 301 if (ftypeok(dp)) 302 pfatal("%s=%s\n", 303 (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf); 304 else 305 pfatal("NAME=%s\n", pathbuf); 306} 307 308void |
317adjust(idesc, lcnt) 318 struct inodesc *idesc; 319 int lcnt; | 309adjust(struct inodesc *idesc, int lcnt) |
320{ 321 struct dinode *dp; 322 int saveresolved; 323 324 dp = ginode(idesc->id_number); 325 if (dp->di_nlink == lcnt) { 326 /* 327 * If we have not hit any unresolved problems, are running --- 51 unchanged lines hidden (view full) --- 379 &cmd, sizeof cmd) == -1) 380 rwerror("ADJUST INODE", cmd.value); 381 } 382 } 383 } 384} 385 386static int | 310{ 311 struct dinode *dp; 312 int saveresolved; 313 314 dp = ginode(idesc->id_number); 315 if (dp->di_nlink == lcnt) { 316 /* 317 * If we have not hit any unresolved problems, are running --- 51 unchanged lines hidden (view full) --- 369 &cmd, sizeof cmd) == -1) 370 rwerror("ADJUST INODE", cmd.value); 371 } 372 } 373 } 374} 375 376static int |
387mkentry(idesc) 388 struct inodesc *idesc; | 377mkentry(struct inodesc *idesc) |
389{ 390 struct direct *dirp = idesc->id_dirp; 391 struct direct newent; 392 int newlen, oldlen; 393 394 newent.d_namlen = strlen(idesc->id_name); 395 newlen = DIRSIZ(0, &newent); 396 if (dirp->d_ino != 0) --- 27 unchanged lines hidden (view full) --- 424 dirp->d_namlen = dirp->d_type; 425 dirp->d_type = tmp; 426 } 427# endif 428 return (ALTERED|STOP); 429} 430 431static int | 378{ 379 struct direct *dirp = idesc->id_dirp; 380 struct direct newent; 381 int newlen, oldlen; 382 383 newent.d_namlen = strlen(idesc->id_name); 384 newlen = DIRSIZ(0, &newent); 385 if (dirp->d_ino != 0) --- 27 unchanged lines hidden (view full) --- 413 dirp->d_namlen = dirp->d_type; 414 dirp->d_type = tmp; 415 } 416# endif 417 return (ALTERED|STOP); 418} 419 420static int |
432chgino(idesc) 433 struct inodesc *idesc; | 421chgino(struct inodesc *idesc) |
434{ 435 struct direct *dirp = idesc->id_dirp; 436 437 if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1)) 438 return (KEEPON); 439 dirp->d_ino = idesc->id_parent; 440 if (newinofmt) 441 dirp->d_type = inoinfo(idesc->id_parent)->ino_type; 442 else 443 dirp->d_type = 0; 444 return (ALTERED|STOP); 445} 446 447int | 422{ 423 struct direct *dirp = idesc->id_dirp; 424 425 if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1)) 426 return (KEEPON); 427 dirp->d_ino = idesc->id_parent; 428 if (newinofmt) 429 dirp->d_type = inoinfo(idesc->id_parent)->ino_type; 430 else 431 dirp->d_type = 0; 432 return (ALTERED|STOP); 433} 434 435int |
448linkup(orphan, parentdir, name) 449 ino_t orphan; 450 ino_t parentdir; 451 char *name; | 436linkup(ino_t orphan, ino_t parentdir, char *name) |
452{ 453 struct dinode *dp; 454 int lostdir; 455 ino_t oldlfdir; 456 struct inodesc idesc; 457 char tempname[BUFSIZ]; 458 459 memset(&idesc, 0, sizeof(struct inodesc)); --- 102 unchanged lines hidden (view full) --- 562 } 563 return (1); 564} 565 566/* 567 * fix an entry in a directory. 568 */ 569int | 437{ 438 struct dinode *dp; 439 int lostdir; 440 ino_t oldlfdir; 441 struct inodesc idesc; 442 char tempname[BUFSIZ]; 443 444 memset(&idesc, 0, sizeof(struct inodesc)); --- 102 unchanged lines hidden (view full) --- 547 } 548 return (1); 549} 550 551/* 552 * fix an entry in a directory. 553 */ 554int |
570changeino(dir, name, newnum) 571 ino_t dir; 572 char *name; 573 ino_t newnum; | 555changeino(ino_t dir, char *name, ino_t newnum) |
574{ 575 struct inodesc idesc; 576 577 memset(&idesc, 0, sizeof(struct inodesc)); 578 idesc.id_type = DATA; 579 idesc.id_func = chgino; 580 idesc.id_number = dir; 581 idesc.id_fix = DONTKNOW; 582 idesc.id_name = name; 583 idesc.id_parent = newnum; /* new value for name */ 584 return (ckinode(ginode(dir), &idesc)); 585} 586 587/* 588 * make an entry in a directory 589 */ 590int | 556{ 557 struct inodesc idesc; 558 559 memset(&idesc, 0, sizeof(struct inodesc)); 560 idesc.id_type = DATA; 561 idesc.id_func = chgino; 562 idesc.id_number = dir; 563 idesc.id_fix = DONTKNOW; 564 idesc.id_name = name; 565 idesc.id_parent = newnum; /* new value for name */ 566 return (ckinode(ginode(dir), &idesc)); 567} 568 569/* 570 * make an entry in a directory 571 */ 572int |
591makeentry(parent, ino, name) 592 ino_t parent, ino; 593 char *name; | 573makeentry(ino_t parent, ino_t ino, char *name) |
594{ 595 struct dinode *dp; 596 struct inodesc idesc; 597 char pathbuf[MAXPATHLEN + 1]; 598 599 if (parent < ROOTINO || parent >= maxino || 600 ino < ROOTINO || ino >= maxino) 601 return (0); --- 17 unchanged lines hidden (view full) --- 619 return (0); 620 return (ckinode(dp, &idesc) & ALTERED); 621} 622 623/* 624 * Attempt to expand the size of a directory 625 */ 626static int | 574{ 575 struct dinode *dp; 576 struct inodesc idesc; 577 char pathbuf[MAXPATHLEN + 1]; 578 579 if (parent < ROOTINO || parent >= maxino || 580 ino < ROOTINO || ino >= maxino) 581 return (0); --- 17 unchanged lines hidden (view full) --- 599 return (0); 600 return (ckinode(dp, &idesc) & ALTERED); 601} 602 603/* 604 * Attempt to expand the size of a directory 605 */ 606static int |
627expanddir(dp, name) 628 struct dinode *dp; 629 char *name; | 607expanddir(struct dinode *dp, char *name) |
630{ 631 ufs_daddr_t lastbn, newblk; 632 struct bufarea *bp; 633 char *cp, firstblk[DIRBLKSIZ]; 634 635 lastbn = lblkno(&sblock, dp->di_size); 636 if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) 637 return (0); --- 38 unchanged lines hidden (view full) --- 676 freeblk(newblk, sblock.fs_frag); 677 return (0); 678} 679 680/* 681 * allocate a new directory 682 */ 683ino_t | 608{ 609 ufs_daddr_t lastbn, newblk; 610 struct bufarea *bp; 611 char *cp, firstblk[DIRBLKSIZ]; 612 613 lastbn = lblkno(&sblock, dp->di_size); 614 if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) 615 return (0); --- 38 unchanged lines hidden (view full) --- 654 freeblk(newblk, sblock.fs_frag); 655 return (0); 656} 657 658/* 659 * allocate a new directory 660 */ 661ino_t |
684allocdir(parent, request, mode) 685 ino_t parent, request; 686 int mode; | 662allocdir(ino_t parent, ino_t request, int mode) |
687{ 688 ino_t ino; 689 char *cp; 690 struct dinode *dp; 691 struct bufarea *bp; 692 struct inoinfo *inp; 693 struct dirtemplate *dirp; 694 --- 42 unchanged lines hidden (view full) --- 737 inodirty(); 738 return (ino); 739} 740 741/* 742 * free a directory inode 743 */ 744static void | 663{ 664 ino_t ino; 665 char *cp; 666 struct dinode *dp; 667 struct bufarea *bp; 668 struct inoinfo *inp; 669 struct dirtemplate *dirp; 670 --- 42 unchanged lines hidden (view full) --- 713 inodirty(); 714 return (ino); 715} 716 717/* 718 * free a directory inode 719 */ 720static void |
745freedir(ino, parent) 746 ino_t ino, parent; | 721freedir(ino_t ino, ino_t parent) |
747{ 748 struct dinode *dp; 749 750 if (ino != parent) { 751 dp = ginode(parent); 752 dp->di_nlink--; 753 inodirty(); 754 } 755 freeino(ino); 756} 757 758/* 759 * generate a temporary name for the lost+found directory. 760 */ 761static int | 722{ 723 struct dinode *dp; 724 725 if (ino != parent) { 726 dp = ginode(parent); 727 dp->di_nlink--; 728 inodirty(); 729 } 730 freeino(ino); 731} 732 733/* 734 * generate a temporary name for the lost+found directory. 735 */ 736static int |
762lftempname(bufp, ino) 763 char *bufp; 764 ino_t ino; | 737lftempname(char *bufp, ino_t ino) |
765{ 766 ino_t in; 767 char *cp; 768 int namlen; 769 770 cp = bufp + 2; 771 for (in = maxino; in > 0; in /= 10) 772 cp++; --- 8 unchanged lines hidden (view full) --- 781 return (namlen); 782} 783 784/* 785 * Get a directory block. 786 * Insure that it is held until another is requested. 787 */ 788static struct bufarea * | 738{ 739 ino_t in; 740 char *cp; 741 int namlen; 742 743 cp = bufp + 2; 744 for (in = maxino; in > 0; in /= 10) 745 cp++; --- 8 unchanged lines hidden (view full) --- 754 return (namlen); 755} 756 757/* 758 * Get a directory block. 759 * Insure that it is held until another is requested. 760 */ 761static struct bufarea * |
789getdirblk(blkno, size) 790 ufs_daddr_t blkno; 791 long size; | 762getdirblk(ufs_daddr_t blkno, long size) |
792{ 793 794 if (pdirbp != 0) 795 pdirbp->b_flags &= ~B_INUSE; 796 pdirbp = getdatablk(blkno, size); 797 return (pdirbp); 798} | 763{ 764 765 if (pdirbp != 0) 766 pdirbp->b_flags &= ~B_INUSE; 767 pdirbp = getdatablk(blkno, size); 768 return (pdirbp); 769} |