BSD 4_4 release
[unix-history] / usr / src / sys / ufs / ffs / ffs_alloc.c
index c5cfe2c..5bc3787 100644 (file)
@@ -1,10 +1,36 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 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.
  *
  *
- *     @(#)ffs_alloc.c 7.32 (Berkeley) %G%
+ * 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.
+ *
+ *     @(#)ffs_alloc.c 8.1 (Berkeley) 6/11/93
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 #include <sys/buf.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
 #include <sys/buf.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
+#include <sys/mount.h>
 #include <sys/kernel.h>
 #include <sys/syslog.h>
 
 #include <sys/kernel.h>
 #include <sys/syslog.h>
 
+#include <vm/vm.h>
+
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
 
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
 
@@ -229,17 +258,8 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp)
        bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request,
            (u_long (*)())ffs_alloccg);
        if (bno > 0) {
        bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request,
            (u_long (*)())ffs_alloccg);
        if (bno > 0) {
-#ifdef SECSIZE
-               obp = bread(ip->i_dev, fsbtodb(fs, bprev), osize,
-                   fs->fs_dbsize);
-#else SECSIZE
-               count = howmany(osize, CLBYTES);
-               for (i = 0; i < count; i++)
-#ifdef SECSIZE
-                       munhash(ip->i_dev, bn + i * CLBYTES / fs->fs_dbsize);
-#else SECSIZE
-                       munhash(ip->i_dev, bn + i * CLBYTES / DEV_BSIZE);
-#endif SECSIZE
+               bp->b_blkno = fsbtodb(fs, bno);
+               (void) vnode_pager_uncache(ITOV(ip));
                ffs_blkfree(ip, bprev, (long)osize);
                if (nsize < request)
                        ffs_blkfree(ip, bno + numfrags(fs, nsize),
                ffs_blkfree(ip, bprev, (long)osize);
                if (nsize < request)
                        ffs_blkfree(ip, bno + numfrags(fs, nsize),
@@ -283,19 +303,23 @@ nospace:
  *   2) quadradically rehash into other cylinder groups, until an
  *      available inode is located.
  */
  *   2) quadradically rehash into other cylinder groups, until an
  *      available inode is located.
  */
-ffs_valloc(pvp, mode, cred, vpp)
-       register struct vnode *pvp;
-       int mode;
-       struct ucred *cred;
-       struct vnode **vpp;
+ffs_valloc(ap)
+       struct vop_valloc_args /* {
+               struct vnode *a_pvp;
+               int a_mode;
+               struct ucred *a_cred;
+               struct vnode **a_vpp;
+       } */ *ap;
 {
 {
+       register struct vnode *pvp = ap->a_pvp;
        register struct inode *pip;
        register struct fs *fs;
        register struct inode *ip;
        register struct inode *pip;
        register struct fs *fs;
        register struct inode *ip;
+       mode_t mode = ap->a_mode;
        ino_t ino, ipref;
        int cg, error;
        
        ino_t ino, ipref;
        int cg, error;
        
-       *vpp = NULL;
+       *ap->a_vpp = NULL;
        pip = VTOI(pvp);
        fs = pip->i_fs;
        if (fs->fs_cstotal.cs_nifree == 0)
        pip = VTOI(pvp);
        fs = pip->i_fs;
        if (fs->fs_cstotal.cs_nifree == 0)
@@ -311,12 +335,12 @@ ffs_valloc(pvp, mode, cred, vpp)
        ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, ffs_ialloccg);
        if (ino == 0)
                goto noinodes;
        ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, ffs_ialloccg);
        if (ino == 0)
                goto noinodes;
-       error = ffs_vget(pvp->v_mount, ino, vpp);
+       error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp);
        if (error) {
        if (error) {
-               ffs_vfree(pvp, ino, mode);
+               VOP_VFREE(pvp, ino, mode);
                return (error);
        }
                return (error);
        }
-       ip = VTOI(*vpp);
+       ip = VTOI(*ap->a_vpp);
        if (ip->i_mode) {
                printf("mode = 0%o, inum = %d, fs = %s\n",
                    ip->i_mode, ip->i_number, fs->fs_fsmnt);
        if (ip->i_mode) {
                printf("mode = 0%o, inum = %d, fs = %s\n",
                    ip->i_mode, ip->i_number, fs->fs_fsmnt);
@@ -336,7 +360,7 @@ ffs_valloc(pvp, mode, cred, vpp)
        ip->i_gen = nextgennumber;
        return (0);
 noinodes:
        ip->i_gen = nextgennumber;
        return (0);
 noinodes:
-       ffs_fserr(fs, cred->cr_uid, "out of inodes");
+       ffs_fserr(fs, ap->a_cred->cr_uid, "out of inodes");
        uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
        return (ENOSPC);
 }
        uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);
        return (ENOSPC);
 }
@@ -439,9 +463,8 @@ ffs_blkpref(ip, lbn, indx, bap)
         * requested rotationally delayed by fs_rotdelay milliseconds.
         */
        nextblk = bap[indx - 1] + fs->fs_frag;
         * requested rotationally delayed by fs_rotdelay milliseconds.
         */
        nextblk = bap[indx - 1] + fs->fs_frag;
-       if (indx > fs->fs_maxcontig &&
-           bap[indx - fs->fs_maxcontig] + blkstofrags(fs, fs->fs_maxcontig)
-           != nextblk)
+       if (indx < fs->fs_maxcontig || bap[indx - fs->fs_maxcontig] +
+           blkstofrags(fs, fs->fs_maxcontig) != nextblk)
                return (nextblk);
        if (fs->fs_rotdelay != 0)
                /*
                return (nextblk);
        if (fs->fs_rotdelay != 0)
                /*
@@ -540,17 +563,12 @@ ffs_fragextend(ip, cg, bprev, osize, nsize)
                /* cannot extend across a block boundary */
                return (NULL);
        }
                /* cannot extend across a block boundary */
                return (NULL);
        }
