(no message)
[unix-history] / usr / src / sys / ufs / ffs / ffs_alloc.c
index 043f89b..c8b7518 100644 (file)
@@ -1,8 +1,4 @@
-/*     alloc.c 4.1     82/03/25        */
-
-/* merged into kernel: @(#)ffs_alloc.c 2.3 %G% */
-
-/* last monet version: alloc.c 4.8     81/03/08        */
+/*     ffs_alloc.c     2.11    82/09/06        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -11,8 +7,10 @@
 #include "../h/conf.h"
 #include "../h/buf.h"
 #include "../h/inode.h"
 #include "../h/conf.h"
 #include "../h/buf.h"
 #include "../h/inode.h"
-#include "../h/ndir.h"
+#include "../h/dir.h"
 #include "../h/user.h"
 #include "../h/user.h"
+#include "../h/quota.h"
+#include "../h/kernel.h"
 
 extern u_long          hashalloc();
 extern ino_t           ialloccg();
 
 extern u_long          hashalloc();
 extern ino_t           ialloccg();
@@ -55,14 +53,21 @@ alloc(ip, bpref, size)
        int cg;
        
        fs = ip->i_fs;
        int cg;
        
        fs = ip->i_fs;
-       if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0)
+       if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0) {
+               printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n",
+                   ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt);
                panic("alloc: bad size");
                panic("alloc: bad size");
+       }
        if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
                goto nospace;
        if (u.u_uid != 0 &&
            fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
              fs->fs_dsize * fs->fs_minfree / 100)
                goto nospace;
        if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0)
                goto nospace;
        if (u.u_uid != 0 &&
            fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
              fs->fs_dsize * fs->fs_minfree / 100)
                goto nospace;
+#ifdef QUOTA
+       if (chkdq(ip, (long)((unsigned)size/DEV_BSIZE), 0))
+               return(NULL);
+#endif
        if (bpref >= fs->fs_size)
                bpref = 0;
        if (bpref == 0)
        if (bpref >= fs->fs_size)
                bpref = 0;
        if (bpref == 0)
@@ -70,7 +75,7 @@ alloc(ip, bpref, size)
        else
                cg = dtog(fs, bpref);
        bno = (daddr_t)hashalloc(ip, cg, (long)bpref, size, alloccg);
        else
                cg = dtog(fs, bpref);
        bno = (daddr_t)hashalloc(ip, cg, (long)bpref, size, alloccg);
-       if (bno == 0)
+       if (bno <= 0)
                goto nospace;
        bp = getblk(ip->i_dev, fsbtodb(fs, bno), size);
        clrbuf(bp);
                goto nospace;
        bp = getblk(ip->i_dev, fsbtodb(fs, bno), size);
        clrbuf(bp);
@@ -99,51 +104,56 @@ realloccg(ip, bprev, bpref, osize, nsize)
        daddr_t bno;
        register struct fs *fs;
        register struct buf *bp, *obp;
        daddr_t bno;
        register struct fs *fs;
        register struct buf *bp, *obp;
-       caddr_t cp;
        int cg;
        
        fs = ip->i_fs;
        if ((unsigned)osize > fs->fs_bsize || fragoff(fs, osize) != 0 ||
        int cg;
        
        fs = ip->i_fs;
        if ((unsigned)osize > fs->fs_bsize || fragoff(fs, osize) != 0 ||
-           (unsigned)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0)
+           (unsigned)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) {
+               printf("dev = 0x%x, bsize = %d, osize = %d, nsize = %d, fs = %s\n",
+                   ip->i_dev, fs->fs_bsize, osize, nsize, fs->fs_fsmnt);
                panic("realloccg: bad size");
                panic("realloccg: bad size");
+       }
        if (u.u_uid != 0 &&
            fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
              fs->fs_dsize * fs->fs_minfree / 100)
                goto nospace;
        if (u.u_uid != 0 &&
            fs->fs_cstotal.cs_nbfree * fs->fs_frag + fs->fs_cstotal.cs_nffree <
              fs->fs_dsize * fs->fs_minfree / 100)
                goto nospace;
-       if (bprev == 0)
+       if (bprev == 0) {
+               printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n",
+                   ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt);
                panic("realloccg: bad bprev");
                panic("realloccg: bad bprev");
+       }
+#ifdef QUOTA
+       if (chkdq(ip, (long)((unsigned)(nsize-osize)/DEV_BSIZE), 0))
+               return(NULL);
+#endif
        cg = dtog(fs, bprev);
        bno = fragextend(ip, cg, (long)bprev, osize, nsize);
        if (bno != 0) {
        cg = dtog(fs, bprev);
        bno = fragextend(ip, cg, (long)bprev, osize, nsize);
        if (bno != 0) {
-               bp = bread(ip->i_dev, fsbtodb(fs, bno), osize);
-               if (bp->b_flags & B_ERROR) {
-                       brelse(bp);
-                       return (NULL);
-               }
-               bp->b_bcount = nsize;
-               blkclr(bp->b_un.b_addr + osize, nsize - osize);
+               do {
+                       bp = bread(ip->i_dev, fsbtodb(fs, bno), osize);
+                       if (bp->b_flags & B_ERROR) {
+                               brelse(bp);
+                               return (NULL);
+                       }
+               } while (brealloc(bp, nsize) == 0);
+               bp->b_flags |= B_DONE;
+               bzero(bp->b_un.b_addr + osize, nsize - osize);
                return (bp);
        }
        if (bpref >= fs->fs_size)
                bpref = 0;
        bno = (daddr_t)hashalloc(ip, cg, (long)bpref, nsize, alloccg);
                return (bp);
        }
        if (bpref >= fs->fs_size)
                bpref = 0;
        bno = (daddr_t)hashalloc(ip, cg, (long)bpref, nsize, alloccg);
-       if (bno != 0) {
-               /*
-                * make a new copy
-                */
+       if (bno > 0) {
                obp = bread(ip->i_dev, fsbtodb(fs, bprev), osize);
                if (obp->b_flags & B_ERROR) {
                        brelse(obp);
                        return (NULL);
                }
                bp = getblk(ip->i_dev, fsbtodb(fs, bno), nsize);
                obp = bread(ip->i_dev, fsbtodb(fs, bprev), osize);
                if (obp->b_flags & B_ERROR) {
                        brelse(obp);
                        return (NULL);
                }
                bp = getblk(ip->i_dev, fsbtodb(fs, bno), nsize);
-               cp = bp->b_un.b_addr;
-               bp->b_un.b_addr = obp->b_un.b_addr;
-               obp->b_un.b_addr = cp;
-               obp->b_flags |= B_INVAL;
+               bcopy(obp->b_un.b_addr, bp->b_un.b_addr, osize);
+               bzero(bp->b_un.b_addr + osize, nsize - osize);
                brelse(obp);
                fre(ip, bprev, (off_t)osize);
                brelse(obp);
                fre(ip, bprev, (off_t)osize);
-               blkclr(bp->b_un.b_addr + osize, nsize - osize);
                return (bp);
        }
 nospace:
                return (bp);
        }
 nospace:
