Fix copyright
[unix-history] / usr / src / sbin / fsck / dir.c
index 8739297..5095c3a 100644 (file)
@@ -1,6 +1,12 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char version[] = "@(#)dir.c     3.7 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)dir.c      5.1 (Berkeley) %G%";
+#endif not lint
 
 #include <sys/param.h>
 #include <sys/inode.h>
 
 #include <sys/param.h>
 #include <sys/inode.h>
@@ -43,11 +49,19 @@ descend(parentino, inumber)
                if (reply("FIX") == 1)
                        inodirty();
        }
                if (reply("FIX") == 1)
                        inodirty();
        }
+       if ((dp->di_size & (DIRBLKSIZ - 1)) != 0) {
+               pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d",
+                       pathname, dp->di_size, DIRBLKSIZ);
+               dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
+               if (preen)
+                       printf(" (ADJUSTED)\n");
+               if (preen || reply("ADJUST") == 1)
+                       inodirty();
+       }
        curino.id_type = DATA;
        curino.id_func = parentino->id_func;
        curino.id_parent = parentino->id_number;
        curino.id_number = inumber;
        curino.id_type = DATA;
        curino.id_func = parentino->id_func;
        curino.id_parent = parentino->id_number;
        curino.id_number = inumber;
-       curino.id_filesize = dp->di_size;
        (void)ckinode(dp, &curino);
 }
 
        (void)ckinode(dp, &curino);
 }
 
@@ -61,6 +75,9 @@ dirscan(idesc)
 
        if (idesc->id_type != DATA)
                errexit("wrong type to dirscan %d\n", idesc->id_type);
 
        if (idesc->id_type != DATA)
                errexit("wrong type to dirscan %d\n", idesc->id_type);
