BSD 4_3 release
[unix-history] / usr / src / sys / sys / ufs_bio.c
index 6c761e3..e90bb16 100644 (file)
@@ -1,17 +1,23 @@
-/*     ufs_bio.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_bio.c   7.1 (Berkeley) 6/5/86
+ */
 
 #include "../machine/pte.h"
 
 
 #include "../machine/pte.h"
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/buf.h"
-#include "../h/conf.h"
-#include "../h/proc.h"
-#include "../h/seg.h"
-#include "../h/vm.h"
-#include "../h/trace.h"
+#include "param.h"
+#include "systm.h"
+#include "dir.h"
+#include "user.h"
+#include "buf.h"
+#include "conf.h"
+#include "proc.h"
+#include "seg.h"
+#include "vm.h"
+#include "trace.h"
 
 /*
  * Read in (if necessary) the block and return a buffer pointer.
 
 /*
  * Read in (if necessary) the block and return a buffer pointer.
@@ -28,17 +34,17 @@ bread(dev, blkno, size)
                panic("bread: size 0");
        bp = getblk(dev, blkno, size);
        if (bp->b_flags&B_DONE) {
                panic("bread: size 0");
        bp = getblk(dev, blkno, size);
        if (bp->b_flags&B_DONE) {
-               trace(TR_BREADHIT, dev, blkno);
-               return(bp);
+               trace(TR_BREADHIT, pack(dev, size), blkno);
+               return (bp);
        }
        bp->b_flags |= B_READ;
        if (bp->b_bcount > bp->b_bufsize)
                panic("bread");
        (*bdevsw[major(dev)].d_strategy)(bp);
        }
        bp->b_flags |= B_READ;
        if (bp->b_bcount > bp->b_bufsize)
                panic("bread");
        (*bdevsw[major(dev)].d_strategy)(bp);
-       trace(TR_BREADMISS, dev, blkno);
+       trace(TR_BREADMISS, pack(dev, size), blkno);
        u.u_ru.ru_inblock++;            /* pay for read */
        biowait(bp);
        u.u_ru.ru_inblock++;            /* pay for read */
        biowait(bp);
-       return(bp);
+       return (bp);
 }
 
 /*
 }
 
 /*
@@ -66,10 +72,10 @@ breada(dev, blkno, size, rablkno, rabsize)
                        if (bp->b_bcount > bp->b_bufsize)
                                panic("breada");
                        (*bdevsw[major(dev)].d_strategy)(bp);
                        if (bp->b_bcount > bp->b_bufsize)
                                panic("breada");
                        (*bdevsw[major(dev)].d_strategy)(bp);
-                       trace(TR_BREADMISS, dev, blkno);
+                       trace(TR_BREADMISS, pack(dev, size), blkno);
                        u.u_ru.ru_inblock++;            /* pay for read */
                } else
                        u.u_ru.ru_inblock++;            /* pay for read */
                } else
-                       trace(TR_BREADHIT, dev, blkno);
+                       trace(TR_BREADHIT, pack(dev, size), blkno);
        }
 
        /*
        }
 
        /*
@@ -80,13 +86,13 @@ breada(dev, blkno, size, rablkno, rabsize)
                rabp = getblk(dev, rablkno, rabsize);
                if (rabp->b_flags & B_DONE) {
                        brelse(rabp);
                rabp = getblk(dev, rablkno, rabsize);
                if (rabp->b_flags & B_DONE) {
                        brelse(rabp);
-                       trace(TR_BREADHITRA, dev, blkno);
+                       trace(TR_BREADHITRA, pack(dev, rabsize), blkno);
                } else {
                        rabp->b_flags |= B_READ|B_ASYNC;
                        if (rabp->b_bcount > rabp->b_bufsize)
                                panic("breadrabp");
                        (*bdevsw[major(dev)].d_strategy)(rabp);
                } else {
                        rabp->b_flags |= B_READ|B_ASYNC;
                        if (rabp->b_bcount > rabp->b_bufsize)
                                panic("breadrabp");
                        (*bdevsw[major(dev)].d_strategy)(rabp);
-                       trace(TR_BREADMISSRA, dev, rablock);
+                       trace(TR_BREADMISSRA, pack(dev, rabsize), rablock);
                        u.u_ru.ru_inblock++;            /* pay in advance */
                }
        }
                        u.u_ru.ru_inblock++;            /* pay in advance */
                }
        }
@@ -115,7 +121,7 @@ bwrite(bp)
        bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
        if ((flag&B_DELWRI) == 0)
                u.u_ru.ru_oublock++;            /* noone paid yet */
        bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI);
        if ((flag&B_DELWRI) == 0)
                u.u_ru.ru_oublock++;            /* noone paid yet */