-#ifdef SECSIZE
-       bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
-           fs->fs_dbsize);
-#else SECSIZE
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
-#endif SECSIZE
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
@@ -608,17 +626,12 @@ ffs_alloccg(ip, cg, bpref, size)
        fs = ip->i_fs;
        if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
                return (NULL);
        fs = ip->i_fs;
        if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
                return (NULL);
-#ifdef SECSIZE
-       bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
-           fs->fs_dbsize);
-#else SECSIZE
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
-#endif SECSIZE
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp) ||
            (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) {
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp) ||
            (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) {
@@ -723,10 +736,13 @@ ffs_alloccgblk(fs, cgp, bpref)
                goto norot;
        if (fs->fs_cpc == 0) {
                /*
                goto norot;
        if (fs->fs_cpc == 0) {
                /*
-                * block layout info is not available, so just have
-                * to take any block in this cylinder.
+                * Block layout information is not available.
+                * Leaving bpref unchanged means we take the
+                * next available free block following the one 
+                * we just allocated. Hopefully this will at
+                * least hit a track cache on drives of unknown
+                * geometry (e.g. SCSI).
                 */
                 */
-               bpref = howmany(fs->fs_spc * cylno, NSPF(fs));
                goto norot;
        }
        /*
                goto norot;
        }
        /*
@@ -814,17 +830,12 @@ ffs_ialloccg(ip, cg, ipref, mode)
        fs = ip->i_fs;
        if (fs->fs_cs(fs, cg).cs_nifree == 0)
                return (NULL);
        fs = ip->i_fs;
        if (fs->fs_cs(fs, cg).cs_nifree == 0)
                return (NULL);
-#ifdef SECSIZE
-       bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
-           fs->fs_dbsize);
-#else SECSIZE
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return (NULL);
        }
-#endif SECSIZE
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) {
                brelse(bp);
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) {
                brelse(bp);
@@ -907,17 +918,12 @@ ffs_blkfree(ip, bno, size)
                ffs_fserr(fs, ip->i_uid, "bad block");
                return;
        }
                ffs_fserr(fs, ip->i_uid, "bad block");
                return;
        }
-#ifdef SECSIZE
-       bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
-           fs->fs_dbsize);
-#else SECSIZE
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return;
        }
        error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
                return;
        }
-#endif SECSIZE
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
@@ -990,39 +996,37 @@ ffs_blkfree(ip, bno, size)
  *
  * The specified inode is placed back in the free map.
  */
  *
  * The specified inode is placed back in the free map.
  */
-void
-ffs_vfree(pvp, ino, mode)
-       struct vnode *pvp;
-       ino_t ino;
-       int mode;
+int
+ffs_vfree(ap)
+       struct vop_vfree_args /* {
+               struct vnode *a_pvp;
+               ino_t a_ino;
+               int a_mode;
+       } */ *ap;
 {
        register struct fs *fs;
        register struct cg *cgp;
        register struct inode *pip;
 {
        register struct fs *fs;
        register struct cg *cgp;
        register struct inode *pip;
+       ino_t ino = ap->a_ino;
        struct buf *bp;
        int error, cg;
 
        struct buf *bp;
        int error, cg;
 
-       pip = VTOI(pvp);
+       pip = VTOI(ap->a_pvp);
        fs = pip->i_fs;
        if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg)
                panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n",
                    pip->i_dev, ino, fs->fs_fsmnt);
        cg = itog(fs, ino);
        fs = pip->i_fs;
        if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg)
                panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n",
                    pip->i_dev, ino, fs->fs_fsmnt);
        cg = itog(fs, ino);
-#ifdef SECSIZE
-       bp = bread(ip->i_dev, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
-           fs->fs_dbsize);
-#else SECSIZE
        error = bread(pip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
        error = bread(pip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
                (int)fs->fs_cgsize, NOCRED, &bp);
        if (error) {
                brelse(bp);
-               return;
+               return (0);
        }
        }
-#endif SECSIZE
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
        cgp = bp->b_un.b_cg;
        if (!cg_chkmagic(cgp)) {
                brelse(bp);
-               return;
+               return (0);
        }
        cgp->cg_time = time.tv_sec;
        ino %= fs->fs_ipg;
        }
        cgp->cg_time = time.tv_sec;
        ino %= fs->fs_ipg;
@@ -1038,13 +1042,14 @@ ffs_vfree(pvp, ino, mode)
        cgp->cg_cs.cs_nifree++;
        fs->fs_cstotal.cs_nifree++;
        fs->fs_cs(fs, cg).cs_nifree++;
        cgp->cg_cs.cs_nifree++;
        fs->fs_cstotal.cs_nifree++;
        fs->fs_cs(fs, cg).cs_nifree++;
-       if ((mode & IFMT) == IFDIR) {
+       if ((ap->a_mode & IFMT) == IFDIR) {
                cgp->cg_cs.cs_ndir--;
                fs->fs_cstotal.cs_ndir--;
                fs->fs_cs(fs, cg).cs_ndir--;
        }
        fs->fs_fmod = 1;
        bdwrite(bp);
                cgp->cg_cs.cs_ndir--;
                fs->fs_cstotal.cs_ndir--;
                fs->fs_cs(fs, cg).cs_ndir--;
        }
        fs->fs_fmod = 1;
        bdwrite(bp);
+       return (0);
 }
 
 /*
 }
 
 /*