+       if (idesc->id_entryno == 0 &&
+           (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
+               idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
        blksiz = idesc->id_numfrags * sblock.fs_fsize;
        if (outrange(idesc->id_blkno, idesc->id_numfrags)) {
                idesc->id_filesize -= blksiz;
        blksiz = idesc->id_numfrags * sblock.fs_fsize;
        if (outrange(idesc->id_blkno, idesc->id_numfrags)) {
                idesc->id_filesize -= blksiz;
@@ -72,12 +89,14 @@ dirscan(idesc)
                bcopy((char *)dp, dbuf, dsize);
                idesc->id_dirp = (DIRECT *)dbuf;
                if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
                bcopy((char *)dp, dbuf, dsize);
                idesc->id_dirp = (DIRECT *)dbuf;
                if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
-                       if (getblk(&fileblk, idesc->id_blkno, blksiz) != NULL) {
+                       getblk(&fileblk, idesc->id_blkno, blksiz);
+                       if (fileblk.b_errs != NULL) {
+                               n &= ~ALTERED;
+                       } else {
                                bcopy(dbuf, (char *)dp, dsize);
                                dirty(&fileblk);
                                sbdirty();
                                bcopy(dbuf, (char *)dp, dsize);
                                dirty(&fileblk);
                                sbdirty();
-                       } else
-                               n &= ~ALTERED;
+                       }
                }
                if (n & STOP) 
                        return (n);
                }
                if (n & STOP) 
                        return (n);
@@ -96,7 +115,8 @@ fsck_readdir(idesc)
        long size, blksiz;
 
        blksiz = idesc->id_numfrags * sblock.fs_fsize;
        long size, blksiz;
 
        blksiz = idesc->id_numfrags * sblock.fs_fsize;
-       if (getblk(&fileblk, idesc->id_blkno, blksiz) == NULL) {
+       getblk(&fileblk, idesc->id_blkno, blksiz);
+       if (fileblk.b_errs != NULL) {
                idesc->id_filesize -= blksiz - idesc->id_loc;
                return NULL;
        }
                idesc->id_filesize -= blksiz - idesc->id_loc;
                return NULL;
        }
@@ -286,23 +306,20 @@ linkup(orphan, pdir)
                idesc.id_type = DATA;
                idesc.id_func = findino;
                idesc.id_number = ROOTINO;
                idesc.id_type = DATA;
                idesc.id_func = findino;
                idesc.id_number = ROOTINO;
-               idesc.id_filesize = dp->di_size;
                (void)ckinode(dp, &idesc);
                if (idesc.id_parent >= ROOTINO && idesc.id_parent < imax) {
                        lfdir = idesc.id_parent;
                } else {
                        pwarn("NO lost+found DIRECTORY");
                        if (preen || reply("CREATE")) {
                (void)ckinode(dp, &idesc);
                if (idesc.id_parent >= ROOTINO && idesc.id_parent < imax) {
                        lfdir = idesc.id_parent;
                } else {
                        pwarn("NO lost+found DIRECTORY");
                        if (preen || reply("CREATE")) {
-                               idesc.id_func = mkentry;
-                               idesc.id_parent = allocdir(ROOTINO, 0);
-                               idesc.id_filesize = dp->di_size;
-                               if (idesc.id_parent != 0) {
-                                       if (makeentry(dp, &idesc) != 0) {
-                                               lfdir = idesc.id_parent;
+                               lfdir = allocdir(ROOTINO, 0);
+                               if (lfdir != 0) {
+                                       if (makeentry(ROOTINO, lfdir, lfname) != 0) {
                                                if (preen)
                                                        printf(" (CREATED)\n");
                                        } else {
                                                if (preen)
                                                        printf(" (CREATED)\n");
                                        } else {
-                                               freedir(idesc.id_parent, ROOTINO);
+                                               freedir(lfdir, ROOTINO);
+                                               lfdir = 0;
                                                if (preen)
                                                        printf("\n");
                                        }
                                                if (preen)
                                                        printf("\n");
                                        }
@@ -346,22 +363,11 @@ linkup(orphan, pdir)
                pfatal("SORRY. NO lost+found DIRECTORY\n\n");
                return (0);
        }
                pfatal("SORRY. NO lost+found DIRECTORY\n\n");
                return (0);
        }
-       if (dp->di_size % DIRBLKSIZ) {
-               dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
-               inodirty();
-       }
        len = strlen(lfname);
        bcopy(lfname, pathp, len + 1);
        pathp += len;
        len = strlen(lfname);
        bcopy(lfname, pathp, len + 1);
        pathp += len;
-       idesc.id_type = DATA;
-       idesc.id_func = mkentry;
-       idesc.id_number = lfdir;
-       idesc.id_filesize = dp->di_size;
-       idesc.id_parent = orphan;       /* this is the inode to enter */
-       idesc.id_fix = DONTKNOW;
-       idesc.id_name = tempname;
-       len = lftempname(idesc.id_name, orphan);
-       if (makeentry(dp, &idesc) == 0) {
+       len = lftempname(tempname, orphan);
+       if (makeentry(lfdir, orphan, tempname) == 0) {
                pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
                printf("\n\n");
                return (0);
                pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");
                printf("\n\n");
                return (0);
@@ -375,7 +381,6 @@ linkup(orphan, pdir)
                idesc.id_type = DATA;
                idesc.id_func = chgino;
                idesc.id_number = orphan;
                idesc.id_type = DATA;
                idesc.id_func = chgino;
                idesc.id_number = orphan;
-               idesc.id_filesize = dp->di_size;
                idesc.id_fix = DONTKNOW;
                idesc.id_name = "..";
                idesc.id_parent = lfdir;        /* new value for ".." */
                idesc.id_fix = DONTKNOW;
                idesc.id_name = "..";
                idesc.id_parent = lfdir;        /* new value for ".." */
@@ -395,17 +400,32 @@ linkup(orphan, pdir)
 /*
  * make an entry in a directory
  */
 /*
  * make an entry in a directory
  */
-makeentry(dp, idesc)
-       DINODE *dp;
-       struct inodesc *idesc;
+makeentry(parent, ino, name)
+       ino_t parent, ino;
+       char *name;
 {
 {
+       DINODE *dp;
+       struct inodesc idesc;
        
        
-       if ((ckinode(dp, idesc) & ALTERED) != 0)
+       if (parent < ROOTINO || parent >= imax || ino < ROOTINO || ino >= imax)
+               return (0);
+       bzero(&idesc, sizeof(struct inodesc));
+       idesc.id_type = DATA;
+       idesc.id_func = mkentry;
+       idesc.id_number = parent;
+       idesc.id_parent = ino;  /* this is the inode to enter */
+       idesc.id_fix = DONTKNOW;
+       idesc.id_name = name;
+       dp = ginode(parent);
+       if (dp->di_size % DIRBLKSIZ) {
+               dp->di_size = roundup(dp->di_size, DIRBLKSIZ);
+               inodirty();
+       }
+       if ((ckinode(dp, &idesc) & ALTERED) != 0)
                return (1);
        if (expanddir(dp) == 0)
                return (0);
                return (1);
        if (expanddir(dp) == 0)
                return (0);
-       idesc->id_filesize = dp->di_size;
-       return (ckinode(dp, idesc) & ALTERED);
+       return (ckinode(dp, &idesc) & ALTERED);
 }
 
 /*
 }
 
 /*
@@ -426,11 +446,13 @@ expanddir(dp)
        dp->di_db[lastbn] = newblk;
        dp->di_size += sblock.fs_bsize;
        dp->di_blocks += btodb(sblock.fs_bsize);
        dp->di_db[lastbn] = newblk;
        dp->di_size += sblock.fs_bsize;
        dp->di_blocks += btodb(sblock.fs_bsize);
-       if (getblk(&fileblk, dp->di_db[lastbn + 1],
-           dblksize(&sblock, dp, lastbn + 1)) == NULL)
+       getblk(&fileblk, dp->di_db[lastbn + 1],
+           dblksize(&sblock, dp, lastbn + 1));
+       if (fileblk.b_errs != NULL)
                goto bad;
        bcopy(dirblk.b_buf, firstblk, DIRBLKSIZ);
                goto bad;
        bcopy(dirblk.b_buf, firstblk, DIRBLKSIZ);
-       if (getblk(&fileblk, newblk, sblock.fs_bsize) == NULL)
+       getblk(&fileblk, newblk, sblock.fs_bsize);
+       if (fileblk.b_errs != NULL)
                goto bad;
        bcopy(firstblk, dirblk.b_buf, DIRBLKSIZ);
        for (cp = &dirblk.b_buf[DIRBLKSIZ];
                goto bad;
        bcopy(firstblk, dirblk.b_buf, DIRBLKSIZ);
        for (cp = &dirblk.b_buf[DIRBLKSIZ];
@@ -438,8 +460,9 @@ expanddir(dp)
             cp += DIRBLKSIZ)
                bcopy((char *)&emptydir, cp, sizeof emptydir);
        dirty(&fileblk);
             cp += DIRBLKSIZ)
                bcopy((char *)&emptydir, cp, sizeof emptydir);
        dirty(&fileblk);
-       if (getblk(&fileblk, dp->di_db[lastbn + 1],
-           dblksize(&sblock, dp, lastbn + 1)) == NULL)
+       getblk(&fileblk, dp->di_db[lastbn + 1],
+           dblksize(&sblock, dp, lastbn + 1));
+       if (fileblk.b_errs != NULL)
                goto bad;
        bcopy((char *)&emptydir, dirblk.b_buf, sizeof emptydir);
        pwarn("NO SPACE LEFT IN %s", pathname);
                goto bad;
        bcopy((char *)&emptydir, dirblk.b_buf, sizeof emptydir);
        pwarn("NO SPACE LEFT IN %s", pathname);
@@ -473,7 +496,8 @@ allocdir(parent, request)
        dirhead.dot_ino = ino;
        dirhead.dotdot_ino = parent;
        dp = ginode(ino);
        dirhead.dot_ino = ino;
        dirhead.dotdot_ino = parent;
        dp = ginode(ino);
-       if (getblk(&fileblk, dp->di_db[0], sblock.fs_fsize) == NULL) {
+       getblk(&fileblk, dp->di_db[0], sblock.fs_fsize);
+       if (fileblk.b_errs != NULL) {
                freeino(ino);
                return (0);
        }
                freeino(ino);
                return (0);
        }