BSD 4_3 release
[unix-history] / usr / src / sys / sys / ufs_subr.c
index 5b42957..43d5a1e 100644 (file)
@@ -1,23 +1,27 @@
-/*     ufs_subr.c      6.1     83/07/29        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)ufs_subr.c  7.1 (Berkeley) 6/5/86
+ */
 
 #ifdef KERNEL
 
 #ifdef KERNEL
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/mount.h"
-#include "../h/fs.h"
-#include "../h/conf.h"
-#include "../h/buf.h"
-#include "../h/inode.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/quota.h"
-#include "../h/kernel.h"
+#include "param.h"
+#include "systm.h"
+#include "mount.h"
+#include "fs.h"
+#include "buf.h"
+#include "inode.h"
+#include "dir.h"
+#include "user.h"
+#include "quota.h"
+#include "kernel.h"
 #else
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/mount.h>
 #include <sys/fs.h>
 #else
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/mount.h>
 #include <sys/fs.h>
-#include <sys/conf.h>
 #include <sys/buf.h>
 #include <sys/inode.h>
 #include <sys/dir.h>
 #include <sys/buf.h>
 #include <sys/inode.h>
 #include <sys/dir.h>
@@ -68,7 +72,8 @@ update()
         * Write back each (modified) inode.
         */
        for (ip = inode; ip < inodeNINODE; ip++) {
         * Write back each (modified) inode.
         */
        for (ip = inode; ip < inodeNINODE; ip++) {
-               if ((ip->i_flag & ILOCKED) != 0 || ip->i_count == 0)
+               if ((ip->i_flag & ILOCKED) != 0 || ip->i_count == 0 ||
+                   (ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0)
                        continue;
                ip->i_flag |= ILOCKED;
                ip->i_count++;
                        continue;
                ip->i_flag |= ILOCKED;
                ip->i_count++;
@@ -85,23 +90,54 @@ update()
 
 /*
  * Flush all the blocks associated with an inode.
 
 /*
  * Flush all the blocks associated with an inode.
- * Note that we make a more stringent check of
- * writing out any block in the buffer pool that may
- * overlap the inode. This brings the inode up to
- * date with recent mods to the cooked device.
+ * There are two strategies based on the size of the file;
+ * large files are those with more than (nbuf / 2) blocks.
+ * Large files
+ *     Walk through the buffer pool and push any dirty pages
+ *     associated with the device on which the file resides.
+ * Small files
+ *     Look up each block in the file to see if it is in the 
+ *     buffer pool writing any that are found to disk.
+ *     Note that we make a more stringent check of
+ *     writing out any block in the buffer pool that may
+ *     overlap the inode. This brings the inode up to
+ *     date with recent mods to the cooked device.
  */
 syncip(ip)
        register struct inode *ip;
 {
        register struct fs *fs;
  */
 syncip(ip)
        register struct inode *ip;
 {
        register struct fs *fs;
+       register struct buf *bp;
+       struct buf *lastbufp;
        long lbn, lastlbn;
        long lbn, lastlbn;
+       int s;
        daddr_t blkno;
 
        fs = ip->i_fs;
        lastlbn = howmany(ip->i_size, fs->fs_bsize);
        daddr_t blkno;
 
        fs = ip->i_fs;
        lastlbn = howmany(ip->i_size, fs->fs_bsize);
-       for (lbn = 0; lbn < lastlbn; lbn++) {
-               blkno = fsbtodb(fs, bmap(ip, lbn, B_READ));
-               blkflush(ip->i_dev, blkno, blksize(fs, ip, lbn));
+       if (lastlbn < nbuf / 2) {
+               for (lbn = 0; lbn < lastlbn; lbn++) {
+                       blkno = fsbtodb(fs, bmap(ip, lbn, B_READ));
+                       blkflush(ip->i_dev, blkno, blksize(fs, ip, lbn));
+               }
+       } else {
+               lastbufp = &buf[nbuf];
+               for (bp = buf; bp < lastbufp; bp++) {
+                       if (bp->b_dev != ip->i_dev ||
+                           (bp->b_flags & B_DELWRI) == 0)
+                               continue;
+                       s = splbio();
+                       if (bp->b_flags & B_BUSY) {
+                               bp->b_flags |= B_WANTED;
+                               sleep((caddr_t)bp, PRIBIO+1);
+                               splx(s);
+                               bp--;
+                               continue;
+                       }
+                       splx(s);
+                       notavail(bp);
+                       bwrite(bp);
+               }
        }
        ip->i_flag |= ICHG;
        iupdat(ip, &time, &time, 1);
        }
        ip->i_flag |= ICHG;
        iupdat(ip, &time, &time, 1);
@@ -176,7 +212,7 @@ isblock(fs, cp, h)
 {
        unsigned char mask;
 
 {
        unsigned char mask;
 
-       switch (fs->fs_frag) {
+       switch ((int)fs->fs_frag) {
        case 8:
                return (cp[h] == 0xff);
        case 4:
        case 8:
                return (cp[h] == 0xff);
        case 4:
@@ -203,7 +239,7 @@ clrblock(fs, cp, h)
        daddr_t h;
 {
 
        daddr_t h;
 {
 
-       switch ((fs)->fs_frag) {
+       switch ((int)fs->fs_frag) {
        case 8:
                cp[h] = 0;
                return;
        case 8:
                cp[h] = 0;
                return;
@@ -230,7 +266,7 @@ setblock(fs, cp, h)
        daddr_t h;
 {
 
        daddr_t h;
 {
 
-       switch (fs->fs_frag) {
+       switch ((int)fs->fs_frag) {
 
        case 8:
                cp[h] = 0xff;
 
        case 8:
                cp[h] = 0xff;
@@ -322,7 +358,7 @@ bufstats()
                count = 0;
                for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
                        counts[j] = 0;
                count = 0;
                for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
                        counts[j] = 0;
-               s = spl6();
+               s = splbio();
                for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) {
                        counts[dp->b_bufsize/CLBYTES]++;
                        count++;
                for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) {
                        counts[dp->b_bufsize/CLBYTES]++;
                        count++;
@@ -336,3 +372,47 @@ bufstats()
        }
 }
 #endif
        }
 }
 #endif
+
+#if !defined(vax) || defined(VAX630)
+/*
+ * C definitions of special vax instructions.
+ */
+scanc(size, cp, table, mask)
+       u_int size;
+       register u_char *cp, table[];
+       register u_char mask;
+{
+       register u_char *end = &cp[size];
+
+       while (cp < end && (table[*cp] & mask) == 0)
+               cp++;
+       return (end - cp);
+}
+
+#endif
+#if !defined(vax)
+
+skpc(mask, size, cp)
+       register u_char mask;
+       u_int size;
+       register u_char *cp;
+{
+       register u_char *end = &cp[size];
+
+       while (cp < end && *cp == mask)
+               cp++;
+       return (end - cp);
+}
+
+locc(mask, size, cp)
+       register u_char mask;
+       u_int size;
+       register u_char *cp;
+{
+       register u_char *end = &cp[size];
+
+       while (cp < end && *cp != mask)
+               cp++;
+       return (end - cp);
+}
+#endif vax