From ad30fb672122d5a4daba6642b8a6075e44df7af5 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 20 Apr 1982 02:27:16 -0800 Subject: [PATCH] merge in the new file system SCCS-vsn: sys/kern/kern_physio.c 4.29 SCCS-vsn: sys/kern/vfs_bio.c 4.29 SCCS-vsn: sys/kern/vfs_cluster.c 4.29 SCCS-vsn: sys/sys/param.h 4.17 SCCS-vsn: sys/sys/buf.h 4.14 SCCS-vsn: sys/ufs/ffs/dir.h 4.3 SCCS-vsn: sys/ufs/ufs/dir.h 4.3 SCCS-vsn: sys/ufs/ffs/dinode.h 4.11 SCCS-vsn: sys/ufs/ffs/inode.h 4.11 SCCS-vsn: sys/ufs/ufs/dinode.h 4.11 SCCS-vsn: sys/ufs/ufs/inode.h 4.11 SCCS-vsn: sys/sys/user.h 4.12 SCCS-vsn: sys/sys/stat.h 4.4 SCCS-vsn: sys/sys/types.h 4.4 SCCS-vsn: sys/ufs/ffs/fs.h 2.4 --- usr/src/sys/kern/kern_physio.c | 161 +++++++++++++++++++++++++-------- usr/src/sys/kern/vfs_bio.c | 161 +++++++++++++++++++++++++-------- usr/src/sys/kern/vfs_cluster.c | 161 +++++++++++++++++++++++++-------- usr/src/sys/sys/buf.h | 9 +- usr/src/sys/sys/param.h | 111 +++++++++++------------ usr/src/sys/sys/stat.h | 3 +- usr/src/sys/sys/types.h | 6 +- usr/src/sys/sys/user.h | 7 +- usr/src/sys/ufs/ffs/dinode.h | 118 +++++++++++++++--------- usr/src/sys/ufs/ffs/dir.h | 61 +++++++++++-- usr/src/sys/ufs/ffs/fs.h | 2 +- usr/src/sys/ufs/ffs/inode.h | 118 +++++++++++++++--------- usr/src/sys/ufs/ufs/dinode.h | 118 +++++++++++++++--------- usr/src/sys/ufs/ufs/dir.h | 61 +++++++++++-- usr/src/sys/ufs/ufs/inode.h | 118 +++++++++++++++--------- 15 files changed, 851 insertions(+), 364 deletions(-) diff --git a/usr/src/sys/kern/kern_physio.c b/usr/src/sys/kern/kern_physio.c index 2b5a39be39..4bd60bb9ff 100644 --- a/usr/src/sys/kern/kern_physio.c +++ b/usr/src/sys/kern/kern_physio.c @@ -1,4 +1,6 @@ -/* kern_physio.c 4.28 82/03/31 */ +/* kern_physio.c 4.29 82/04/19 */ + +/* merged into kernel: @(#)bio.c 2.3 4/8/82 */ #include "../h/param.h" #include "../h/systm.h" @@ -38,9 +40,10 @@ struct buf bfreelist[BQUEUES]; struct buf bswlist, *bclnlist; #define BUFHSZ 63 +#define RND (MAXBSIZE/DEV_BSIZE) struct bufhd bufhash[BUFHSZ]; #define BUFHASH(dev, dblkno) \ - ((struct buf *)&bufhash[((int)(dev)+(int)(dblkno)) % BUFHSZ]) + ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND)) % BUFHSZ]) /* * Initialize hash links for buffers. @@ -97,13 +100,14 @@ int *swpf; * Read in (if necessary) the block and return a buffer pointer. */ struct buf * -bread(dev, blkno) -dev_t dev; -daddr_t blkno; +bread(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp; - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if (bp->b_flags&B_DONE) { #ifdef TRACE trace(TR_BREADHIT, dev, blkno); @@ -114,7 +118,6 @@ daddr_t blkno; return(bp); } bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -132,18 +135,18 @@ daddr_t blkno; * read-ahead block (which is not allocated to the caller) */ struct buf * -breada(dev, blkno, rablkno) -dev_t dev; -daddr_t blkno, rablkno; +breada(dev, blkno, rablkno, size) + dev_t dev; + daddr_t blkno, rablkno; + int size; { register struct buf *bp, *rabp; bp = NULL; if (!incore(dev, blkno)) { - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if ((bp->b_flags&B_DONE) == 0) { bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -159,7 +162,7 @@ daddr_t blkno, rablkno; #endif } if (rablkno && !incore(dev, rablkno)) { - rabp = getblk(dev, rablkno); + rabp = getblk(dev, rablkno, size); if (rabp->b_flags & B_DONE) { brelse(rabp); #ifdef TRACE @@ -167,7 +170,6 @@ daddr_t blkno, rablkno; #endif } else { rabp->b_flags |= B_READ|B_ASYNC; - rabp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(rabp); #ifdef TRACE trace(TR_BREADMISSRA, dev, rablock); @@ -179,7 +181,7 @@ daddr_t blkno, rablkno; } } if(bp == NULL) - return(bread(dev, blkno)); + return(bread(dev, blkno, size)); iowait(bp); return(bp); } @@ -195,7 +197,6 @@ register struct buf *bp; flag = bp->b_flags; bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI | B_AGE); - bp->b_bcount = BSIZE; #ifdef DISKMON io_info.nwrite++; #endif @@ -303,24 +304,24 @@ daddr_t blkno; { register struct buf *bp; register struct buf *dp; - register int dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) - if (bp->b_blkno == dblkno && bp->b_dev == dev && + if (bp->b_blkno == blkno && bp->b_dev == dev && !(bp->b_flags & B_INVAL)) return (1); return (0); } struct buf * -baddr(dev, blkno) -dev_t dev; -daddr_t blkno; +baddr(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { if (incore(dev, blkno)) - return (bread(dev, blkno)); + return (bread(dev, blkno, size)); return (0); } @@ -334,12 +335,12 @@ daddr_t blkno; * want to lower the ipl back to 0. */ struct buf * -getblk(dev, blkno) -dev_t dev; -daddr_t blkno; +getblk(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp, *dp, *ep; - register int dblkno = fsbtodb(blkno); #ifdef DISKMON register int i; #endif @@ -347,11 +348,10 @@ daddr_t blkno; if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT)) blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1); - dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); loop: for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) { - if (bp->b_blkno != dblkno || bp->b_dev != dev || + if (bp->b_blkno != blkno || bp->b_dev != dev || bp->b_flags&B_INVAL) continue; s = spl6(); @@ -373,6 +373,7 @@ daddr_t blkno; io_info.bufcount[i]++; #endif notavail(bp); + brealloc(bp, size); bp->b_flags |= B_CACHE; return(bp); } @@ -400,6 +401,7 @@ daddr_t blkno; trace(TR_BRELSE, bp->b_dev, bp->b_blkno); #endif bp->b_flags = B_BUSY; + bfree(bp); bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; @@ -407,7 +409,8 @@ daddr_t blkno; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; - bp->b_blkno = dblkno; + bp->b_blkno = blkno; + brealloc(bp, size); return(bp); } @@ -416,7 +419,8 @@ daddr_t blkno; * not assigned to any particular device */ struct buf * -geteblk() +geteblk(size) + int size; { register struct buf *bp, *dp; int s; @@ -450,15 +454,96 @@ loop: dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = (dev_t)NODEV; + bp->b_bcount = size; return(bp); } +/* + * Allocate space associated with a buffer. + */ +brealloc(bp, size) + register struct buf *bp; + int size; +{ + daddr_t start, last; + register struct buf *ep; + struct buf *dp; + int s; + + /* + * First need to make sure that all overlaping previous I/O + * is dispatched with. + */ + if (size == bp->b_bcount) + return; + if (size < bp->b_bcount) { + bp->b_bcount = size; + return; + } + start = bp->b_blkno + (bp->b_bcount / DEV_BSIZE); + last = bp->b_blkno + (size / DEV_BSIZE) - 1; + if (bp->b_bcount == 0) { + start++; + if (start == last) + goto allocit; + } + dp = BUFHASH(bp->b_dev, bp->b_blkno); +loop: + (void) spl0(); + for (ep = dp->b_forw; ep != dp; ep = ep->b_forw) { + if (ep->b_blkno < start || ep->b_blkno > last || + ep->b_dev != bp->b_dev || ep->b_flags&B_INVAL) + continue; + s = spl6(); + if (ep->b_flags&B_BUSY) { + ep->b_flags |= B_WANTED; + sleep((caddr_t)ep, PRIBIO+1); + splx(s); + goto loop; + } + (void) spl0(); + /* + * What we would really like to do is kill this + * I/O since it is now useless. We cannot do that + * so we force it to complete, so that it cannot + * over-write our useful data later. + */ + if (ep->b_flags & B_DELWRI) { + notavail(ep); + ep->b_flags |= B_ASYNC; + bwrite(ep); + goto loop; + } + } +allocit: + /* + * Here the buffer is already available, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = size; +} + +/* + * Release space associated with a buffer. + */ +bfree(bp) + struct buf *bp; +{ + /* + * Here the buffer does not change, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = 0; +} + /* * Wait for I/O completion on the buffer; return errors * to the user. */ iowait(bp) -register struct buf *bp; + register struct buf *bp; { int s; @@ -530,13 +615,13 @@ register struct buf *bp; * Zero the core associated with a buffer. */ clrbuf(bp) -struct buf *bp; + struct buf *bp; { - register *p; - register c; + register int *p; + register int c; p = bp->b_un.b_words; - c = BSIZE/sizeof(int); + c = bp->b_bcount/sizeof(int); do *p++ = 0; while (--c); @@ -673,6 +758,7 @@ swkill(p, rout) * on dev (or NODEV for all) * are flushed out. * (from umount and update) + * (and temporarily pagein) */ bflush(dev) dev_t dev; @@ -770,6 +856,7 @@ struct buf *bp; bp->b_bcount = 63 * 1024; } + /* * 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 diff --git a/usr/src/sys/kern/vfs_bio.c b/usr/src/sys/kern/vfs_bio.c index 342efeaf57..7798d783f1 100644 --- a/usr/src/sys/kern/vfs_bio.c +++ b/usr/src/sys/kern/vfs_bio.c @@ -1,4 +1,6 @@ -/* vfs_bio.c 4.28 82/03/31 */ +/* vfs_bio.c 4.29 82/04/19 */ + +/* merged into kernel: @(#)bio.c 2.3 4/8/82 */ #include "../h/param.h" #include "../h/systm.h" @@ -38,9 +40,10 @@ struct buf bfreelist[BQUEUES]; struct buf bswlist, *bclnlist; #define BUFHSZ 63 +#define RND (MAXBSIZE/DEV_BSIZE) struct bufhd bufhash[BUFHSZ]; #define BUFHASH(dev, dblkno) \ - ((struct buf *)&bufhash[((int)(dev)+(int)(dblkno)) % BUFHSZ]) + ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND)) % BUFHSZ]) /* * Initialize hash links for buffers. @@ -97,13 +100,14 @@ int *swpf; * Read in (if necessary) the block and return a buffer pointer. */ struct buf * -bread(dev, blkno) -dev_t dev; -daddr_t blkno; +bread(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp; - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if (bp->b_flags&B_DONE) { #ifdef TRACE trace(TR_BREADHIT, dev, blkno); @@ -114,7 +118,6 @@ daddr_t blkno; return(bp); } bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -132,18 +135,18 @@ daddr_t blkno; * read-ahead block (which is not allocated to the caller) */ struct buf * -breada(dev, blkno, rablkno) -dev_t dev; -daddr_t blkno, rablkno; +breada(dev, blkno, rablkno, size) + dev_t dev; + daddr_t blkno, rablkno; + int size; { register struct buf *bp, *rabp; bp = NULL; if (!incore(dev, blkno)) { - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if ((bp->b_flags&B_DONE) == 0) { bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -159,7 +162,7 @@ daddr_t blkno, rablkno; #endif } if (rablkno && !incore(dev, rablkno)) { - rabp = getblk(dev, rablkno); + rabp = getblk(dev, rablkno, size); if (rabp->b_flags & B_DONE) { brelse(rabp); #ifdef TRACE @@ -167,7 +170,6 @@ daddr_t blkno, rablkno; #endif } else { rabp->b_flags |= B_READ|B_ASYNC; - rabp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(rabp); #ifdef TRACE trace(TR_BREADMISSRA, dev, rablock); @@ -179,7 +181,7 @@ daddr_t blkno, rablkno; } } if(bp == NULL) - return(bread(dev, blkno)); + return(bread(dev, blkno, size)); iowait(bp); return(bp); } @@ -195,7 +197,6 @@ register struct buf *bp; flag = bp->b_flags; bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI | B_AGE); - bp->b_bcount = BSIZE; #ifdef DISKMON io_info.nwrite++; #endif @@ -303,24 +304,24 @@ daddr_t blkno; { register struct buf *bp; register struct buf *dp; - register int dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) - if (bp->b_blkno == dblkno && bp->b_dev == dev && + if (bp->b_blkno == blkno && bp->b_dev == dev && !(bp->b_flags & B_INVAL)) return (1); return (0); } struct buf * -baddr(dev, blkno) -dev_t dev; -daddr_t blkno; +baddr(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { if (incore(dev, blkno)) - return (bread(dev, blkno)); + return (bread(dev, blkno, size)); return (0); } @@ -334,12 +335,12 @@ daddr_t blkno; * want to lower the ipl back to 0. */ struct buf * -getblk(dev, blkno) -dev_t dev; -daddr_t blkno; +getblk(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp, *dp, *ep; - register int dblkno = fsbtodb(blkno); #ifdef DISKMON register int i; #endif @@ -347,11 +348,10 @@ daddr_t blkno; if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT)) blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1); - dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); loop: for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) { - if (bp->b_blkno != dblkno || bp->b_dev != dev || + if (bp->b_blkno != blkno || bp->b_dev != dev || bp->b_flags&B_INVAL) continue; s = spl6(); @@ -373,6 +373,7 @@ daddr_t blkno; io_info.bufcount[i]++; #endif notavail(bp); + brealloc(bp, size); bp->b_flags |= B_CACHE; return(bp); } @@ -400,6 +401,7 @@ daddr_t blkno; trace(TR_BRELSE, bp->b_dev, bp->b_blkno); #endif bp->b_flags = B_BUSY; + bfree(bp); bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; @@ -407,7 +409,8 @@ daddr_t blkno; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; - bp->b_blkno = dblkno; + bp->b_blkno = blkno; + brealloc(bp, size); return(bp); } @@ -416,7 +419,8 @@ daddr_t blkno; * not assigned to any particular device */ struct buf * -geteblk() +geteblk(size) + int size; { register struct buf *bp, *dp; int s; @@ -450,15 +454,96 @@ loop: dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = (dev_t)NODEV; + bp->b_bcount = size; return(bp); } +/* + * Allocate space associated with a buffer. + */ +brealloc(bp, size) + register struct buf *bp; + int size; +{ + daddr_t start, last; + register struct buf *ep; + struct buf *dp; + int s; + + /* + * First need to make sure that all overlaping previous I/O + * is dispatched with. + */ + if (size == bp->b_bcount) + return; + if (size < bp->b_bcount) { + bp->b_bcount = size; + return; + } + start = bp->b_blkno + (bp->b_bcount / DEV_BSIZE); + last = bp->b_blkno + (size / DEV_BSIZE) - 1; + if (bp->b_bcount == 0) { + start++; + if (start == last) + goto allocit; + } + dp = BUFHASH(bp->b_dev, bp->b_blkno); +loop: + (void) spl0(); + for (ep = dp->b_forw; ep != dp; ep = ep->b_forw) { + if (ep->b_blkno < start || ep->b_blkno > last || + ep->b_dev != bp->b_dev || ep->b_flags&B_INVAL) + continue; + s = spl6(); + if (ep->b_flags&B_BUSY) { + ep->b_flags |= B_WANTED; + sleep((caddr_t)ep, PRIBIO+1); + splx(s); + goto loop; + } + (void) spl0(); + /* + * What we would really like to do is kill this + * I/O since it is now useless. We cannot do that + * so we force it to complete, so that it cannot + * over-write our useful data later. + */ + if (ep->b_flags & B_DELWRI) { + notavail(ep); + ep->b_flags |= B_ASYNC; + bwrite(ep); + goto loop; + } + } +allocit: + /* + * Here the buffer is already available, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = size; +} + +/* + * Release space associated with a buffer. + */ +bfree(bp) + struct buf *bp; +{ + /* + * Here the buffer does not change, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = 0; +} + /* * Wait for I/O completion on the buffer; return errors * to the user. */ iowait(bp) -register struct buf *bp; + register struct buf *bp; { int s; @@ -530,13 +615,13 @@ register struct buf *bp; * Zero the core associated with a buffer. */ clrbuf(bp) -struct buf *bp; + struct buf *bp; { - register *p; - register c; + register int *p; + register int c; p = bp->b_un.b_words; - c = BSIZE/sizeof(int); + c = bp->b_bcount/sizeof(int); do *p++ = 0; while (--c); @@ -673,6 +758,7 @@ swkill(p, rout) * on dev (or NODEV for all) * are flushed out. * (from umount and update) + * (and temporarily pagein) */ bflush(dev) dev_t dev; @@ -770,6 +856,7 @@ struct buf *bp; bp->b_bcount = 63 * 1024; } + /* * 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 diff --git a/usr/src/sys/kern/vfs_cluster.c b/usr/src/sys/kern/vfs_cluster.c index 2a209f1dec..18c21b61c7 100644 --- a/usr/src/sys/kern/vfs_cluster.c +++ b/usr/src/sys/kern/vfs_cluster.c @@ -1,4 +1,6 @@ -/* vfs_cluster.c 4.28 82/03/31 */ +/* vfs_cluster.c 4.29 82/04/19 */ + +/* merged into kernel: @(#)bio.c 2.3 4/8/82 */ #include "../h/param.h" #include "../h/systm.h" @@ -38,9 +40,10 @@ struct buf bfreelist[BQUEUES]; struct buf bswlist, *bclnlist; #define BUFHSZ 63 +#define RND (MAXBSIZE/DEV_BSIZE) struct bufhd bufhash[BUFHSZ]; #define BUFHASH(dev, dblkno) \ - ((struct buf *)&bufhash[((int)(dev)+(int)(dblkno)) % BUFHSZ]) + ((struct buf *)&bufhash[((int)(dev)+(((int)(dblkno))/RND)) % BUFHSZ]) /* * Initialize hash links for buffers. @@ -97,13 +100,14 @@ int *swpf; * Read in (if necessary) the block and return a buffer pointer. */ struct buf * -bread(dev, blkno) -dev_t dev; -daddr_t blkno; +bread(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp; - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if (bp->b_flags&B_DONE) { #ifdef TRACE trace(TR_BREADHIT, dev, blkno); @@ -114,7 +118,6 @@ daddr_t blkno; return(bp); } bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -132,18 +135,18 @@ daddr_t blkno; * read-ahead block (which is not allocated to the caller) */ struct buf * -breada(dev, blkno, rablkno) -dev_t dev; -daddr_t blkno, rablkno; +breada(dev, blkno, rablkno, size) + dev_t dev; + daddr_t blkno, rablkno; + int size; { register struct buf *bp, *rabp; bp = NULL; if (!incore(dev, blkno)) { - bp = getblk(dev, blkno); + bp = getblk(dev, blkno, size); if ((bp->b_flags&B_DONE) == 0) { bp->b_flags |= B_READ; - bp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(bp); #ifdef TRACE trace(TR_BREADMISS, dev, blkno); @@ -159,7 +162,7 @@ daddr_t blkno, rablkno; #endif } if (rablkno && !incore(dev, rablkno)) { - rabp = getblk(dev, rablkno); + rabp = getblk(dev, rablkno, size); if (rabp->b_flags & B_DONE) { brelse(rabp); #ifdef TRACE @@ -167,7 +170,6 @@ daddr_t blkno, rablkno; #endif } else { rabp->b_flags |= B_READ|B_ASYNC; - rabp->b_bcount = BSIZE; (*bdevsw[major(dev)].d_strategy)(rabp); #ifdef TRACE trace(TR_BREADMISSRA, dev, rablock); @@ -179,7 +181,7 @@ daddr_t blkno, rablkno; } } if(bp == NULL) - return(bread(dev, blkno)); + return(bread(dev, blkno, size)); iowait(bp); return(bp); } @@ -195,7 +197,6 @@ register struct buf *bp; flag = bp->b_flags; bp->b_flags &= ~(B_READ | B_DONE | B_ERROR | B_DELWRI | B_AGE); - bp->b_bcount = BSIZE; #ifdef DISKMON io_info.nwrite++; #endif @@ -303,24 +304,24 @@ daddr_t blkno; { register struct buf *bp; register struct buf *dp; - register int dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) - if (bp->b_blkno == dblkno && bp->b_dev == dev && + if (bp->b_blkno == blkno && bp->b_dev == dev && !(bp->b_flags & B_INVAL)) return (1); return (0); } struct buf * -baddr(dev, blkno) -dev_t dev; -daddr_t blkno; +baddr(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { if (incore(dev, blkno)) - return (bread(dev, blkno)); + return (bread(dev, blkno, size)); return (0); } @@ -334,12 +335,12 @@ daddr_t blkno; * want to lower the ipl back to 0. */ struct buf * -getblk(dev, blkno) -dev_t dev; -daddr_t blkno; +getblk(dev, blkno, size) + dev_t dev; + daddr_t blkno; + int size; { register struct buf *bp, *dp, *ep; - register int dblkno = fsbtodb(blkno); #ifdef DISKMON register int i; #endif @@ -347,11 +348,10 @@ daddr_t blkno; if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT)) blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1); - dblkno = fsbtodb(blkno); - dp = BUFHASH(dev, dblkno); + dp = BUFHASH(dev, blkno); loop: for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) { - if (bp->b_blkno != dblkno || bp->b_dev != dev || + if (bp->b_blkno != blkno || bp->b_dev != dev || bp->b_flags&B_INVAL) continue; s = spl6(); @@ -373,6 +373,7 @@ daddr_t blkno; io_info.bufcount[i]++; #endif notavail(bp); + brealloc(bp, size); bp->b_flags |= B_CACHE; return(bp); } @@ -400,6 +401,7 @@ daddr_t blkno; trace(TR_BRELSE, bp->b_dev, bp->b_blkno); #endif bp->b_flags = B_BUSY; + bfree(bp); bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; @@ -407,7 +409,8 @@ daddr_t blkno; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; - bp->b_blkno = dblkno; + bp->b_blkno = blkno; + brealloc(bp, size); return(bp); } @@ -416,7 +419,8 @@ daddr_t blkno; * not assigned to any particular device */ struct buf * -geteblk() +geteblk(size) + int size; { register struct buf *bp, *dp; int s; @@ -450,15 +454,96 @@ loop: dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = (dev_t)NODEV; + bp->b_bcount = size; return(bp); } +/* + * Allocate space associated with a buffer. + */ +brealloc(bp, size) + register struct buf *bp; + int size; +{ + daddr_t start, last; + register struct buf *ep; + struct buf *dp; + int s; + + /* + * First need to make sure that all overlaping previous I/O + * is dispatched with. + */ + if (size == bp->b_bcount) + return; + if (size < bp->b_bcount) { + bp->b_bcount = size; + return; + } + start = bp->b_blkno + (bp->b_bcount / DEV_BSIZE); + last = bp->b_blkno + (size / DEV_BSIZE) - 1; + if (bp->b_bcount == 0) { + start++; + if (start == last) + goto allocit; + } + dp = BUFHASH(bp->b_dev, bp->b_blkno); +loop: + (void) spl0(); + for (ep = dp->b_forw; ep != dp; ep = ep->b_forw) { + if (ep->b_blkno < start || ep->b_blkno > last || + ep->b_dev != bp->b_dev || ep->b_flags&B_INVAL) + continue; + s = spl6(); + if (ep->b_flags&B_BUSY) { + ep->b_flags |= B_WANTED; + sleep((caddr_t)ep, PRIBIO+1); + splx(s); + goto loop; + } + (void) spl0(); + /* + * What we would really like to do is kill this + * I/O since it is now useless. We cannot do that + * so we force it to complete, so that it cannot + * over-write our useful data later. + */ + if (ep->b_flags & B_DELWRI) { + notavail(ep); + ep->b_flags |= B_ASYNC; + bwrite(ep); + goto loop; + } + } +allocit: + /* + * Here the buffer is already available, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = size; +} + +/* + * Release space associated with a buffer. + */ +bfree(bp) + struct buf *bp; +{ + /* + * Here the buffer does not change, so all we + * need to do is set the size. Someday a better memory + * management scheme will be implemented. + */ + bp->b_bcount = 0; +} + /* * Wait for I/O completion on the buffer; return errors * to the user. */ iowait(bp) -register struct buf *bp; + register struct buf *bp; { int s; @@ -530,13 +615,13 @@ register struct buf *bp; * Zero the core associated with a buffer. */ clrbuf(bp) -struct buf *bp; + struct buf *bp; { - register *p; - register c; + register int *p; + register int c; p = bp->b_un.b_words; - c = BSIZE/sizeof(int); + c = bp->b_bcount/sizeof(int); do *p++ = 0; while (--c); @@ -673,6 +758,7 @@ swkill(p, rout) * on dev (or NODEV for all) * are flushed out. * (from umount and update) + * (and temporarily pagein) */ bflush(dev) dev_t dev; @@ -770,6 +856,7 @@ struct buf *bp; bp->b_bcount = 63 * 1024; } + /* * 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 diff --git a/usr/src/sys/sys/buf.h b/usr/src/sys/sys/buf.h index 18c24b4d0f..b3ed1feec5 100644 --- a/usr/src/sys/sys/buf.h +++ b/usr/src/sys/sys/buf.h @@ -1,4 +1,6 @@ -/* buf.h 4.13 81/05/09 */ +/* buf.h 4.14 82/04/19 */ + +/* buf.h 2.1 3/25/82 */ /* * The header for buffers in the buffer pool and otherwise used @@ -45,7 +47,9 @@ struct buf union { caddr_t b_addr; /* low order core address */ int *b_words; /* words for clearing */ - struct filsys *b_filsys; /* superblocks */ + struct fs *b_fs; /* superblocks */ + struct csum *b_cs; /* superblock summary information */ + struct cg *b_cg; /* cylinder group block */ struct dinode *b_dino; /* ilist */ daddr_t *b_daddr; /* indirect block */ } b_un; @@ -74,6 +78,7 @@ struct buf bswlist; /* head of free swap header list */ struct buf *bclnlist; /* head of cleaned page list */ struct buf *alloc(); +struct buf *realloccg(); struct buf *baddr(); struct buf *getblk(); struct buf *geteblk(); diff --git a/usr/src/sys/sys/param.h b/usr/src/sys/sys/param.h index 8e41a51222..f5fa1e6efb 100644 --- a/usr/src/sys/sys/param.h +++ b/usr/src/sys/sys/param.h @@ -1,4 +1,6 @@ -/* param.h 4.16 82/03/30 */ +/* "@(#)param.h 2.1 3/25/82" */ + +/* param.h 4.17 82/04/19 */ /* * Tunable variables which do not usually vary per system. @@ -68,9 +70,6 @@ #define NULL 0 #define CMASK 0 /* default mask for file creation */ #define NODEV (dev_t)(-1) -#define ROOTINO ((ino_t)2) /* i number of all roots */ -#define SUPERB ((daddr_t)1) /* block number of the super block */ -#define DIRSIZ 14 /* max characters per directory */ #define NGRPS 256 /* max number groups */ /* @@ -95,66 +94,15 @@ /* round a number of clicks up to a whole cluster */ #define clrnd(i) (((i) + (CLSIZE-1)) &~ (CLSIZE-1)) -#define DEV_BSIZE 512 -#if CLSIZE==1 -#define BSIZE 512 /* size of secondary block (bytes) */ -#define INOPB 8 /* 8 inodes per block */ -#define BMASK 0777 /* BSIZE-1 */ -#define BSHIFT 9 /* LOG2(BSIZE) */ -#define NMASK 0177 /* NINDIR-1 */ -#define NSHIFT 7 /* LOG2(NINDIR) */ -#define NICINOD 100 /* number of superblock inodes */ -#define NICFREE 50 /* number of superblock free blocks */ - -#endif - -#if CLSIZE==2 -#define BSIZE 1024 -#define INOPB 16 -#define BMASK 01777 -#define BSHIFT 10 -#define NMASK 0377 -#define NSHIFT 8 -#define NICINOD 100 -#define NICFREE 178 -#endif - -#if CLSIZE==4 -#define BSIZE 2048 -#define INOPB 32 -#define BMASK 03777 -#define BSHIFT 11 -#define NMASK 0777 -#define NSHIFT 9 -#define NICINOD 100 -#define NICFREE 434 -#endif - #ifndef INTRLVE /* macros replacing interleaving functions */ #define dkblock(bp) ((bp)->b_blkno) #define dkunit(bp) (minor((bp)->b_dev) >> 3) #endif -/* inumber to disk address and inumber to disk offset */ -#define itod(x) ((daddr_t)((((unsigned)(x)+2*INOPB-1)/INOPB))) -#define itoo(x) ((int)(((x)+2*INOPB-1)%INOPB)) - -/* file system blocks to disk blocks and back */ -#define fsbtodb(b) ((b)*CLSIZE) -#define dbtofsb(b) ((b)/CLSIZE) - -#define NINDIR (BSIZE/sizeof(daddr_t)) - #define CBSIZE 28 /* number of chars in a clist block */ #define CROUND 0x1F /* clist rounding; sizeof(int *) + CBSIZE -1*/ -/* - * Macros for fast min/max - */ -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - /* * Some macros for units conversion */ @@ -186,6 +134,57 @@ #define BASEPRI(ps) (((ps) & PSL_IPL) != 0) /* - * Provide about n microseconds of delay + * File system parameters and macros. + * + * The file system is made out of blocks of at most MAXBSIZE units, + * with smaller units (fragments) only in the last direct block. + * MAXBSIZE primarily determines the size of buffers in the buffer + * pool. It may be made larger without any effect on existing + * file systems; however making it smaller make make some file + * systems unmountable. + * + * Note that the blocked devices are assumed to have DEV_BSIZE + * "sectors" and that fragments must be some multiple of this size. + */ +#define MAXBSIZE 8192 +#define DEV_BSIZE 512 +#define MAXFRAG 8 + +/* + * MAXPATHLEN defines the longest permissable path length + * after expanding symbolic links. It is used to allocate + * a temporary buffer from the buffer pool in which to do the + * name expansion, hence should be a power of two, and must + * be less than or equal to MAXBSIZE. + * MAXSYMLINKS defines the maximum number of symbolic links + * that may be expanded in a path name. It should be set high + * enough to allow all legitimate uses, but halt infinite loops + * reasonably quickly. + */ +#define MAXPATHLEN 1024 +#define MAXSYMLINKS 8 + +/* + * bit map related macros + */ +#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) + +/* + * Macros for fast min/max. + */ +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +/* + * Macros for counting and rounding. + */ +#define howmany(x, y) (((x)+((y)-1))/(y)) +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) + +/* + * Provide about n microseconds of delay. */ #define DELAY(n) { register int N = (n); while (--N > 0); } diff --git a/usr/src/sys/sys/stat.h b/usr/src/sys/sys/stat.h index dc00dcd944..ca2266dc00 100644 --- a/usr/src/sys/sys/stat.h +++ b/usr/src/sys/sys/stat.h @@ -1,4 +1,4 @@ -/* stat.h 4.3 82/02/27 */ +/* stat.h 4.4 82/04/19 */ struct stat { @@ -13,6 +13,7 @@ struct stat time_t st_atime; time_t st_mtime; time_t st_ctime; + long st_blksize; }; #define S_IFMT 0170000 /* type of file */ diff --git a/usr/src/sys/sys/types.h b/usr/src/sys/sys/types.h index a93486d457..4c657234d0 100644 --- a/usr/src/sys/sys/types.h +++ b/usr/src/sys/sys/types.h @@ -1,4 +1,6 @@ -/* types.h 4.3 81/10/17 */ +/* types.h 2.1 3/25/82 */ + +/* types.h 4.4 82/04/19 */ /* * Basic system types and major/minor device constructing/busting macros. @@ -23,7 +25,7 @@ typedef unsigned long u_long; typedef struct _physadr { int r[1]; } *physadr; typedef int daddr_t; typedef char * caddr_t; -typedef u_short ino_t; +typedef u_long ino_t; typedef int swblk_t; typedef int size_t; typedef int time_t; diff --git a/usr/src/sys/sys/user.h b/usr/src/sys/sys/user.h index 0b192adba8..19aa6ee8fc 100644 --- a/usr/src/sys/sys/user.h +++ b/usr/src/sys/sys/user.h @@ -1,4 +1,6 @@ -/* user.h 4.11 82/03/27 */ +/* @(#)user.h 2.1 3/25/82 */ + +/* user.h 4.12 82/04/19 */ #ifdef KERNEL #include "../h/pcb.h" @@ -55,7 +57,6 @@ struct user off_t u_offset; /* offset in file for IO */ struct inode *u_cdir; /* pointer to inode of current directory */ struct inode *u_rdir; /* root directory of current process */ - char u_dbuf[DIRSIZ]; /* current pathname component */ caddr_t u_dirp; /* pathname pointer */ struct direct u_dent; /* current directory entry */ struct inode *u_pdir; /* inode of parent directory of dirp */ @@ -100,7 +101,7 @@ struct user #define ux_unused Ux_A.Ux_unused #define ux_relflg Ux_A.Ux_relflg - char u_comm[DIRSIZ]; + char u_comm[MAXNAMLEN + 1]; time_t u_start; char u_acflag; short u_fpflag; /* unused now, will be later */ diff --git a/usr/src/sys/ufs/ffs/dinode.h b/usr/src/sys/ufs/ffs/dinode.h index 1f2d84962a..a9495b7a1d 100644 --- a/usr/src/sys/ufs/ffs/dinode.h +++ b/usr/src/sys/ufs/ffs/dinode.h @@ -1,52 +1,84 @@ -/* dinode.h 4.10 82/02/27 */ +/* dinode.h 4.11 82/04/19 */ + +/* inode.h 2.1 3/25/82 */ /* * The I node is the focus of all file activity in UNIX. * There is a unique inode allocated for each active file, * each current directory, each mounted-on file, text file, and the root. * An inode is 'named' by its dev/inumber pair. (iget/iget.c) - * Data, from mode on, is read in from permanent inode on volume. + * Data in icommon is read in from permanent inode on volume. */ -#define NADDR 13 + +#define NDADDR 8 /* direct addresses in inode */ +#define NIADDR 2 /* indirect addresses in inode */ struct inode { char i_flag; char i_count; /* reference count */ dev_t i_dev; /* device where inode resides */ ino_t i_number; /* i number, 1-to-1 with device address */ -/* begin read from disk */ - u_short i_mode; - short i_nlink; /* directory entries */ - short i_uid; /* owner */ - short i_gid; /* group of owner */ - off_t i_size; /* size of file */ + long i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct fs *i_fs; /* file sys associated with this inode */ union { - struct i_f { - daddr_t if_addr[NADDR]; /* if normal file/directory */ - daddr_t if_lastr; /* last read (read-ahead) */ - } i_f; - struct i_d { - daddr_t id_rdev; /* i_addr[0] */ - } i_d; - struct i_s { - struct socket *is_socket; - } i_s; -#define i_addr i_f.if_addr -#define i_lastr i_f.if_lastr -#define i_rdev i_d.id_rdev -#define i_socket i_s.is_socket + daddr_t if_lastr; /* last read (read-ahead) */ + struct socket *is_socket; } i_un; -/* end read from disk */ - short i_XXXXXX; /* ### */ -/* SHOULD USE POINTERS, NOT INDICES, FOR HAS CHAIN */ - short i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct icommon + { + u_short ic_mode; /* 0: mode and type of file */ + short ic_nlink; /* 2: number of links to file */ + short ic_uid; /* 4: owner's user id */ + short ic_gid; /* 6: owner's group id */ + off_t ic_size; /* 8: number of bytes in file */ + daddr_t ic_db[NDADDR]; /* 12: disk block addresses */ + daddr_t ic_ib[NIADDR]; /* 44: indirect blocks */ + time_t ic_atime; /* 52: time last accessed */ + time_t ic_mtime; /* 56: time last modified */ + time_t ic_ctime; /* 60: time created */ + } i_ic; }; +struct dinode { + union { + struct icommon di_icom; + char di_size[64]; + } di_un; +}; + +#define i_mode i_ic.ic_mode +#define i_nlink i_ic.ic_nlink +#define i_uid i_ic.ic_uid +#define i_gid i_ic.ic_gid +#define i_size i_ic.ic_size +#define i_db i_ic.ic_db +#define i_ib i_ic.ic_ib +#define i_atime i_ic.ic_atime +#define i_mtime i_ic.ic_mtime +#define i_ctime i_ic.ic_ctime +#define i_rdev i_ic.ic_db[0] +#define i_lastr i_un.if_lastr +#define i_socket is_socket + +#define di_ic di_un.di_icom +#define di_mode di_ic.ic_mode +#define di_nlink di_ic.ic_nlink +#define di_uid di_ic.ic_uid +#define di_gid di_ic.ic_gid +#define di_size di_ic.ic_size +#define di_db di_ic.ic_db +#define di_ib di_ic.ic_ib +#define di_atime di_ic.ic_atime +#define di_mtime di_ic.ic_mtime +#define di_ctime di_ic.ic_ctime +#define di_rdev di_ic.ic_db[0] + #ifdef KERNEL -struct inode *inode, *inodeNINODE; -int ninode; +extern struct inode *inode; /* The inode table itself */ +extern struct inode *inodeNINODE; /* The end of the inode table */ +extern int ninode; /* number of slots in the table */ -struct inode *rootdir; /* pointer to inode of root directory */ +struct inode *rootdir; /* pointer to inode of root directory */ struct inode *ialloc(); struct inode *ifind(); @@ -66,16 +98,16 @@ struct inode *namei(); #define ICHG 0100 /* inode has been changed */ /* modes */ -#define IFMT 0170000 /* type of file */ -#define IFCHR 0020000 /* character special */ -#define IFDIR 0040000 /* directory */ -#define IFBLK 0060000 /* block special */ -#define IFREG 0100000 /* regular */ -#define IFLNK 0120000 /* symbolic link */ -#define IFPORTAL 0140000 /* portal */ -#define ISUID 04000 /* set user id on execution */ -#define ISGID 02000 /* set group id on execution */ -#define ISVTX 01000 /* save swapped text even after use */ -#define IREAD 0400 /* read, write, execute permissions */ -#define IWRITE 0200 -#define IEXEC 0100 +#define IFMT 0170000 /* type of file */ +#define IFCHR 0020000 /* character special */ +#define IFDIR 0040000 /* directory */ +#define IFBLK 0060000 /* block special */ +#define IFREG 0100000 /* regular */ +#define IFLNK 0120000 /* symbolic link */ +#define IFPORTAL 0140000 /* portal */ +#define ISUID 04000 /* set user id on execution */ +#define ISGID 02000 /* set group id on execution */ +#define ISVTX 01000 /* save swapped text even after use */ +#define IREAD 0400 /* read, write, execute permissions */ +#define IWRITE 0200 +#define IEXEC 0100 diff --git a/usr/src/sys/ufs/ffs/dir.h b/usr/src/sys/ufs/ffs/dir.h index c978a72252..f815f6c637 100644 --- a/usr/src/sys/ufs/ffs/dir.h +++ b/usr/src/sys/ufs/ffs/dir.h @@ -1,10 +1,55 @@ -/* dir.h 4.2 81/02/19 */ +/* dir.h 4.3 82/04/19 */ -#ifndef DIRSIZ -#define DIRSIZ 14 -#endif -struct direct -{ - ino_t d_ino; - char d_name[DIRSIZ]; +/* @(#)ndir.h 4.4 3/30/82 */ + +/* + * This sets the "page size" for directories. + * Requirements are DEV_BSIZE <= DIRBLKSIZ <= MINBSIZE with + * DIRBLKSIZ a power of two. + * Dennis Ritchie feels that directory pages should be atomic + * operations to the disk, so we use DEV_BSIZE. + */ +#define DIRBLKSIZ DEV_BSIZE + +/* + * This limits the directory name length. Its main constraint + * is that it appears twice in the user structure. (u. area) + */ +#define MAXNAMLEN 255 + +struct direct { + u_long d_ino; + short d_reclen; + short d_namlen; + char d_name[MAXNAMLEN + 1]; + /* typically shorter */ }; + +struct _dirdesc { + int dd_fd; + long dd_loc; + long dd_size; + char dd_buf[DIRBLKSIZ]; +}; + +/* + * useful macros. + */ +#undef DIRSIZ +#define DIRSIZ(dp) \ + ((sizeof(struct direct) - MAXNAMLEN + (dp)->d_namlen + sizeof(ino_t) - 1) &\ + ~(sizeof(ino_t) - 1)) +typedef struct _dirdesc DIR; +#ifndef NULL +#define NULL 0 +#endif + +/* + * functions defined on directories + */ +extern DIR *opendir(); +extern struct direct *readdir(); +extern long telldir(); +extern void seekdir(); +#define rewinddir(dirp) seekdir((dirp), 0) +extern void closedir(); diff --git a/usr/src/sys/ufs/ffs/fs.h b/usr/src/sys/ufs/ffs/fs.h index a7c6e17623..ba0a3494fc 100644 --- a/usr/src/sys/ufs/ffs/fs.h +++ b/usr/src/sys/ufs/ffs/fs.h @@ -1,6 +1,6 @@ /* Copyright (c) 1981 Regents of the University of California */ -/* fs.h 2.3 %G% */ +/* fs.h 2.3 4/12/82 */ /* * Each disk drive contains some number of file systems. diff --git a/usr/src/sys/ufs/ffs/inode.h b/usr/src/sys/ufs/ffs/inode.h index 15efb10086..7936321b6f 100644 --- a/usr/src/sys/ufs/ffs/inode.h +++ b/usr/src/sys/ufs/ffs/inode.h @@ -1,52 +1,84 @@ -/* inode.h 4.10 82/02/27 */ +/* inode.h 4.11 82/04/19 */ + +/* inode.h 2.1 3/25/82 */ /* * The I node is the focus of all file activity in UNIX. * There is a unique inode allocated for each active file, * each current directory, each mounted-on file, text file, and the root. * An inode is 'named' by its dev/inumber pair. (iget/iget.c) - * Data, from mode on, is read in from permanent inode on volume. + * Data in icommon is read in from permanent inode on volume. */ -#define NADDR 13 + +#define NDADDR 8 /* direct addresses in inode */ +#define NIADDR 2 /* indirect addresses in inode */ struct inode { char i_flag; char i_count; /* reference count */ dev_t i_dev; /* device where inode resides */ ino_t i_number; /* i number, 1-to-1 with device address */ -/* begin read from disk */ - u_short i_mode; - short i_nlink; /* directory entries */ - short i_uid; /* owner */ - short i_gid; /* group of owner */ - off_t i_size; /* size of file */ + long i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct fs *i_fs; /* file sys associated with this inode */ union { - struct i_f { - daddr_t if_addr[NADDR]; /* if normal file/directory */ - daddr_t if_lastr; /* last read (read-ahead) */ - } i_f; - struct i_d { - daddr_t id_rdev; /* i_addr[0] */ - } i_d; - struct i_s { - struct socket *is_socket; - } i_s; -#define i_addr i_f.if_addr -#define i_lastr i_f.if_lastr -#define i_rdev i_d.id_rdev -#define i_socket i_s.is_socket + daddr_t if_lastr; /* last read (read-ahead) */ + struct socket *is_socket; } i_un; -/* end read from disk */ - short i_XXXXXX; /* ### */ -/* SHOULD USE POINTERS, NOT INDICES, FOR HAS CHAIN */ - short i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct icommon + { + u_short ic_mode; /* 0: mode and type of file */ + short ic_nlink; /* 2: number of links to file */ + short ic_uid; /* 4: owner's user id */ + short ic_gid; /* 6: owner's group id */ + off_t ic_size; /* 8: number of bytes in file */ + daddr_t ic_db[NDADDR]; /* 12: disk block addresses */ + daddr_t ic_ib[NIADDR]; /* 44: indirect blocks */ + time_t ic_atime; /* 52: time last accessed */ + time_t ic_mtime; /* 56: time last modified */ + time_t ic_ctime; /* 60: time created */ + } i_ic; }; +struct dinode { + union { + struct icommon di_icom; + char di_size[64]; + } di_un; +}; + +#define i_mode i_ic.ic_mode +#define i_nlink i_ic.ic_nlink +#define i_uid i_ic.ic_uid +#define i_gid i_ic.ic_gid +#define i_size i_ic.ic_size +#define i_db i_ic.ic_db +#define i_ib i_ic.ic_ib +#define i_atime i_ic.ic_atime +#define i_mtime i_ic.ic_mtime +#define i_ctime i_ic.ic_ctime +#define i_rdev i_ic.ic_db[0] +#define i_lastr i_un.if_lastr +#define i_socket is_socket + +#define di_ic di_un.di_icom +#define di_mode di_ic.ic_mode +#define di_nlink di_ic.ic_nlink +#define di_uid di_ic.ic_uid +#define di_gid di_ic.ic_gid +#define di_size di_ic.ic_size +#define di_db di_ic.ic_db +#define di_ib di_ic.ic_ib +#define di_atime di_ic.ic_atime +#define di_mtime di_ic.ic_mtime +#define di_ctime di_ic.ic_ctime +#define di_rdev di_ic.ic_db[0] + #ifdef KERNEL -struct inode *inode, *inodeNINODE; -int ninode; +extern struct inode *inode; /* The inode table itself */ +extern struct inode *inodeNINODE; /* The end of the inode table */ +extern int ninode; /* number of slots in the table */ -struct inode *rootdir; /* pointer to inode of root directory */ +struct inode *rootdir; /* pointer to inode of root directory */ struct inode *ialloc(); struct inode *ifind(); @@ -66,16 +98,16 @@ struct inode *namei(); #define ICHG 0100 /* inode has been changed */ /* modes */ -#define IFMT 0170000 /* type of file */ -#define IFCHR 0020000 /* character special */ -#define IFDIR 0040000 /* directory */ -#define IFBLK 0060000 /* block special */ -#define IFREG 0100000 /* regular */ -#define IFLNK 0120000 /* symbolic link */ -#define IFPORTAL 0140000 /* portal */ -#define ISUID 04000 /* set user id on execution */ -#define ISGID 02000 /* set group id on execution */ -#define ISVTX 01000 /* save swapped text even after use */ -#define IREAD 0400 /* read, write, execute permissions */ -#define IWRITE 0200 -#define IEXEC 0100 +#define IFMT 0170000 /* type of file */ +#define IFCHR 0020000 /* character special */ +#define IFDIR 0040000 /* directory */ +#define IFBLK 0060000 /* block special */ +#define IFREG 0100000 /* regular */ +#define IFLNK 0120000 /* symbolic link */ +#define IFPORTAL 0140000 /* portal */ +#define ISUID 04000 /* set user id on execution */ +#define ISGID 02000 /* set group id on execution */ +#define ISVTX 01000 /* save swapped text even after use */ +#define IREAD 0400 /* read, write, execute permissions */ +#define IWRITE 0200 +#define IEXEC 0100 diff --git a/usr/src/sys/ufs/ufs/dinode.h b/usr/src/sys/ufs/ufs/dinode.h index 1f2d84962a..a9495b7a1d 100644 --- a/usr/src/sys/ufs/ufs/dinode.h +++ b/usr/src/sys/ufs/ufs/dinode.h @@ -1,52 +1,84 @@ -/* dinode.h 4.10 82/02/27 */ +/* dinode.h 4.11 82/04/19 */ + +/* inode.h 2.1 3/25/82 */ /* * The I node is the focus of all file activity in UNIX. * There is a unique inode allocated for each active file, * each current directory, each mounted-on file, text file, and the root. * An inode is 'named' by its dev/inumber pair. (iget/iget.c) - * Data, from mode on, is read in from permanent inode on volume. + * Data in icommon is read in from permanent inode on volume. */ -#define NADDR 13 + +#define NDADDR 8 /* direct addresses in inode */ +#define NIADDR 2 /* indirect addresses in inode */ struct inode { char i_flag; char i_count; /* reference count */ dev_t i_dev; /* device where inode resides */ ino_t i_number; /* i number, 1-to-1 with device address */ -/* begin read from disk */ - u_short i_mode; - short i_nlink; /* directory entries */ - short i_uid; /* owner */ - short i_gid; /* group of owner */ - off_t i_size; /* size of file */ + long i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct fs *i_fs; /* file sys associated with this inode */ union { - struct i_f { - daddr_t if_addr[NADDR]; /* if normal file/directory */ - daddr_t if_lastr; /* last read (read-ahead) */ - } i_f; - struct i_d { - daddr_t id_rdev; /* i_addr[0] */ - } i_d; - struct i_s { - struct socket *is_socket; - } i_s; -#define i_addr i_f.if_addr -#define i_lastr i_f.if_lastr -#define i_rdev i_d.id_rdev -#define i_socket i_s.is_socket + daddr_t if_lastr; /* last read (read-ahead) */ + struct socket *is_socket; } i_un; -/* end read from disk */ - short i_XXXXXX; /* ### */ -/* SHOULD USE POINTERS, NOT INDICES, FOR HAS CHAIN */ - short i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct icommon + { + u_short ic_mode; /* 0: mode and type of file */ + short ic_nlink; /* 2: number of links to file */ + short ic_uid; /* 4: owner's user id */ + short ic_gid; /* 6: owner's group id */ + off_t ic_size; /* 8: number of bytes in file */ + daddr_t ic_db[NDADDR]; /* 12: disk block addresses */ + daddr_t ic_ib[NIADDR]; /* 44: indirect blocks */ + time_t ic_atime; /* 52: time last accessed */ + time_t ic_mtime; /* 56: time last modified */ + time_t ic_ctime; /* 60: time created */ + } i_ic; }; +struct dinode { + union { + struct icommon di_icom; + char di_size[64]; + } di_un; +}; + +#define i_mode i_ic.ic_mode +#define i_nlink i_ic.ic_nlink +#define i_uid i_ic.ic_uid +#define i_gid i_ic.ic_gid +#define i_size i_ic.ic_size +#define i_db i_ic.ic_db +#define i_ib i_ic.ic_ib +#define i_atime i_ic.ic_atime +#define i_mtime i_ic.ic_mtime +#define i_ctime i_ic.ic_ctime +#define i_rdev i_ic.ic_db[0] +#define i_lastr i_un.if_lastr +#define i_socket is_socket + +#define di_ic di_un.di_icom +#define di_mode di_ic.ic_mode +#define di_nlink di_ic.ic_nlink +#define di_uid di_ic.ic_uid +#define di_gid di_ic.ic_gid +#define di_size di_ic.ic_size +#define di_db di_ic.ic_db +#define di_ib di_ic.ic_ib +#define di_atime di_ic.ic_atime +#define di_mtime di_ic.ic_mtime +#define di_ctime di_ic.ic_ctime +#define di_rdev di_ic.ic_db[0] + #ifdef KERNEL -struct inode *inode, *inodeNINODE; -int ninode; +extern struct inode *inode; /* The inode table itself */ +extern struct inode *inodeNINODE; /* The end of the inode table */ +extern int ninode; /* number of slots in the table */ -struct inode *rootdir; /* pointer to inode of root directory */ +struct inode *rootdir; /* pointer to inode of root directory */ struct inode *ialloc(); struct inode *ifind(); @@ -66,16 +98,16 @@ struct inode *namei(); #define ICHG 0100 /* inode has been changed */ /* modes */ -#define IFMT 0170000 /* type of file */ -#define IFCHR 0020000 /* character special */ -#define IFDIR 0040000 /* directory */ -#define IFBLK 0060000 /* block special */ -#define IFREG 0100000 /* regular */ -#define IFLNK 0120000 /* symbolic link */ -#define IFPORTAL 0140000 /* portal */ -#define ISUID 04000 /* set user id on execution */ -#define ISGID 02000 /* set group id on execution */ -#define ISVTX 01000 /* save swapped text even after use */ -#define IREAD 0400 /* read, write, execute permissions */ -#define IWRITE 0200 -#define IEXEC 0100 +#define IFMT 0170000 /* type of file */ +#define IFCHR 0020000 /* character special */ +#define IFDIR 0040000 /* directory */ +#define IFBLK 0060000 /* block special */ +#define IFREG 0100000 /* regular */ +#define IFLNK 0120000 /* symbolic link */ +#define IFPORTAL 0140000 /* portal */ +#define ISUID 04000 /* set user id on execution */ +#define ISGID 02000 /* set group id on execution */ +#define ISVTX 01000 /* save swapped text even after use */ +#define IREAD 0400 /* read, write, execute permissions */ +#define IWRITE 0200 +#define IEXEC 0100 diff --git a/usr/src/sys/ufs/ufs/dir.h b/usr/src/sys/ufs/ufs/dir.h index c978a72252..f815f6c637 100644 --- a/usr/src/sys/ufs/ufs/dir.h +++ b/usr/src/sys/ufs/ufs/dir.h @@ -1,10 +1,55 @@ -/* dir.h 4.2 81/02/19 */ +/* dir.h 4.3 82/04/19 */ -#ifndef DIRSIZ -#define DIRSIZ 14 -#endif -struct direct -{ - ino_t d_ino; - char d_name[DIRSIZ]; +/* @(#)ndir.h 4.4 3/30/82 */ + +/* + * This sets the "page size" for directories. + * Requirements are DEV_BSIZE <= DIRBLKSIZ <= MINBSIZE with + * DIRBLKSIZ a power of two. + * Dennis Ritchie feels that directory pages should be atomic + * operations to the disk, so we use DEV_BSIZE. + */ +#define DIRBLKSIZ DEV_BSIZE + +/* + * This limits the directory name length. Its main constraint + * is that it appears twice in the user structure. (u. area) + */ +#define MAXNAMLEN 255 + +struct direct { + u_long d_ino; + short d_reclen; + short d_namlen; + char d_name[MAXNAMLEN + 1]; + /* typically shorter */ }; + +struct _dirdesc { + int dd_fd; + long dd_loc; + long dd_size; + char dd_buf[DIRBLKSIZ]; +}; + +/* + * useful macros. + */ +#undef DIRSIZ +#define DIRSIZ(dp) \ + ((sizeof(struct direct) - MAXNAMLEN + (dp)->d_namlen + sizeof(ino_t) - 1) &\ + ~(sizeof(ino_t) - 1)) +typedef struct _dirdesc DIR; +#ifndef NULL +#define NULL 0 +#endif + +/* + * functions defined on directories + */ +extern DIR *opendir(); +extern struct direct *readdir(); +extern long telldir(); +extern void seekdir(); +#define rewinddir(dirp) seekdir((dirp), 0) +extern void closedir(); diff --git a/usr/src/sys/ufs/ufs/inode.h b/usr/src/sys/ufs/ufs/inode.h index 15efb10086..7936321b6f 100644 --- a/usr/src/sys/ufs/ufs/inode.h +++ b/usr/src/sys/ufs/ufs/inode.h @@ -1,52 +1,84 @@ -/* inode.h 4.10 82/02/27 */ +/* inode.h 4.11 82/04/19 */ + +/* inode.h 2.1 3/25/82 */ /* * The I node is the focus of all file activity in UNIX. * There is a unique inode allocated for each active file, * each current directory, each mounted-on file, text file, and the root. * An inode is 'named' by its dev/inumber pair. (iget/iget.c) - * Data, from mode on, is read in from permanent inode on volume. + * Data in icommon is read in from permanent inode on volume. */ -#define NADDR 13 + +#define NDADDR 8 /* direct addresses in inode */ +#define NIADDR 2 /* indirect addresses in inode */ struct inode { char i_flag; char i_count; /* reference count */ dev_t i_dev; /* device where inode resides */ ino_t i_number; /* i number, 1-to-1 with device address */ -/* begin read from disk */ - u_short i_mode; - short i_nlink; /* directory entries */ - short i_uid; /* owner */ - short i_gid; /* group of owner */ - off_t i_size; /* size of file */ + long i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct fs *i_fs; /* file sys associated with this inode */ union { - struct i_f { - daddr_t if_addr[NADDR]; /* if normal file/directory */ - daddr_t if_lastr; /* last read (read-ahead) */ - } i_f; - struct i_d { - daddr_t id_rdev; /* i_addr[0] */ - } i_d; - struct i_s { - struct socket *is_socket; - } i_s; -#define i_addr i_f.if_addr -#define i_lastr i_f.if_lastr -#define i_rdev i_d.id_rdev -#define i_socket i_s.is_socket + daddr_t if_lastr; /* last read (read-ahead) */ + struct socket *is_socket; } i_un; -/* end read from disk */ - short i_XXXXXX; /* ### */ -/* SHOULD USE POINTERS, NOT INDICES, FOR HAS CHAIN */ - short i_hlink; /* link in hash chain (iget/iput/ifind) */ + struct icommon + { + u_short ic_mode; /* 0: mode and type of file */ + short ic_nlink; /* 2: number of links to file */ + short ic_uid; /* 4: owner's user id */ + short ic_gid; /* 6: owner's group id */ + off_t ic_size; /* 8: number of bytes in file */ + daddr_t ic_db[NDADDR]; /* 12: disk block addresses */ + daddr_t ic_ib[NIADDR]; /* 44: indirect blocks */ + time_t ic_atime; /* 52: time last accessed */ + time_t ic_mtime; /* 56: time last modified */ + time_t ic_ctime; /* 60: time created */ + } i_ic; }; +struct dinode { + union { + struct icommon di_icom; + char di_size[64]; + } di_un; +}; + +#define i_mode i_ic.ic_mode +#define i_nlink i_ic.ic_nlink +#define i_uid i_ic.ic_uid +#define i_gid i_ic.ic_gid +#define i_size i_ic.ic_size +#define i_db i_ic.ic_db +#define i_ib i_ic.ic_ib +#define i_atime i_ic.ic_atime +#define i_mtime i_ic.ic_mtime +#define i_ctime i_ic.ic_ctime +#define i_rdev i_ic.ic_db[0] +#define i_lastr i_un.if_lastr +#define i_socket is_socket + +#define di_ic di_un.di_icom +#define di_mode di_ic.ic_mode +#define di_nlink di_ic.ic_nlink +#define di_uid di_ic.ic_uid +#define di_gid di_ic.ic_gid +#define di_size di_ic.ic_size +#define di_db di_ic.ic_db +#define di_ib di_ic.ic_ib +#define di_atime di_ic.ic_atime +#define di_mtime di_ic.ic_mtime +#define di_ctime di_ic.ic_ctime +#define di_rdev di_ic.ic_db[0] + #ifdef KERNEL -struct inode *inode, *inodeNINODE; -int ninode; +extern struct inode *inode; /* The inode table itself */ +extern struct inode *inodeNINODE; /* The end of the inode table */ +extern int ninode; /* number of slots in the table */ -struct inode *rootdir; /* pointer to inode of root directory */ +struct inode *rootdir; /* pointer to inode of root directory */ struct inode *ialloc(); struct inode *ifind(); @@ -66,16 +98,16 @@ struct inode *namei(); #define ICHG 0100 /* inode has been changed */ /* modes */ -#define IFMT 0170000 /* type of file */ -#define IFCHR 0020000 /* character special */ -#define IFDIR 0040000 /* directory */ -#define IFBLK 0060000 /* block special */ -#define IFREG 0100000 /* regular */ -#define IFLNK 0120000 /* symbolic link */ -#define IFPORTAL 0140000 /* portal */ -#define ISUID 04000 /* set user id on execution */ -#define ISGID 02000 /* set group id on execution */ -#define ISVTX 01000 /* save swapped text even after use */ -#define IREAD 0400 /* read, write, execute permissions */ -#define IWRITE 0200 -#define IEXEC 0100 +#define IFMT 0170000 /* type of file */ +#define IFCHR 0020000 /* character special */ +#define IFDIR 0040000 /* directory */ +#define IFBLK 0060000 /* block special */ +#define IFREG 0100000 /* regular */ +#define IFLNK 0120000 /* symbolic link */ +#define IFPORTAL 0140000 /* portal */ +#define ISUID 04000 /* set user id on execution */ +#define ISGID 02000 /* set group id on execution */ +#define ISVTX 01000 /* save swapped text even after use */ +#define IREAD 0400 /* read, write, execute permissions */ +#define IWRITE 0200 +#define IEXEC 0100 -- 2.20.1