[BACK]Return to pass1.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / fsck_lfs

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sbin/fsck_lfs/pass1.c between version 1.5 and 1.6

version 1.5, 2000/05/16 04:55:59 version 1.6, 2000/05/23 01:48:54
Line 1 
Line 1 
 /*      $NetBSD$        */  /* $NetBSD$      */
   
 /*  /*
  * Copyright (c) 1980, 1986, 1993   * Copyright (c) 1980, 1986, 1993
Line 50 
Line 50 
 #include "extern.h"  #include "extern.h"
 #include "fsutil.h"  #include "fsutil.h"
   
 SEGUSE *seg_table;  SEGUSE         *seg_table;
 extern daddr_t *din_table;  extern daddr_t *din_table;
   
 static daddr_t badblk;  static daddr_t  badblk;
 static daddr_t dupblk;  static daddr_t  dupblk;
 static void checkinode __P((ino_t, struct inodesc *));  static void     checkinode(ino_t, struct inodesc *);
 static int i_d_cmp(const void *, const void *);  static int      i_d_cmp(const void *, const void *);
   
 static void bmapcheck(void)  static void
   bmapcheck(void)
 {  {
         int i;          int             i;
   
         if(testbmap(0))          if (testbmap(0))
                 raise(1);                  raise(1);
         for(i=0;i<maxfsblock;i++)          for (i = 0; i < maxfsblock; i++)
                 if(testbmap(i) > maxino)                  if (testbmap(i) > maxino)
                         raise(1);                          raise(1);
 }  }
   
 struct ino_daddr {  struct ino_daddr {
         ino_t ino;          ino_t           ino;
         daddr_t daddr;          daddr_t         daddr;
 };  };
   
 static int  static int
Line 94  i_d_cmp(const void *va, const void *vb)
Line 95  i_d_cmp(const void *va, const void *vb)
 void  void
 pass1()  pass1()
 {  {
         ino_t inumber;          ino_t           inumber;
         int i, total_segments;          int             i, total_segments;
         struct inodesc idesc;          struct inodesc  idesc;
         struct dinode *idinode, *tinode;          struct dinode  *idinode, *tinode;
         struct ifile *ifp;          struct ifile   *ifp;
         CLEANERINFO *cp;          CLEANERINFO    *cp;
         struct bufarea *bp;          struct bufarea *bp;
         struct ino_daddr **dins;          struct ino_daddr **dins;
   
         idinode = lfs_difind(&sblock,sblock.lfs_ifile,&ifblock);          idinode = lfs_difind(&sblock, sblock.lfs_ifile, &ifblock);
   
         /*          /*
          * We now have the ifile's inode block in core.  Read out the           * We now have the ifile's inode block in core.  Read out the
          * number of segments.           * number of segments.
          */           */
 #if 1  #if 1
         if(pbp != 0)          if (pbp != 0)
             pbp->b_flags &= ~B_INUSE;                  pbp->b_flags &= ~B_INUSE;
         pbp = getddblk(idinode->di_db[0], sblock.lfs_bsize);          pbp = getddblk(idinode->di_db[0], sblock.lfs_bsize);
   
         cp = (CLEANERINFO *)(pbp->b_un.b_buf);          cp = (CLEANERINFO *)(pbp->b_un.b_buf);
 #endif  #endif
         total_segments = sblock.lfs_size / sblock.lfs_bsize;          total_segments = sblock.lfs_size / sblock.lfs_bsize;
   
         /*          /*
          * Find all allocated blocks, initialize numdirs.           * Find all allocated blocks, initialize numdirs.
Line 131  pass1()
Line 132  pass1()
         if (debug)          if (debug)
                 printf("creating inode address table...\n");                  printf("creating inode address table...\n");
         /* Sort by daddr */          /* Sort by daddr */
         dins = (struct ino_daddr **)malloc((maxino+1) * sizeof(*dins));          dins = (struct ino_daddr **)malloc((maxino + 1) * sizeof(*dins));
         for(i=0;i<=maxino;i++) {          for (i = 0; i <= maxino; i++) {
                 dins[i] = malloc(sizeof(**dins));                  dins[i] = malloc(sizeof(**dins));
                 dins[i]->ino = i;                  dins[i]->ino = i;
                 dins[i]->daddr = lfs_ino_daddr(i);                  dins[i]->daddr = lfs_ino_daddr(i);
         }          }
         qsort(dins, maxino+1, sizeof(*dins), i_d_cmp);          qsort(dins, maxino + 1, sizeof(*dins), i_d_cmp);
   
         /* find a value for numdirs, fill in din_table */          /* find a value for numdirs, fill in din_table */
         if (debug)          if (debug)
                 printf("counting dirs...\n");                  printf("counting dirs...\n");
         numdirs=0;          numdirs = 0;
         for(i=0; i <= maxino; i++) {          for (i = 0; i <= maxino; i++) {
                 inumber = dins[i]->ino;                  inumber = dins[i]->ino;
                 if(inumber == 0 || dins[i]->daddr == 0)                  if (inumber == 0 || dins[i]->daddr == 0)
                         continue;                          continue;
                 tinode = lfs_ginode(inumber);                  tinode = lfs_ginode(inumber);
                 if(tinode && (tinode->di_mode & IFMT)==IFDIR)                  if (tinode && (tinode->di_mode & IFMT) == IFDIR)
                         numdirs++;                          numdirs++;
         }          }
   
         /* from setup.c */          /* from setup.c */
         inplast = 0;          inplast = 0;
         listmax = numdirs + 10;          listmax = numdirs + 10;
         inpsort = (struct inoinfo **)calloc((unsigned)listmax,          inpsort = (struct inoinfo **)calloc((unsigned) listmax,
             sizeof(struct inoinfo *));                                               sizeof(struct inoinfo *));
         inphead = (struct inoinfo **)calloc((unsigned)numdirs,          inphead = (struct inoinfo **)calloc((unsigned) numdirs,
             sizeof(struct inoinfo *));                                               sizeof(struct inoinfo *));
         if (inpsort == NULL || inphead == NULL) {          if (inpsort == NULL || inphead == NULL) {
                 printf("cannot alloc %lu bytes for inphead\n",                  printf("cannot alloc %lu bytes for inphead\n",
                     (unsigned long)numdirs * sizeof(struct inoinfo *));                         (unsigned long)numdirs * sizeof(struct inoinfo *));
                 exit(1);                  exit(1);
         }          }
   
         /* resetinodebuf(); */          /* resetinodebuf(); */
         if (debug)          if (debug)
                 printf("counting blocks...\n");                  printf("counting blocks...\n");
         for(i=0; i <= maxino; i++) {          for (i = 0; i <= maxino; i++) {
                 inumber = dins[i]->ino;                  inumber = dins[i]->ino;
                 if(inumber == 0 || dins[i]->daddr == 0)                  if (inumber == 0 || dins[i]->daddr == 0)
                         continue;                          continue;
                 ifp = lfs_ientry(inumber,&bp);                  ifp = lfs_ientry(inumber, &bp);
                 if(ifp && ifp->if_daddr != LFS_UNUSED_DADDR) {                  if (ifp && ifp->if_daddr != LFS_UNUSED_DADDR) {
                         bp->b_flags &= ~B_INUSE;                          bp->b_flags &= ~B_INUSE;
                         checkinode(inumber, &idesc);                          checkinode(inumber, &idesc);
                 } else {                  } else {
Line 181  pass1()
Line 181  pass1()
                         statemap[inumber] = USTATE;                          statemap[inumber] = USTATE;
                 }                  }
                 free(dins[i]);                  free(dins[i]);
         }          }
         free(dins);          free(dins);
   
         bmapcheck();          bmapcheck();