@@ -185,6 +195,10 @@ ialloc(pip, ipref, mode)
        fs = pip->i_fs;
        if (fs->fs_cstotal.cs_nifree == 0)
                goto noinodes;
        fs = pip->i_fs;
        if (fs->fs_cstotal.cs_nifree == 0)
                goto noinodes;
+#ifdef QUOTA
+       if (chkiq(pip->i_dev, NULL, u.u_uid, 0))
+               return(NULL);
+#endif
        if (ipref >= fs->fs_ncg * fs->fs_ipg)
                ipref = 0;
        cg = itog(fs, ipref);
        if (ipref >= fs->fs_ncg * fs->fs_ipg)
                ipref = 0;
        cg = itog(fs, ipref);
@@ -196,8 +210,11 @@ ialloc(pip, ipref, mode)
                ifree(ip, ino, 0);
                return (NULL);
        }
                ifree(ip, ino, 0);
                return (NULL);
        }
-       if (ip->i_mode)
+       if (ip->i_mode) {
+               printf("mode = 0%o, inum = %d, fs = %s\n",
+                   ip->i_mode, ip->i_number, fs->fs_fsmnt);
                panic("ialloc: dup alloc");
                panic("ialloc: dup alloc");
+       }
        return (ip);
 noinodes:
        fserr(fs, "out of inodes");
        return (ip);
 noinodes:
        fserr(fs, "out of inodes");
@@ -347,6 +364,7 @@ fragextend(ip, cg, bprev, osize, nsize)
                brelse(bp);
                return (NULL);
        }
                brelse(bp);
                return (NULL);
        }
