BSD 4_4_Lite1 release
[unix-history] / usr / src / sbin / fsck / inode.c
index 3a84411..f1c1758 100644 (file)
@@ -1,18 +1,45 @@
 /*
 /*
- * Copyright (c) 1980, 1986 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * 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 sccsid[] = "@(#)inode.c    5.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)inode.c    8.4 (Berkeley) 4/18/94";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
-#include <ufs/dinode.h>
-#include <ufs/fs.h>
-#include <ufs/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 <pwd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,12 +54,16 @@ ckinode(dp, idesc)
        register daddr_t *ap;
        long ret, n, ndb, offset;
        struct dinode dino;
        register daddr_t *ap;
        long ret, n, ndb, offset;
        struct dinode dino;
+       quad_t remsize, sizepb;
+       mode_t mode;
 
        if (idesc->id_fix != IGNORE)
                idesc->id_fix = DONTKNOW;
        idesc->id_entryno = 0;
        idesc->id_filesize = dp->di_size;
 
        if (idesc->id_fix != IGNORE)
                idesc->id_fix = DONTKNOW;
        idesc->id_entryno = 0;
        idesc->id_filesize = dp->di_size;
-       if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR)
+       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);
@@ -53,27 +84,31 @@ 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 long ilevel;
-       u_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;
        register struct bufarea *bp;
        register struct bufarea *bp;
+       int i, n, (*func)(), nif;
+       quad_t sizepb;
        char buf[BUFSIZ];
        extern int dirscan(), pass1check();
 
        char buf[BUFSIZ];
        extern int dirscan(), pass1check();
 
@@ -89,7 +124,7 @@ iblock(idesc, ilevel, isize)
        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)) {
@@ -107,18 +142,19 @@ iblock(idesc, ilevel, isize)
                flush(fswritefd, bp);
        }
        aplim = &bp->b_un.b_indir[nif];
                flush(fswritefd, bp);
        }
        aplim = &bp->b_un.b_indir[nif];
-       for (ap = bp->b_un.b_indir, i = 1; ap < aplim; ap++, i++) {
+       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);
+                       else
+                               n = iblock(idesc, ilevel, isize);
                        if (n & STOP) {
                                bp->b_flags &= ~B_INUSE;
                                return (n);
                        }
                }
                        if (n & STOP) {
                                bp->b_flags &= ~B_INUSE;
                                return (n);
                        }
                }
+               isize -= sizepb;
        }
        bp->b_flags &= ~B_INUSE;
        return (KEEPON);
        }
        bp->b_flags &= ~B_INUSE;
        return (KEEPON);
@@ -174,7 +210,7 @@ ginode(inumber)
                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);
+               iblk = ino_to_fsba(&sblock, inumber);
                if (pbp != 0)
                        pbp->b_flags &= ~B_INUSE;
                pbp = getdatablk(iblk, sblock.fs_bsize);
                if (pbp != 0)
                        pbp->b_flags &= ~B_INUSE;
                pbp = getdatablk(iblk, sblock.fs_bsize);
@@ -203,7 +239,7 @@ getnextinode(inumber)
                errexit("bad inode number %d to nextinode\n", inumber);
        if (inumber >= lastinum) {
                readcnt++;
                errexit("bad inode number %d to nextinode\n", inumber);
        if (inumber >= lastinum) {
                readcnt++;
-               dblk = fsbtodb(&sblock, itod(&sblock, lastinum));
+               dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
                if (readcnt % readpercg == 0) {
                        size = partialsize;
                        lastinum += partialcnt;
                if (readcnt % readpercg == 0) {
                        size = partialsize;
                        lastinum += partialcnt;
@@ -401,10 +437,10 @@ pinode(ino)
                printf("%u ", (unsigned)dp->di_uid);
        printf("MODE=%o\n", dp->di_mode);
        if (preen)
                printf("%u ", (unsigned)dp->di_uid);
        printf("MODE=%o\n", dp->di_mode);
        if (preen)
-               printf("%s: ", devname);
-       printf("SIZE=%lu ", 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]);
 }
 
 blkerror(ino, type, blk)
 }
 
 blkerror(ino, type, blk)
@@ -473,12 +509,14 @@ allocino(request, type)
                return (0);
        }
        dp->di_mode = type;
                return (0);
        }
        dp->di_mode = type;
-       (void)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);
 }