BSD 4_4_Lite1 release
[unix-history] / usr / src / sbin / fsck / inode.c
index 990259c..f1c1758 100644 (file)
@@ -1,26 +1,69 @@
+/*
+ * Copyright (c) 1980, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
 #ifndef lint
 #ifndef lint
-static char version[] = "@(#)inode.c   3.11 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)inode.c    8.4 (Berkeley) 4/18/94";
+#endif /* not lint */
 
 
-#include <pwd.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include <sys/inode.h>
-#include <sys/fs.h>
-#include <sys/dir.h>
+#include <sys/time.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
 #include "fsck.h"
 
 #include "fsck.h"
 
+static ino_t startinum;
+
 ckinode(dp, idesc)
 ckinode(dp, idesc)
-       DINODE *dp;
+       struct dinode *dp;
        register struct inodesc *idesc;
 {
        register daddr_t *ap;
        register struct inodesc *idesc;
 {
        register daddr_t *ap;
-       int ret, n, ndb, offset;
-       DINODE dino;
+       long ret, n, ndb, offset;
+       struct dinode dino;
+       quad_t remsize, sizepb;
+       mode_t mode;
 
 
-       idesc->id_fix = DONTKNOW;
+       if (idesc->id_fix != IGNORE)
+               idesc->id_fix = DONTKNOW;
        idesc->id_entryno = 0;
        idesc->id_filesize = dp->di_size;
        idesc->id_entryno = 0;
        idesc->id_filesize = dp->di_size;
-       if (SPECIAL(dp))
+       mode = dp->di_mode & IFMT;
+       if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
+           dp->di_size < sblock.fs_maxsymlinklen))
                return (KEEPON);
        dino = *dp;
        ndb = howmany(dino.di_size, sblock.fs_bsize);
                return (KEEPON);
        dino = *dp;
        ndb = howmany(dino.di_size, sblock.fs_bsize);
@@ -41,28 +84,33 @@ ckinode(dp, idesc)
                        return (ret);
        }
        idesc->id_numfrags = sblock.fs_frag;
                        return (ret);
        }
        idesc->id_numfrags = sblock.fs_frag;
+       remsize = dino.di_size - sblock.fs_bsize * NDADDR;
+       sizepb = sblock.fs_bsize;
        for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
                if (*ap) {
                        idesc->id_blkno = *ap;
        for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
                if (*ap) {
                        idesc->id_blkno = *ap;
-                       ret = iblock(idesc, n,
-                               dino.di_size - sblock.fs_bsize * NDADDR);
+                       ret = iblock(idesc, n, remsize);
                        if (ret & STOP)
                                return (ret);
                }
                        if (ret & STOP)
                                return (ret);
                }
+               sizepb *= NINDIR(&sblock);
+               remsize -= sizepb;
        }
        return (KEEPON);
 }
 
 iblock(idesc, ilevel, isize)
        struct inodesc *idesc;
        }
        return (KEEPON);
 }
 
 iblock(idesc, ilevel, isize)
        struct inodesc *idesc;
-       register ilevel;
-       long isize;
+       long ilevel;
+       quad_t isize;
 {
        register daddr_t *ap;
        register daddr_t *aplim;
 {
        register daddr_t *ap;
        register daddr_t *aplim;
-       int i, n, (*func)(), nif, sizepb;
-       BUFAREA ib;
-       extern int pass1check();
+       register struct bufarea *bp;
+       int i, n, (*func)(), nif;
+       quad_t sizepb;
+       char buf[BUFSIZ];
+       extern int dirscan(), pass1check();
 
        if (idesc->id_type == ADDR) {
                func = idesc->id_func;
 
        if (idesc->id_type == ADDR) {
                func = idesc->id_func;
@@ -70,69 +118,77 @@ iblock(idesc, ilevel, isize)
                        return (n);
        } else
                func = dirscan;
                        return (n);
        } else
                func = dirscan;
-       if (outrange(idesc->id_blkno, idesc->id_numfrags)) /* protect thyself */
-               return (SKIP);
-       initbarea(&ib);
-       getblk(&ib, idesc->id_blkno, sblock.fs_bsize);
-       if (ib.b_errs != NULL)
+       if (chkrange(idesc->id_blkno, idesc->id_numfrags))
                return (SKIP);
                return (SKIP);
+       bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
        ilevel--;
        for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
                sizepb *= NINDIR(&sblock);
        ilevel--;
        for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
                sizepb *= NINDIR(&sblock);
-       nif = isize / sizepb + 1;
+       nif = howmany(isize , sizepb);
        if (nif > NINDIR(&sblock))
                nif = NINDIR(&sblock);
        if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
        if (nif > NINDIR(&sblock))
                nif = NINDIR(&sblock);
        if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
-               aplim = &ib.b_un.b_indir[NINDIR(&sblock)];
-               for (ap = &ib.b_un.b_indir[nif]; ap < aplim; ap++) {
+               aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
+               for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
                        if (*ap == 0)
                                continue;
                        if (*ap == 0)
                                continue;
-                       if (dofix(idesc, "PARTIALLY TRUNCATED INODE")) {
+                       (void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
+                               idesc->id_number);
+                       if (dofix(idesc, buf)) {
                                *ap = 0;
                                *ap = 0;
-                               dirty(&ib);
+                               dirty(bp);
                        }
                }
                        }
                }
-               flush(&dfile, &ib);
+               flush(fswritefd, bp);
        }
        }