-       trace(TR_BWRITE, bp->b_dev, bp->b_blkno);
+       trace(TR_BWRITE, pack(bp->b_dev, bp->b_bcount), bp->b_blkno);
        if (bp->b_bcount > bp->b_bufsize)
                panic("bwrite");
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
        if (bp->b_bcount > bp->b_bufsize)
                panic("bwrite");
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
@@ -176,6 +182,7 @@ brelse(bp)
        register struct buf *flist;
        register s;
 
        register struct buf *flist;
        register s;
 
+       trace(TR_BRELSE, pack(bp->b_dev, bp->b_bufsize), bp->b_blkno);
        /*
         * If someone's waiting for the buffer, or
         * is waiting for a buffer wake 'em up.
        /*
         * If someone's waiting for the buffer, or
         * is waiting for a buffer wake 'em up.
@@ -195,7 +202,7 @@ brelse(bp)
        /*
         * Stick the buffer back on a free list.
         */
        /*
         * Stick the buffer back on a free list.
         */
-       s = spl6();
+       s = splbio();
        if (bp->b_bufsize <= 0) {
                /* block has no buffer ... put at front of unused buffer list */
                flist = &bfreelist[BQ_EMPTY];
        if (bp->b_bufsize <= 0) {
                /* block has no buffer ... put at front of unused buffer list */
                flist = &bfreelist[BQ_EMPTY];
@@ -266,8 +273,18 @@ getblk(dev, blkno, size)
        register struct buf *bp, *dp;
        int s;
 
        register struct buf *bp, *dp;
        int s;
 
-       if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT)) /* XXX */
-               blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1);
+       if (size > MAXBSIZE)
+               panic("getblk: size too big");
+       /*
+        * To prevent overflow of 32-bit ints when converting block
+        * numbers to byte offsets, blknos > 2^32 / DEV_BSIZE are set
+        * to the maximum number that can be converted to a byte offset
+        * without overflow. This is historic code; what bug it fixed,
+        * or whether it is still a reasonable thing to do is open to
+        * dispute. mkm 9/85
+        */
+       if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-DEV_BSHIFT))
+               blkno = 1 << ((sizeof(int)*NBBY-DEV_BSHIFT) + 1);
        /*
         * Search the cache for the block.  If we hit, but
         * the buffer is in use for i/o, then we wait until
        /*
         * Search the cache for the block.  If we hit, but
         * the buffer is in use for i/o, then we wait until
@@ -279,7 +296,7 @@ loop:
                if (bp->b_blkno != blkno || bp->b_dev != dev ||
                    bp->b_flags&B_INVAL)
                        continue;
                if (bp->b_blkno != blkno || bp->b_dev != dev ||
                    bp->b_flags&B_INVAL)
                        continue;
-               s = spl6();
+               s = splbio();
                if (bp->b_flags&B_BUSY) {
                        bp->b_flags |= B_WANTED;
                        sleep((caddr_t)bp, PRIBIO+1);
                if (bp->b_flags&B_BUSY) {
                        bp->b_flags |= B_WANTED;
                        sleep((caddr_t)bp, PRIBIO+1);
@@ -288,10 +305,10 @@ loop:
                }
                splx(s);
                notavail(bp);
                }
                splx(s);
                notavail(bp);
-               if (brealloc(bp, size) == 0)
+               if (bp->b_bcount != size && brealloc(bp, size) == 0)
                        goto loop;
                bp->b_flags |= B_CACHE;
                        goto loop;
                bp->b_flags |= B_CACHE;
-               return(bp);
+               return (bp);
        }
        if (major(dev) >= nblkdev)
                panic("blkdev");
        }
        if (major(dev) >= nblkdev)
                panic("blkdev");
@@ -304,7 +321,7 @@ loop:
        bp->b_error = 0;
        if (brealloc(bp, size) == 0)
                goto loop;
        bp->b_error = 0;
        if (brealloc(bp, size) == 0)
                goto loop;
-       return(bp);
+       return (bp);
 }
 
 /*
 }
 
 /*
@@ -317,6 +334,8 @@ geteblk(size)
 {
        register struct buf *bp, *flist;
 
 {
        register struct buf *bp, *flist;
 
+       if (size > MAXBSIZE)
+               panic("geteblk: size too big");
 loop:
        bp = getnewbuf();
        bp->b_flags |= B_INVAL;
 loop:
        bp = getnewbuf();
        bp->b_flags |= B_INVAL;
@@ -328,7 +347,7 @@ loop:
        bp->b_error = 0;
        if (brealloc(bp, size) == 0)
                goto loop;
        bp->b_error = 0;
        if (brealloc(bp, size) == 0)
                goto loop;
-       return(bp);
+       return (bp);
 }
 
 /*
 }
 
 /*
@@ -363,6 +382,7 @@ brealloc(bp, size)
        if (bp->b_dev == NODEV)
                return (allocbuf(bp, size));
 
        if (bp->b_dev == NODEV)
                return (allocbuf(bp, size));
 
+       trace(TR_BREALLOC, pack(bp->b_dev, size), bp->b_blkno);
        /*
         * Search cache for any buffers that overlap the one that we
         * are trying to allocate. Overlapping buffers must be marked
        /*
         * Search cache for any buffers that overlap the one that we
         * are trying to allocate. Overlapping buffers must be marked
@@ -382,7 +402,7 @@ loop:
                if (ep->b_bcount == 0 || ep->b_blkno > last ||
                    ep->b_blkno + btodb(ep->b_bcount) <= start)
                        continue;
                if (ep->b_bcount == 0 || ep->b_blkno > last ||
                    ep->b_blkno + btodb(ep->b_bcount) <= start)
                        continue;
-               s = spl6();
+               s = splbio();
                if (ep->b_flags&B_BUSY) {
                        ep->b_flags |= B_WANTED;
                        sleep((caddr_t)ep, PRIBIO+1);
                if (ep->b_flags&B_BUSY) {
                        ep->b_flags |= B_WANTED;
                        sleep((caddr_t)ep, PRIBIO+1);
@@ -413,7 +433,7 @@ getnewbuf()
        int s;
 
 loop:
        int s;
 
 loop:
-       s = spl6();
+       s = splbio();
        for (dp = &bfreelist[BQ_AGE]; dp > bfreelist; dp--)
                if (dp->av_forw != dp)
                        break;
        for (dp = &bfreelist[BQ_AGE]; dp > bfreelist; dp--)
                if (dp->av_forw != dp)
                        break;
@@ -431,7 +451,7 @@ loop:
                bwrite(bp);
                goto loop;
        }
                bwrite(bp);
                goto loop;
        }
-       trace(TR_BRELSE, bp->b_dev, bp->b_blkno);
+       trace(TR_BRELSE, pack(bp->b_dev, bp->b_bufsize), bp->b_blkno);
        bp->b_flags = B_BUSY;
        return (bp);
 }
        bp->b_flags = B_BUSY;
        return (bp);
 }
@@ -445,7 +465,7 @@ biowait(bp)
 {
        int s;
 
 {
        int s;
 
-       s = spl6();
+       s = splbio();
        while ((bp->b_flags&B_DONE)==0)
                sleep((caddr_t)bp, PRIBIO);
        splx(s);
        while ((bp->b_flags&B_DONE)==0)
                sleep((caddr_t)bp, PRIBIO);
        splx(s);
@@ -503,7 +523,7 @@ loop:
                if (ep->b_bcount == 0 || ep->b_blkno > last ||
                    ep->b_blkno + btodb(ep->b_bcount) <= start)
                        continue;
                if (ep->b_bcount == 0 || ep->b_blkno > last ||
                    ep->b_blkno + btodb(ep->b_bcount) <= start)
                        continue;
-               s = spl6();
+               s = splbio();
                if (ep->b_flags&B_BUSY) {
                        ep->b_flags |= B_WANTED;
                        sleep((caddr_t)ep, PRIBIO+1);
                if (ep->b_flags&B_BUSY) {
                        ep->b_flags |= B_WANTED;
                        sleep((caddr_t)ep, PRIBIO+1);
@@ -534,7 +554,7 @@ bflush(dev)
        int s;
 
 loop:
        int s;
 
 loop:
-       s = spl6();
+       s = splbio();
        for (flist = bfreelist; flist < &bfreelist[BQ_EMPTY]; flist++)
        for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
                if ((bp->b_flags & B_DELWRI) == 0)
        for (flist = bfreelist; flist < &bfreelist[BQ_EMPTY]; flist++)
        for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
                if ((bp->b_flags & B_DELWRI) == 0)
@@ -552,9 +572,7 @@ loop:
 
 /*
  * Pick up the device's error number and pass it to the user;
 
 /*
  * Pick up the device's error number and pass it to the user;
- * if there is an error but the number is 0 set a generalized
- * code.  Actually the latter is always true because devices
- * don't yet return specific errors.
+ * if there is an error but the number is 0 set a generalized code.
  */
 geterror(bp)
        register struct buf *bp;
  */
 geterror(bp)
        register struct buf *bp;