+       cgp->cg_time = time.tv_sec;
        bno = dtogd(fs, bprev);
        for (i = numfrags(fs, osize); i < frags; i++)
                if (isclr(cgp->cg_free, bno + i)) {
        bno = dtogd(fs, bprev);
        for (i = numfrags(fs, osize); i < frags; i++)
                if (isclr(cgp->cg_free, bno + i)) {
@@ -405,6 +423,7 @@ alloccg(ip, cg, bpref, size)
                brelse(bp);
                return (NULL);
        }
                brelse(bp);
                return (NULL);
        }
+       cgp->cg_time = time.tv_sec;
        if (size == fs->fs_bsize) {
                bno = alloccgblk(fs, cgp, bpref);
                bdwrite(bp);
        if (size == fs->fs_bsize) {
                bno = alloccgblk(fs, cgp, bpref);
                bdwrite(bp);
@@ -441,7 +460,7 @@ alloccg(ip, cg, bpref, size)
                return (bno);
        }
        bno = mapsearch(fs, cgp, bpref, allocsiz);
                return (bno);
        }
        bno = mapsearch(fs, cgp, bpref, allocsiz);
-       if (bno == -1)
+       if (bno < 0)
                return (NULL);
        for (i = 0; i < frags; i++)
                clrbit(cgp->cg_free, bno + i);
                return (NULL);
        for (i = 0; i < frags; i++)
                clrbit(cgp->cg_free, bno + i);
@@ -486,10 +505,14 @@ alloccgblk(fs, cgp, bpref)
        /*
         * if the requested block is available, use it
         */
        /*
         * if the requested block is available, use it
         */
+/*
+ * disallow sequential layout.
+ *
        if (isblock(fs, cgp->cg_free, bpref/fs->fs_frag)) {
                bno = bpref;
                goto gotit;
        }
        if (isblock(fs, cgp->cg_free, bpref/fs->fs_frag)) {
                bno = bpref;
                goto gotit;
        }
+ */
        /*
         * check for a block available on the same cylinder
         */
        /*
         * check for a block available on the same cylinder
         */
@@ -541,8 +564,11 @@ alloccgblk(fs, cgp, bpref)
                 */
                pos = cylno % fs->fs_cpc;
                bno = (cylno - pos) * fs->fs_spc / NSPB(fs);
                 */
                pos = cylno % fs->fs_cpc;
                bno = (cylno - pos) * fs->fs_spc / NSPB(fs);
-               if (fs->fs_postbl[pos][i] == -1)
+               if (fs->fs_postbl[pos][i] == -1) {
+                       printf("pos = %d, i = %d, fs = %s\n",
+                           pos, i, fs->fs_fsmnt);
                        panic("alloccgblk: cyl groups corrupted");
                        panic("alloccgblk: cyl groups corrupted");
+               }
                for (i = fs->fs_postbl[pos][i];; ) {
                        if (isblock(fs, cgp->cg_free, bno + i)) {
                                bno = (bno + i) * fs->fs_frag;
                for (i = fs->fs_postbl[pos][i];; ) {
                        if (isblock(fs, cgp->cg_free, bno + i)) {
                                bno = (bno + i) * fs->fs_frag;
@@ -553,6 +579,7 @@ alloccgblk(fs, cgp, bpref)
                                break;
                        i += delta;
                }
                                break;
                        i += delta;
                }
+               printf("pos = %d, i = %d, fs = %s\n", pos, i, fs->fs_fsmnt);
                panic("alloccgblk: can't find blk in cyl");
        }
 norot:
                panic("alloccgblk: can't find blk in cyl");
        }
 norot:
@@ -561,7 +588,7 @@ norot:
         * available one in this cylinder group.
         */
        bno = mapsearch(fs, cgp, bpref, fs->fs_frag);
         * available one in this cylinder group.
         */
        bno = mapsearch(fs, cgp, bpref, fs->fs_frag);
-       if (bno == -1)
+       if (bno < 0)
                return (NULL);
        cgp->cg_rotor = bno;
 gotit:
                return (NULL);
        cgp->cg_rotor = bno;
 gotit:
@@ -606,6 +633,7 @@ ialloccg(ip, cg, ipref, mode)
                brelse(bp);
                return (NULL);
        }
                brelse(bp);
                return (NULL);
        }