-       aplim = &ib.b_un.b_indir[nif];
-       for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++)
+       aplim = &bp->b_un.b_indir[nif];
+       for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
                if (*ap) {
                        idesc->id_blkno = *ap;
                if (*ap) {
                        idesc->id_blkno = *ap;
-                       if (ilevel > 0)
-                               n = iblock(idesc, ilevel, isize - i * sizepb);
-                       else
+                       if (ilevel == 0)
                                n = (*func)(idesc);
                                n = (*func)(idesc);
-                       if (n & STOP)
+                       else
+                               n = iblock(idesc, ilevel, isize);
+                       if (n & STOP) {
+                               bp->b_flags &= ~B_INUSE;
                                return (n);
                                return (n);
+                       }
                }
                }
+               isize -= sizepb;
+       }
+       bp->b_flags &= ~B_INUSE;
        return (KEEPON);
 }
 
        return (KEEPON);
 }
 
-outrange(blk, cnt)
+/*
+ * Check that a block in a legal block number.
+ * Return 0 if in range, 1 if out of range.
+ */
+chkrange(blk, cnt)
        daddr_t blk;
        int cnt;
 {
        register int c;
 
        daddr_t blk;
        int cnt;
 {
        register int c;
 
-       if ((unsigned)(blk+cnt) > fmax)
+       if ((unsigned)(blk + cnt) > maxfsblock)
                return (1);
        c = dtog(&sblock, blk);
        if (blk < cgdmin(&sblock, c)) {
                return (1);
        c = dtog(&sblock, blk);
        if (blk < cgdmin(&sblock, c)) {
-               if ((blk+cnt) > cgsblock(&sblock, c)) {
+               if ((blk + cnt) > cgsblock(&sblock, c)) {
                        if (debug) {
                        if (debug) {
-                               printf("blk %d < cgdmin %d;",
+                               printf("blk %ld < cgdmin %ld;",
                                    blk, cgdmin(&sblock, c));
                                    blk, cgdmin(&sblock, c));
-                               printf(" blk+cnt %d > cgsbase %d\n",
-                                   blk+cnt, cgsblock(&sblock, c));
+                               printf(" blk + cnt %ld > cgsbase %ld\n",
+                                   blk + cnt, cgsblock(&sblock, c));
                        }
                        return (1);
                }
        } else {
                        }
                        return (1);
                }
        } else {
-               if ((blk+cnt) > cgbase(&sblock, c+1)) {
+               if ((blk + cnt) > cgbase(&sblock, c+1)) {
                        if (debug)  {
                        if (debug)  {
-                               printf("blk %d >= cgdmin %d;",
+                               printf("blk %ld >= cgdmin %ld;",
                                    blk, cgdmin(&sblock, c));
                                    blk, cgdmin(&sblock, c));
-                               printf(" blk+cnt %d > sblock.fs_fpg %d\n",
+                               printf(" blk + cnt %ld > sblock.fs_fpg %ld\n",
                                    blk+cnt, sblock.fs_fpg);
                        }
                        return (1);
                                    blk+cnt, sblock.fs_fpg);
                        }
                        return (1);
@@ -141,34 +197,188 @@ outrange(blk, cnt)
        return (0);
 }
 
        return (0);
 }
 
-DINODE *
+/*
+ * General purpose interface for reading inodes.
+ */
+struct dinode *
 ginode(inumber)
        ino_t inumber;
 {
        daddr_t iblk;
 ginode(inumber)
        ino_t inumber;
 {
        daddr_t iblk;
-       static ino_t startinum = 0;     /* blk num of first in raw area */
 
 
-       if (inumber < ROOTINO || inumber > imax)
+       if (inumber < ROOTINO || inumber > maxino)
                errexit("bad inode number %d to ginode\n", inumber);
        if (startinum == 0 ||
            inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
                errexit("bad inode number %d to ginode\n", inumber);
        if (startinum == 0 ||
            inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
-               iblk = itod(&sblock, inumber);
-               getblk(&inoblk, iblk, sblock.fs_bsize);
+               iblk = ino_to_fsba(&sblock, inumber);
+               if (pbp != 0)
+                       pbp->b_flags &= ~B_INUSE;
+               pbp = getdatablk(iblk, sblock.fs_bsize);
                startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
        }
                startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
        }
-       return (&inoblk.b_un.b_dinode[inumber % INOPB(&sblock)]);
+       return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
+}
+
+/*
+ * Special purpose version of ginode used to optimize first pass
+ * over all the inodes in numerical order.
+ */
+ino_t nextino, lastinum;
+long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
+struct dinode *inodebuf;
+
+struct dinode *
+getnextinode(inumber)
+       ino_t inumber;
+{
+       long size;
+       daddr_t dblk;
+       static struct dinode *dp;
+
+       if (inumber != nextino++ || inumber > maxino)
+               errexit("bad inode number %d to nextinode\n", inumber);
+       if (inumber >= lastinum) {
+               readcnt++;
+               dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
+               if (readcnt % readpercg == 0) {
+                       size = partialsize;
+                       lastinum += partialcnt;
+               } else {
+                       size = inobufsize;
+                       lastinum += fullcnt;
+               }
+               (void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
+               dp = inodebuf;
+       }
+       return (dp++);
+}
+
+resetinodebuf()
+{
+
+       startinum = 0;
+       nextino = 0;
+       lastinum = 0;
+       readcnt = 0;
+       inobufsize = blkroundup(&sblock, INOBUFSIZE);
+       fullcnt = inobufsize / sizeof(struct dinode);
+       readpercg = sblock.fs_ipg / fullcnt;
+       partialcnt = sblock.fs_ipg % fullcnt;
+       partialsize = partialcnt * sizeof(struct dinode);
+       if (partialcnt != 0) {
+               readpercg++;
+       } else {
+               partialcnt = fullcnt;
+               partialsize = inobufsize;
+       }
+       if (inodebuf == NULL &&
+           (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
+               errexit("Cannot allocate space for inode buffer\n");
+       while (nextino < ROOTINO)
+               (void)getnextinode(nextino);
+}
+
+freeinodebuf()
+{
+
+       if (inodebuf != NULL)
+               free((char *)inodebuf);
+       inodebuf = NULL;
+}
+
+/*
+ * Routines to maintain information about directory inodes.
+ * This is built during the first pass and used during the
+ * second and third passes.
+ *
+ * Enter inodes into the cache.
+ */
+cacheino(dp, inumber)
+       register struct dinode *dp;
+       ino_t inumber;
+{
+       register struct inoinfo *inp;
+       struct inoinfo **inpp;
+       unsigned int blks;
+
+       blks = howmany(dp->di_size, sblock.fs_bsize);
+       if (blks > NDADDR)
+               blks = NDADDR + NIADDR;
+       inp = (struct inoinfo *)
+               malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t));
+       if (inp == NULL)
+               return;
+       inpp = &inphead[inumber % numdirs];
+       inp->i_nexthash = *inpp;
+       *inpp = inp;
+       inp->i_parent = (ino_t)0;
+       inp->i_dotdot = (ino_t)0;
+       inp->i_number = inumber;
+       inp->i_isize = dp->di_size;
+       inp->i_numblks = blks * sizeof(daddr_t);
+       bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0],
+           (size_t)inp->i_numblks);
+       if (inplast == listmax) {
+               listmax += 100;
+               inpsort = (struct inoinfo **)realloc((char *)inpsort,
+                   (unsigned)listmax * sizeof(struct inoinfo *));
+               if (inpsort == NULL)
+                       errexit("cannot increase directory list");
+       }
+       inpsort[inplast++] = inp;
+}
+
+/*
+ * Look up an inode cache structure.
+ */
+struct inoinfo *
+getinoinfo(inumber)
+       ino_t inumber;
+{
+       register struct inoinfo *inp;
+
+       for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) {
+               if (inp->i_number != inumber)
+                       continue;
+               return (inp);
+       }
+       errexit("cannot find inode %d\n", inumber);
+       return ((struct inoinfo *)0);
+}
+
+/*
+ * Clean up all the inode cache structure.
+ */
+inocleanup()
+{
+       register struct inoinfo **inpp;
+
+       if (inphead == NULL)
+               return;
+       for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
+               free((char *)(*inpp));
+       free((char *)inphead);
+       free((char *)inpsort);
+       inphead = inpsort = NULL;
+}
+       
+inodirty()
+{
+       
+       dirty(pbp);
 }
 
 }
 
-clri(idesc, s, flg)
+clri(idesc, type, flag)
        register struct inodesc *idesc;
        register struct inodesc *idesc;
-       char *s;
-       int flg;
+       char *type;
+       int flag;
 {
 {
-       register DINODE *dp;
+       register struct dinode *dp;
 
        dp = ginode(idesc->id_number);
 
        dp = ginode(idesc->id_number);
-       if (flg == 1) {
-               pwarn("%s %s", s, DIRCT(dp) ? "DIR" : "FILE");
+       if (flag == 1) {
+               pwarn("%s %s", type,
+                   (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
                pinode(idesc->id_number);
        }
        if (preen || reply("CLEAR") == 1) {
                pinode(idesc->id_number);
        }
        if (preen || reply("CLEAR") == 1) {
@@ -176,7 +386,7 @@ clri(idesc, s, flg)
                        printf(" (CLEARED)\n");
                n_files--;
                (void)ckinode(dp, idesc);
                        printf(" (CLEARED)\n");
                n_files--;
                (void)ckinode(dp, idesc);
-               zapino(dp);
+               clearinode(dp);
                statemap[idesc->id_number] = USTATE;
                inodirty();
        }
                statemap[idesc->id_number] = USTATE;
                inodirty();
        }
@@ -185,25 +395,25 @@ clri(idesc, s, flg)
 findname(idesc)
        struct inodesc *idesc;
 {
 findname(idesc)
        struct inodesc *idesc;
 {
-       register DIRECT *dirp = idesc->id_dirp;
+       register struct direct *dirp = idesc->id_dirp;
 
        if (dirp->d_ino != idesc->id_parent)
                return (KEEPON);
 
        if (dirp->d_ino != idesc->id_parent)
                return (KEEPON);
-       bcopy(dirp->d_name, idesc->id_name, dirp->d_namlen + 1);
-       return (STOP);
+       bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1);
+       return (STOP|FOUND);
 }
 
 findino(idesc)
        struct inodesc *idesc;
 {
 }
 
 findino(idesc)
        struct inodesc *idesc;
 {
-       register DIRECT *dirp = idesc->id_dirp;
+       register struct direct *dirp = idesc->id_dirp;
 
        if (dirp->d_ino == 0)
                return (KEEPON);
        if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
 
        if (dirp->d_ino == 0)
                return (KEEPON);
        if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
-           dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) {
+           dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) {
                idesc->id_parent = dirp->d_ino;
                idesc->id_parent = dirp->d_ino;
-               return (STOP);
+               return (STOP|FOUND);
        }
        return (KEEPON);
 }
        }
        return (KEEPON);
 }
@@ -211,35 +421,35 @@ findino(idesc)
 pinode(ino)
        ino_t ino;
 {
 pinode(ino)
        ino_t ino;
 {
-       register DINODE *dp;
+       register struct dinode *dp;
        register char *p;
        struct passwd *pw;
        char *ctime();
 
        register char *p;
        struct passwd *pw;
        char *ctime();
 
-       printf(" I=%u ", ino);
-       if (ino < ROOTINO || ino > imax)
+       printf(" I=%lu ", ino);
+       if (ino < ROOTINO || ino > maxino)
                return;
        dp = ginode(ino);
        printf(" OWNER=");
        if ((pw = getpwuid((int)dp->di_uid)) != 0)
                printf("%s ", pw->pw_name);
        else
                return;
        dp = ginode(ino);
        printf(" OWNER=");
        if ((pw = getpwuid((int)dp->di_uid)) != 0)
                printf("%s ", pw->pw_name);
        else
-               printf("%d ", dp->di_uid);
+               printf("%u ", (unsigned)dp->di_uid);
        printf("MODE=%o\n", dp->di_mode);
        if (preen)
        printf("MODE=%o\n", dp->di_mode);
        if (preen)
-               printf("%s: ", devname);
-       printf("SIZE=%ld ", dp->di_size);
-       p = ctime(&dp->di_mtime);
-       printf("MTIME=%12.12s %4.4s ", p+4, p+20);
+               printf("%s: ", cdevname);
+       printf("SIZE=%qu ", dp->di_size);
+       p = ctime(&dp->di_mtime.ts_sec);
+       printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
 }
 
 }
 
-blkerr(ino, s, blk)
+blkerror(ino, type, blk)
        ino_t ino;
        ino_t ino;
-       char *s;
+       char *type;
        daddr_t blk;
 {
 
        daddr_t blk;
 {
 
-       pfatal("%ld %s I=%u", blk, s, ino);
+       pfatal("%ld %s I=%lu", blk, type, ino);
        printf("\n");
        switch (statemap[ino]) {
 
        printf("\n");
        switch (statemap[ino]) {
 
@@ -270,16 +480,16 @@ allocino(request, type)
        int type;
 {
        register ino_t ino;
        int type;
 {
        register ino_t ino;
-       register DINODE *dp;
+       register struct dinode *dp;
 
        if (request == 0)
                request = ROOTINO;
        else if (statemap[request] != USTATE)
                return (0);
 
        if (request == 0)
                request = ROOTINO;
        else if (statemap[request] != USTATE)
                return (0);
-       for (ino = request; ino < imax; ino++)
+       for (ino = request; ino < maxino; ino++)
                if (statemap[ino] == USTATE)
                        break;
                if (statemap[ino] == USTATE)
                        break;
-       if (ino == imax)
+       if (ino == maxino)
                return (0);
        switch (type & IFMT) {
        case IFDIR:
                return (0);
        switch (type & IFMT) {
        case IFDIR:
@@ -293,18 +503,20 @@ allocino(request, type)
                return (0);
        }
        dp = ginode(ino);
                return (0);
        }
        dp = ginode(ino);
-       dp->di_db[0] = allocblk(1);
+       dp->di_db[0] = allocblk((long)1);
        if (dp->di_db[0] == 0) {
                statemap[ino] = USTATE;
                return (0);
        }
        dp->di_mode = type;
        if (dp->di_db[0] == 0) {
                statemap[ino] = USTATE;
                return (0);
        }
        dp->di_mode = type;
-       time(&dp->di_atime);
+       (void)time(&dp->di_atime.ts_sec);
        dp->di_mtime = dp->di_ctime = dp->di_atime;
        dp->di_size = sblock.fs_fsize;
        dp->di_blocks = btodb(sblock.fs_fsize);
        n_files++;
        inodirty();
        dp->di_mtime = dp->di_ctime = dp->di_atime;
        dp->di_size = sblock.fs_fsize;
        dp->di_blocks = btodb(sblock.fs_fsize);
        n_files++;
        inodirty();
+       if (newinofmt)
+               typemap[ino] = IFTODT(type);
        return (ino);
 }
 
        return (ino);
 }
 
@@ -316,7 +528,7 @@ freeino(ino)
 {
        struct inodesc idesc;
        extern int pass4check();
 {
        struct inodesc idesc;
        extern int pass4check();
-       DINODE *dp;
+       struct dinode *dp;
 
        bzero((char *)&idesc, sizeof(struct inodesc));
        idesc.id_type = ADDR;
 
        bzero((char *)&idesc, sizeof(struct inodesc));
        idesc.id_type = ADDR;
@@ -324,7 +536,7 @@ freeino(ino)
        idesc.id_number = ino;
        dp = ginode(ino);
        (void)ckinode(dp, &idesc);
        idesc.id_number = ino;
        dp = ginode(ino);
        (void)ckinode(dp, &idesc);
-       zapino(dp);
+       clearinode(dp);
        inodirty();
        statemap[ino] = USTATE;
        n_files--;
        inodirty();
        statemap[ino] = USTATE;
        n_files--;