# 2.11BSD#431 - /usr/src/sbin/fsck/pass2.c

##### Functions

    pass2             X
    pass2check        X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char sccsid[] = "@(#)pass2.c	5.2 (Berkeley) 3/5/86";
       9: #endif not lint
      10:
      11: #include <sys/param.h>
      12: #include <sys/inode.h>
      13: #include <sys/fs.h>
      14: #include <sys/dir.h>
      15: #include <strings.h>
      16: #include "fsck.h"
      17:
      18: int pass2check();
      19:
      20: pass2()
      21: {
      22:     register DINODE *dp;
      23:     struct inodesc rootdesc;
      24:
      25:     bzero((char *)&rootdesc, sizeof(struct inodesc));
      26:     rootdesc.id_type = ADDR;
      27:     rootdesc.id_func = pass2check;
      28:     rootdesc.id_number = ROOTINO;
      29:     pathp = pathname;
      30:     switch (getstate(ROOTINO)) {
      31:
      32:     case USTATE:
      33:         pfatal("ROOT INODE UNALLOCATED");
      34:         if (reply("ALLOCATE") == 0)
      35:             errexit("");
      36:         if (allocdir(ROOTINO, ROOTINO) != ROOTINO)
      37:             errexit("CANNOT ALLOCATE ROOT INODE\n");
      38:         descend(&rootdesc, ROOTINO);
      39:         break;
      40:
      41:     case DCLEAR:
      42:         pfatal("DUPS/BAD IN ROOT INODE");
      43:         if (reply("REALLOCATE")) {
      44:             freeino(ROOTINO);
      45:             if (allocdir(ROOTINO, ROOTINO) != ROOTINO)
      46:                 errexit("CANNOT ALLOCATE ROOT INODE\n");
      47:             descend(&rootdesc, ROOTINO);
      48:             break;
      49:         }
      50:         if (reply("CONTINUE") == 0)
      51:             errexit("");
      52:         setstate(ROOTINO, DSTATE);
      53:         descend(&rootdesc, ROOTINO);
      54:         break;
      55:
      56:     case FSTATE:
      57:     case FCLEAR:
      58:         pfatal("ROOT INODE NOT DIRECTORY");
      59:         if (reply("REALLOCATE")) {
      60:             freeino(ROOTINO);
      61:             if (allocdir(ROOTINO, ROOTINO) != ROOTINO)
      62:                 errexit("CANNOT ALLOCATE ROOT INODE\n");
      63:             descend(&rootdesc, ROOTINO);
      64:             break;
      65:         }
      66:         if (reply("FIX") == 0)
      67:             errexit("");
      68:         dp = ginode(ROOTINO);
      69:         dp->di_mode &= ~IFMT;
      70:         dp->di_mode |= IFDIR;
      71:         inodirty();
      72:         setstate(ROOTINO, DSTATE);
      73:         /* fall into ... */
      74:
      75:     case DSTATE:
      76:         descend(&rootdesc, ROOTINO);
      77:         break;
      78:
      79:     default:
      80:         errexit("BAD STATE %d FOR ROOT INODE", getstate(ROOTINO));
      81:     }
      82: }
      83:
      84: pass2check(idesc)
      85:     struct inodesc *idesc;
      86: {
      87:     register DIRECT *dirp = idesc->id_dirp;
      88:     char *curpathloc;
      89:     int n, entrysize, ret = 0;
      90:     DINODE *dp;
      91:     static DIRECT proto;
      92:     static char namebuf[MAXPATHLEN];
      93:
      94:     /*
      95: 	 * check for "."
      96: 	 */
      97:     if (idesc->id_entryno != 0)
      98:         goto chk1;
      99:     if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) {
     100:         if (dirp->d_ino != idesc->id_number) {
     101:             direrr(idesc->id_number, "BAD INODE NUMBER FOR '.'");
     102:             dirp->d_ino = idesc->id_number;
     103:             if (reply("FIX") == 1)
     104:                 ret |= ALTERED;
     105:         }
     106:         goto chk1;
     107:     }
     108:     direrr(idesc->id_number, "MISSING '.'");
     109:     proto.d_ino = idesc->id_number;
     110:     proto.d_namlen = 1;
     111:     (void)strcpy(proto.d_name, ".");
     112:     entrysize = DIRSIZ(&proto);
     113:     if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
     114:         pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
     115:             dirp->d_name);
     116:     } else if (dirp->d_reclen < entrysize) {
     117:         pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
     118:     } else if (dirp->d_reclen < 2 * entrysize) {
     119:         proto.d_reclen = dirp->d_reclen;
     120:         bcopy((char *)&proto, (char *)dirp, entrysize);
     121:         if (reply("FIX") == 1)
     122:             ret |= ALTERED;
     123:     } else {
     124:         n = dirp->d_reclen - entrysize;
     125:         proto.d_reclen = entrysize;
     126:         bcopy((char *)&proto, (char *)dirp, entrysize);
     127:         idesc->id_entryno++;
     128:         declncnt(dirp->d_ino);
     129:         dirp = (DIRECT *)((char *)(dirp) + entrysize);
     130:         bzero((char *)dirp, n);
     131:         dirp->d_reclen = n;
     132:         if (reply("FIX") == 1)
     133:             ret |= ALTERED;
     134:     }
     135: chk1:
     136:     if (idesc->id_entryno > 1)
     137:         goto chk2;
     138:     proto.d_ino = idesc->id_parent;
     139:     proto.d_namlen = 2;
     140:     (void)strcpy(proto.d_name, "..");
     141:     entrysize = DIRSIZ(&proto);
     142:     if (idesc->id_entryno == 0) {
     143:         n = DIRSIZ(dirp);
     144:         if (dirp->d_reclen < n + entrysize)
     145:             goto chk2;
     146:         proto.d_reclen = dirp->d_reclen - n;
     147:         dirp->d_reclen = n;
     148:         idesc->id_entryno++;
     149:         declncnt(dirp->d_ino);
     150:         dirp = (DIRECT *)((char *)(dirp) + n);
     151:         bzero((char *)dirp, n);
     152:         dirp->d_reclen = n;
     153:     }
     154:     if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
     155:         if (dirp->d_ino != idesc->id_parent) {
     156:             direrr(idesc->id_number, "BAD INODE NUMBER FOR '..'");
     157:             dirp->d_ino = idesc->id_parent;
     158:             if (reply("FIX") == 1)
     159:                 ret |= ALTERED;
     160:         }
     161:         goto chk2;
     162:     }
     163:     direrr(idesc->id_number, "MISSING '..'");
     164:     if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) {
     165:         pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
     166:             dirp->d_name);
     167:     } else if (dirp->d_reclen < entrysize) {
     168:         pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
     169:     } else {
     170:         proto.d_reclen = dirp->d_reclen;
     171:         bcopy((char *)&proto, (char *)dirp, entrysize);
     172:         if (reply("FIX") == 1)
     173:             ret |= ALTERED;
     174:     }
     175: chk2:
     176:     if (dirp->d_ino == 0)
     177:         return (ret|KEEPON);
     178:     if (dirp->d_namlen <= 2 &&
     179:         dirp->d_name[0] == '.' &&
     180:         idesc->id_entryno >= 2) {
     181:         if (dirp->d_namlen == 1) {
     182:             direrr(idesc->id_number, "EXTRA '.' ENTRY");
     183:             dirp->d_ino = 0;
     184:             if (reply("FIX") == 1)
     185:                 ret |= ALTERED;
     186:             return (KEEPON | ret);
     187:         }
     188:         if (dirp->d_name[1] == '.') {
     189:             direrr(idesc->id_number, "EXTRA '..' ENTRY");
     190:             dirp->d_ino = 0;
     191:             if (reply("FIX") == 1)
     192:                 ret |= ALTERED;
     193:             return (KEEPON | ret);
     194:         }
     195:     }
     196:     curpathloc = pathp;
     197:     *pathp++ = '/';
     198:     if (pathp + dirp->d_namlen >= endpathname) {
     199:         *pathp = '\0';
     200:         errexit("NAME TOO LONG %s%s\n", pathname, dirp->d_name);
     201:     }
     202:     bcopy(dirp->d_name, pathp, dirp->d_namlen + 1);
     203:     pathp += dirp->d_namlen;
     204:     idesc->id_entryno++;
     205:     n = 0;
     206:     if (dirp->d_ino > imax || dirp->d_ino <= 0) {
     207:         direrr(dirp->d_ino, "I OUT OF RANGE");
     208:         n = reply("REMOVE");
     209:     } else {
     210: again:
     211:         switch (getstate(dirp->d_ino)) {
     212:         case USTATE:
     213:             direrr(dirp->d_ino, "UNALLOCATED");
     214:             n = reply("REMOVE");
     215:             break;
     216:
     217:         case DCLEAR:
     218:         case FCLEAR:
     219:             direrr(dirp->d_ino, "DUP/BAD");
     220:             if ((n = reply("REMOVE")) == 1)
     221:                 break;
     222:             dp = ginode(dirp->d_ino);
     223:             setstate(dirp->d_ino, DIRCT(dp) ? DSTATE : FSTATE);
     224:             goto again;
     225:
     226:         case DFOUND:
     227:             if (idesc->id_entryno > 2) {
     228:                 getpathname(namebuf, dirp->d_ino, dirp->d_ino);
     229:                 pwarn("%s %s %s\n", pathname,
     230:                     "IS AN EXTRANEOUS HARD LINK TO DIRECTORY",
     231:                     namebuf);
     232:                 if (preen)
     233:                     printf(" (IGNORED)\n");
     234:                 else if ((n = reply("REMOVE")) == 1)
     235:                     break;
     236:             }
     237:             /* fall through */
     238:
     239:         case FSTATE:
     240:             declncnt(dirp->d_ino);
     241:             break;
     242:
     243:         case DSTATE:
     244:             descend(idesc, dirp->d_ino);
     245:             if (getstate(dirp->d_ino) == DFOUND) {
     246:                 declncnt(dirp->d_ino);
     247:             } else if (getstate(dirp->d_ino) == DCLEAR) {
     248:                 dirp->d_ino = 0;
     249:                 ret |= ALTERED;
     250:             } else
     251:                 errexit("BAD RETURN STATE %d FROM DESCEND",
     252:                     getstate(dirp->d_ino));
     253:             break;
     254:
     255:         default:
     256:             errexit("BAD STATE %d FOR INODE I=%u",
     257:                 getstate(dirp->d_ino), dirp->d_ino);
     258:         }
     259:     }
     260:     pathp = curpathloc;
     261:     *pathp = '\0';
     262:     if (n == 0)
     263:         return (ret|KEEPON);
     264:     dirp->d_ino = 0;
     265:     return (ret|KEEPON|ALTERED);
     266: }

#### Defined functions

pass2 defined in line 20; used 1 times

- in /usr/src/sbin/fsck/main.c line 204

pass2check defined in line 84; used 4 times

- in line 18, 27
- in /usr/src/sbin/fsck/pass3.c line 16, 46

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1990-09-16 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 964 |