Line 189  pass1()
Line 189  pass1()
 }  }
   
 static void  static void
 checkinode(inumber, idesc)  checkinode(ino_t inumber, struct inodesc * idesc)
         ino_t inumber;  
         register struct inodesc *idesc;  
 {  {
         register struct dinode *dp;          register struct dinode *dp;
         struct zlncnt *zlnp;          struct zlncnt  *zlnp;
         int ndb, j;          int             ndb, j;
         mode_t mode;          mode_t          mode;
         char *symbuf;          char           *symbuf;
   
         /* dp = getnextinode(inumber); */          /* dp = getnextinode(inumber); */
         dp = lfs_ginode(inumber);          dp = lfs_ginode(inumber);
   
         if(dp==NULL) {  
             /* pwarn("Could not find inode %ld\n",(long)inumber); */  
             statemap[inumber]=USTATE;  
             return;  
         }  
   
           if (dp == NULL) {
                   /* pwarn("Could not find inode %ld\n",(long)inumber); */
                   statemap[inumber] = USTATE;
                   return;
           }
         mode = dp->di_mode & IFMT;          mode = dp->di_mode & IFMT;
   
         /* XXX - LFS doesn't have this particular problem (?) */          /* XXX - LFS doesn't have this particular problem (?) */
         if (mode == 0) {          if (mode == 0) {
                 if (memcmp(dp->di_db, zino.di_db, NDADDR * sizeof(daddr_t)) ||                  if (memcmp(dp->di_db, zino.di_db, NDADDR * sizeof(daddr_t)) ||
                     memcmp(dp->di_ib, zino.di_ib, NIADDR * sizeof(daddr_t)) ||                    memcmp(dp->di_ib, zino.di_ib, NIADDR * sizeof(daddr_t)) ||
                     dp->di_mode || dp->di_size) {                      dp->di_mode || dp->di_size) {
                         pwarn("mode=o%o, ifmt=o%o\n", dp->di_mode, mode);                          pwarn("mode=o%o, ifmt=o%o\n", dp->di_mode, mode);
                         pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber);                          pfatal("PARTIALLY ALLOCATED INODE I=%u", inumber);
Line 227  checkinode(inumber, idesc)
Line 224  checkinode(inumber, idesc)
                 return;                  return;
         }          }
         lastino = inumber;          lastino = inumber;
         if (/* dp->di_size < 0 || */          if (                    /* dp->di_size < 0 || */
             dp->di_size + sblock.lfs_bsize - 1 < dp->di_size) {              dp->di_size + sblock.lfs_bsize - 1 < dp->di_size) {
                 if (debug)                  if (debug)
                         printf("bad size %qu:", (unsigned long long)dp->di_size);                          printf("bad size %qu:", (unsigned long long)dp->di_size);
Line 236  checkinode(inumber, idesc)
Line 233  checkinode(inumber, idesc)
         if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {          if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
                 dp = ginode(inumber);                  dp = ginode(inumber);
                 dp->di_size = sblock.lfs_fsize;                  dp->di_size = sblock.lfs_fsize;
                 dp->di_mode = IFREG|0600;                  dp->di_mode = IFREG | 0600;
                 inodirty();                  inodirty();
         }          }
         ndb = howmany(dp->di_size, sblock.lfs_bsize);          ndb = howmany(dp->di_size, sblock.lfs_bsize);
         if (ndb < 0) {          if (ndb < 0) {
                 if (debug)                  if (debug)
                         printf("bad size %qu ndb %d:",                          printf("bad size %qu ndb %d:",
                                 (unsigned long long)dp->di_size, ndb);                                 (unsigned long long)dp->di_size, ndb);
                 goto unknown;                  goto unknown;
         }          }
         if (mode == IFBLK || mode == IFCHR)          if (mode == IFBLK || mode == IFCHR)
Line 252  checkinode(inumber, idesc)
Line 249  checkinode(inumber, idesc)
                 /*                  /*
                  * Note that the old fastlink format always had di_blocks set                   * Note that the old fastlink format always had di_blocks set
                  * to 0.  Other than that we no longer use the `spare' field                   * to 0.  Other than that we no longer use the `spare' field
                  * (which is now the extended uid) for sanity checking, the                   * (which is now the extended uid)for sanity checking, the
                  * new format is the same as the old.  We simply ignore the                   * new format is the same as the old.  We simply ignore the
                  * conversion altogether.  - mycroft, 19MAY1994                   * conversion altogether.  - mycroft, 19MAY1994
                  */                   */
Line 261  checkinode(inumber, idesc)
Line 258  checkinode(inumber, idesc)
                     dp->di_blocks != 0) {                      dp->di_blocks != 0) {
                         symbuf = alloca(secsize);                          symbuf = alloca(secsize);
                         if (bread(fsreadfd, symbuf,                          if (bread(fsreadfd, symbuf,
                             fsbtodb(&sblock, dp->di_db[0]),                                    fsbtodb(&sblock, dp->di_db[0]),
                             (long)secsize) != 0)                                    (long)secsize) != 0)
                                 errexit("cannot read symlink");                                  errexit("cannot read symlink");
                         if (debug) {                          if (debug) {
                                 symbuf[dp->di_size] = 0;                                  symbuf[dp->di_size] = 0;
                                 printf("convert symlink %d(%s) of size %qd\n",                                  printf("convert symlink %d(%s)of size %qd\n",
                                         inumber, symbuf, (long long)dp->di_size);                                    inumber, symbuf, (long long)dp->di_size);
                         }                          }
                         dp = ginode(inumber);                          dp = ginode(inumber);
                         memcpy(dp->di_shortlink, symbuf, (long)dp->di_size);                          memcpy(dp->di_shortlink, symbuf, (long)dp->di_size);
Line 301  checkinode(inumber, idesc)
Line 298  checkinode(inumber, idesc)
                 if (dp->di_ib[j] != 0) {                  if (dp->di_ib[j] != 0) {
                         if (debug)                          if (debug)
                                 printf("bad indirect addr: %d\n",                                  printf("bad indirect addr: %d\n",
                                         dp->di_ib[j]);                                         dp->di_ib[j]);
                         /* goto unknown; */                          /* goto unknown; */
                 }                  }
         if (ftypeok(dp) == 0)          if (ftypeok(dp) == 0)
Line 329  checkinode(inumber, idesc)
Line 326  checkinode(inumber, idesc)
         } else          } else
                 statemap[inumber] = FSTATE;                  statemap[inumber] = FSTATE;
         typemap[inumber] = IFTODT(mode);          typemap[inumber] = IFTODT(mode);
 #if 0 /* FFS */  #if 0                           /* FFS */
         if (doinglevel2 &&          if (doinglevel2 &&
             (dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {              (dp->di_ouid != (u_short) - 1 || dp->di_ogid != (u_short) - 1)) {
                 dp = ginode(inumber);                  dp = ginode(inumber);
                 dp->di_uid = dp->di_ouid;                  dp->di_uid = dp->di_ouid;
                 dp->di_ouid = -1;                  dp->di_ouid = -1;
Line 346  checkinode(inumber, idesc)
Line 343  checkinode(inumber, idesc)
         idesc->id_entryno *= btodb(sblock.lfs_fsize);          idesc->id_entryno *= btodb(sblock.lfs_fsize);
         if (dp->di_blocks != idesc->id_entryno) {          if (dp->di_blocks != idesc->id_entryno) {
                 pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)",                  pwarn("INCORRECT BLOCK COUNT I=%u (%d should be %d)",
                     inumber, dp->di_blocks, idesc->id_entryno);                        inumber, dp->di_blocks, idesc->id_entryno);
                 if (preen)                  if (preen)
                         printf(" (CORRECTED)\n");                          printf(" (CORRECTED)\n");
                 else if (reply("CORRECT") == 0)                  else if (reply("CORRECT") == 0)
Line 368  unknown:
Line 365  unknown:
 }  }
   
 int  int
 pass1check(idesc)  pass1check(struct inodesc * idesc)
         register struct inodesc *idesc;  
 {  {
         int res = KEEPON;          int             res = KEEPON;
         int anyout, nfrags;          int             anyout, nfrags;
         daddr_t blkno = idesc->id_blkno;          daddr_t         blkno = idesc->id_blkno;
         register struct dups *dlp;          register struct dups *dlp;
         struct dups *new;          struct dups    *new;
   
         if (!testbmap(blkno)) {          if (!testbmap(blkno)) {
                 seg_table[datosn(&sblock,blkno)].su_nbytes += idesc->id_numfrags * sblock.lfs_fsize;                  seg_table[datosn(&sblock, blkno)].su_nbytes += idesc->id_numfrags * sblock.lfs_fsize;
         }          }
   
         if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {          if ((anyout = chkrange(blkno, idesc->id_numfrags)) != 0) {
                 blkerror(idesc->id_number, "BAD", blkno);                  blkerror(idesc->id_number, "BAD", blkno);
                 if (badblk++ >= MAXBAD) {                  if (badblk++ >= MAXBAD) {
                         pwarn("EXCESSIVE BAD BLKS I=%u",                          pwarn("EXCESSIVE BAD BLKS I=%u",
                                 idesc->id_number);                                idesc->id_number);
                         if (preen)                          if (preen)
                                 printf(" (SKIPPING)\n");                                  printf(" (SKIPPING)\n");
                         else if (reply("CONTINUE") == 0)                          else if (reply("CONTINUE") == 0)
Line 401  pass1check(idesc)
Line 396  pass1check(idesc)
 #ifndef VERBOSE_BLOCKMAP  #ifndef VERBOSE_BLOCKMAP
                         setbmap(blkno);                          setbmap(blkno);
 #else  #else
                         setbmap(blkno,idesc->id_number);                          setbmap(blkno, idesc->id_number);
 #endif  #endif
                 } else {                  } else {
                         blkerror(idesc->id_number, "DUP", blkno);                          blkerror(idesc->id_number, "DUP", blkno);
 #ifdef VERBOSE_BLOCKMAP  #ifdef VERBOSE_BLOCKMAP
                         pwarn("(lbn %d: Holder is %d)\n", idesc->id_lblkno,                          pwarn("(lbn %d: Holder is %d)\n", idesc->id_lblkno,
                               testbmap(blkno));                                testbmap(blkno));
 #endif  #endif
                         if (dupblk++ >= MAXDUP) {                          if (dupblk++ >= MAXDUP) {
                                 pwarn("EXCESSIVE DUP BLKS I=%u",                                  pwarn("EXCESSIVE DUP BLKS I=%u",
                                         idesc->id_number);                                        idesc->id_number);
                                 if (preen)                                  if (preen)
                                         printf(" (SKIPPING)\n");                                          printf(" (SKIPPING)\n");
                                 else if (reply("CONTINUE") == 0)                                  else if (reply("CONTINUE") == 0)
Line 442  pass1check(idesc)
Line 437  pass1check(idesc)
                 /*                  /*
                  * count the number of blocks found in id_entryno                   * count the number of blocks found in id_entryno
                  */                   */
                 idesc->id_entryno ++;                  idesc->id_entryno++;
         }          }
         return (res);          return (res);
 }  }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

CVSweb <webmaster@jp.NetBSD.org>