+       cgp->cg_time = time.tv_sec;
        if (ipref) {
                ipref %= fs->fs_ipg;
                if (isclr(cgp->cg_iused, ipref))
        if (ipref) {
                ipref %= fs->fs_ipg;
                if (isclr(cgp->cg_iused, ipref))
@@ -657,21 +685,30 @@ fre(ip, bno, size)
        register int i;
 
        fs = ip->i_fs;
        register int i;
 
        fs = ip->i_fs;
-       if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0)
+       if ((unsigned)size > fs->fs_bsize || fragoff(fs, size) != 0) {
+               printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n",
+                   ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt);
                panic("free: bad size");
                panic("free: bad size");
+       }
        cg = dtog(fs, bno);
        cg = dtog(fs, bno);
-       if (badblock(fs, bno))
+       if (badblock(fs, bno)) {
+               printf("bad block %d, ino %d\n", bno, ip->i_number);
                return;
                return;
+       }
        bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
        cgp = bp->b_un.b_cg;
        if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) {
                brelse(bp);
                return;
        }
        bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
        cgp = bp->b_un.b_cg;
        if (bp->b_flags & B_ERROR || cgp->cg_magic != CG_MAGIC) {
                brelse(bp);
                return;
        }
+       cgp->cg_time = time.tv_sec;
        bno = dtogd(fs, bno);
        if (size == fs->fs_bsize) {
        bno = dtogd(fs, bno);
        if (size == fs->fs_bsize) {
-               if (isblock(fs, cgp->cg_free, bno/fs->fs_frag))
+               if (isblock(fs, cgp->cg_free, bno/fs->fs_frag)) {
+                       printf("dev = 0x%x, block = %d, fs = %s\n",
+                           ip->i_dev, bno, fs->fs_fsmnt);
                        panic("free: freeing free block");
                        panic("free: freeing free block");
+               }
                setblock(fs, cgp->cg_free, bno/fs->fs_frag);
                cgp->cg_cs.cs_nbfree++;
                fs->fs_cstotal.cs_nbfree++;
                setblock(fs, cgp->cg_free, bno/fs->fs_frag);
                cgp->cg_cs.cs_nbfree++;
                fs->fs_cstotal.cs_nbfree++;
@@ -691,8 +728,11 @@ fre(ip, bno, size)
                 */
                frags = numfrags(fs, size);
                for (i = 0; i < frags; i++) {
                 */
                frags = numfrags(fs, size);
                for (i = 0; i < frags; i++) {
-                       if (isset(cgp->cg_free, bno + i))
+                       if (isset(cgp->cg_free, bno + i)) {
+                               printf("dev = 0x%x, block = %d, fs = %s\n",
+                                   ip->i_dev, bno + i, fs->fs_fsmnt);
                                panic("free: freeing free frag");
                                panic("free: freeing free frag");
+                       }
                        setbit(cgp->cg_free, bno + i);
                }
                cgp->cg_cs.cs_nffree += i;
                        setbit(cgp->cg_free, bno + i);
                }
                cgp->cg_cs.cs_nffree += i;
@@ -738,8 +778,11 @@ ifree(ip, ino, mode)
        int cg;
 
        fs = ip->i_fs;
        int cg;
 
        fs = ip->i_fs;
-       if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg)
+       if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg) {
+               printf("dev = 0x%x, ino = %d, fs = %s\n",
+                   ip->i_dev, ino, fs->fs_fsmnt);
                panic("ifree: range");
                panic("ifree: range");
+       }
        cg = itog(fs, ino);
        bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
        cgp = bp->b_un.b_cg;
        cg = itog(fs, ino);
        bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), fs->fs_bsize);
        cgp = bp->b_un.b_cg;
@@ -747,9 +790,13 @@ ifree(ip, ino, mode)
                brelse(bp);
                return;
        }
                brelse(bp);
                return;
        }
+       cgp->cg_time = time.tv_sec;
        ino %= fs->fs_ipg;
        ino %= fs->fs_ipg;
-       if (isclr(cgp->cg_iused, ino))
+       if (isclr(cgp->cg_iused, ino)) {
+               printf("dev = 0x%x, ino = %d, fs = %s\n",
+                   ip->i_dev, ino, fs->fs_fsmnt);
                panic("ifree: freeing free inode");
                panic("ifree: freeing free inode");
+       }
        clrbit(cgp->cg_iused, ino);
        cgp->cg_cs.cs_nifree++;
        fs->fs_cstotal.cs_nifree++;
        clrbit(cgp->cg_iused, ino);
        cgp->cg_cs.cs_nifree++;
        fs->fs_cstotal.cs_nifree++;
@@ -797,6 +844,8 @@ mapsearch(fs, cgp, bpref, allocsiz)
                loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
                        1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
                if (loc == 0) {
                loc = scanc(len, &cgp->cg_free[start], fragtbl[fs->fs_frag],
                        1 << (allocsiz - 1 + (fs->fs_frag % NBBY)));
                if (loc == 0) {
+                       printf("start = %d, len = %d, fs = %s\n",
+                           start, len, fs->fs_fsmnt);
                        panic("alloccg: map corrupted");
                        return (-1);
                }
                        panic("alloccg: map corrupted");
                        return (-1);
                }
@@ -819,6 +868,7 @@ mapsearch(fs, cgp, bpref, allocsiz)
                        subfield <<= 1;
                }
        }
                        subfield <<= 1;
                }
        }
+       printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt);
        panic("alloccg: block not in map");
        return (-1);
 }
        panic("alloccg: block not in map");
        return (-1);
 }
@@ -866,6 +916,7 @@ badblock(fs, bn)
 {
 
        if ((unsigned)bn >= fs->fs_size) {
 {
 
        if ((unsigned)bn >= fs->fs_size) {
+               printf("bad block %d, ", bn);
                fserr(fs, "bad block");
                return (1);
        }
                fserr(fs, "bad block");
                return (1);
        }
@@ -892,10 +943,13 @@ getfs(dev)
                if (mp->m_bufp == NULL || mp->m_dev != dev)
                        continue;
                fs = mp->m_bufp->b_un.b_fs;
                if (mp->m_bufp == NULL || mp->m_dev != dev)
                        continue;
                fs = mp->m_bufp->b_un.b_fs;
-               if (fs->fs_magic != FS_MAGIC)
+               if (fs->fs_magic != FS_MAGIC) {
+                       printf("dev = 0x%x, fs = %s\n", dev, fs->fs_fsmnt);
                        panic("getfs: bad magic");
                        panic("getfs: bad magic");
+               }
                return (fs);
        }
                return (fs);
        }
+       printf("dev = 0x%x\n", dev);
        panic("getfs: no fs");
        return (NULL);
 }
        panic("getfs: no fs");
        return (NULL);
 }
@@ -968,23 +1022,13 @@ update(flag)
                fs = mp->m_bufp->b_un.b_fs;
                if (fs->fs_fmod == 0)
                        continue;
                fs = mp->m_bufp->b_un.b_fs;
                if (fs->fs_fmod == 0)
                        continue;
-               if (fs->fs_ronly != 0)
+               if (fs->fs_ronly != 0) {                /* ### */
+                       printf("fs = %s\n", fs->fs_fsmnt);
                        panic("update: rofs mod");
                        panic("update: rofs mod");
-               bp = getblk(mp->m_dev, SBLOCK, SBSIZE);
-               if (bp->b_un.b_fs != fs || fs->fs_magic != FS_MAGIC)
-                       panic("update: bad b_fs");
-               fs->fs_fmod = 0;
-               fs->fs_time = time;
-               bwrite(bp);
-               blks = howmany(fs->fs_cssize, fs->fs_fsize);
-               for (i = 0; i < blks; i += fs->fs_frag) {
-                       bp = getblk(mp->m_dev,
-                           fsbtodb(fs, fs->fs_csaddr + i),
-                           blks - i < fs->fs_frag ? 
-                               (blks - i) * fs->fs_fsize :
-                               fs->fs_bsize);
-                       bwrite(bp);
                }
                }
+               fs->fs_fmod = 0;
+               fs->fs_time = time.tv_sec;
+               sbupdate(mp);
        }
        /*
         * Write back each (modified) inode.
        }
        /*
         * Write back each (modified) inode.
@@ -994,7 +1038,7 @@ update(flag)
                        continue;
                ip->i_flag |= ILOCK;
                ip->i_count++;
                        continue;
                ip->i_flag |= ILOCK;
                ip->i_count++;
-               iupdat(ip, &time, &time, 0);
+               iupdat(ip, &time.tv_sec, &time.tv_sec, 0);
                iput(ip);
        }
        updlock = 0;
                iput(ip);
        }
        updlock = 0;