diff --git a/bio.c b/bio.c index 6a28053..629bb2c 100644 --- a/bio.c +++ b/bio.c @@ -24,6 +24,7 @@ #include "defs.h" #include "param.h" #include "spinlock.h" +#include "fs.h" #include "buf.h" struct { @@ -55,20 +56,20 @@ binit(void) } } -// Look through buffer cache for sector on device dev. +// Look through buffer cache for block on device dev. // If not found, allocate a buffer. // In either case, return B_BUSY buffer. static struct buf* -bget(uint dev, uint sector) +bget(uint dev, uint blockno) { struct buf *b; acquire(&bcache.lock); loop: - // Is the sector already cached? + // Is the block already cached? for(b = bcache.head.next; b != &bcache.head; b = b->next){ - if(b->dev == dev && b->sector == sector){ + if(b->dev == dev && b->blockno == blockno){ if(!(b->flags & B_BUSY)){ b->flags |= B_BUSY; release(&bcache.lock); @@ -85,7 +86,7 @@ bget(uint dev, uint sector) for(b = bcache.head.prev; b != &bcache.head; b = b->prev){ if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){ b->dev = dev; - b->sector = sector; + b->blockno = blockno; b->flags = B_BUSY; release(&bcache.lock); return b; @@ -94,15 +95,16 @@ bget(uint dev, uint sector) panic("bget: no buffers"); } -// Return a B_BUSY buf with the contents of the indicated disk sector. +// Return a B_BUSY buf with the contents of the indicated block. struct buf* -bread(uint dev, uint sector) +bread(uint dev, uint blockno) { struct buf *b; - b = bget(dev, sector); - if(!(b->flags & B_VALID)) + b = bget(dev, blockno); + if(!(b->flags & B_VALID)) { iderw(b); + } return b; } diff --git a/bootmain.c b/bootmain.c index d24bf66..97d5258 100644 --- a/bootmain.c +++ b/bootmain.c @@ -1,6 +1,6 @@ // Boot loader. // -// Part of the boot sector, along with bootasm.S, which calls bootmain(). +// Part of the boot block, along with bootasm.S, which calls bootmain(). // bootasm.S has put the processor into protected 32-bit mode. // bootmain() loads an ELF kernel image from the disk starting at // sector 1 and then jumps to the kernel entry routine. diff --git a/buf.h b/buf.h index 9c586f2..f18fd87 100644 --- a/buf.h +++ b/buf.h @@ -1,11 +1,11 @@ struct buf { int flags; uint dev; - uint sector; + uint blockno; struct buf *prev; // LRU cache list struct buf *next; struct buf *qnext; // disk queue - uchar data[512]; + uchar data[BSIZE]; }; #define B_BUSY 0x1 // buffer is locked by some process #define B_VALID 0x2 // buffer has been read from disk diff --git a/fs.c b/fs.c index 1803cb4..286252d 100644 --- a/fs.c +++ b/fs.c @@ -16,8 +16,8 @@ #include "mmu.h" #include "proc.h" #include "spinlock.h" -#include "buf.h" #include "fs.h" +#include "buf.h" #include "file.h" #define min(a, b) ((a) < (b) ? (a) : (b)) diff --git a/fs.h b/fs.h index f191d43..e74ff5b 100644 --- a/fs.h +++ b/fs.h @@ -9,7 +9,7 @@ // Then sb.nlog log blocks. #define ROOTINO 1 // root i-number -#define BSIZE 512 // block size +#define BSIZE 1024 // block size // File system super block struct superblock { diff --git a/ide.c b/ide.c index 6850a09..96216ea 100644 --- a/ide.c +++ b/ide.c @@ -9,8 +9,10 @@ #include "x86.h" #include "traps.h" #include "spinlock.h" +#include "fs.h" #include "buf.h" +#define SECTOR_SIZE 512 #define IDE_BSY 0x80 #define IDE_DRDY 0x40 #define IDE_DF 0x20 @@ -71,17 +73,21 @@ idestart(struct buf *b) { if(b == 0) panic("idestart"); + int sector_per_block = BSIZE/SECTOR_SIZE; + int sector = b->blockno * sector_per_block; + if (sector_per_block > 7) panic("idestart"); + idewait(0); outb(0x3f6, 0); // generate interrupt - outb(0x1f2, 1); // number of sectors - outb(0x1f3, b->sector & 0xff); - outb(0x1f4, (b->sector >> 8) & 0xff); - outb(0x1f5, (b->sector >> 16) & 0xff); - outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((b->sector>>24)&0x0f)); + outb(0x1f2, sector_per_block); // number of sectors + outb(0x1f3, sector & 0xff); + outb(0x1f4, (sector >> 8) & 0xff); + outb(0x1f5, (sector >> 16) & 0xff); + outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((sector>>24)&0x0f)); if(b->flags & B_DIRTY){ outb(0x1f7, IDE_CMD_WRITE); - outsl(0x1f0, b->data, 512/4); + outsl(0x1f0, b->data, BSIZE/4); } else { outb(0x1f7, IDE_CMD_READ); } @@ -104,7 +110,7 @@ ideintr(void) // Read data if needed. if(!(b->flags & B_DIRTY) && idewait(1) >= 0) - insl(0x1f0, b->data, 512/4); + insl(0x1f0, b->data, BSIZE/4); // Wake process waiting for this buf. b->flags |= B_VALID; diff --git a/kill.c b/kill.c index 5e60113..364f6af 100644 --- a/kill.c +++ b/kill.c @@ -7,7 +7,7 @@ main(int argc, char **argv) { int i; - if(argc < 1){ + if(argc < 2){ printf(2, "usage: kill pid...\n"); exit(); } diff --git a/log.c b/log.c index f519a8c..01aa580 100644 --- a/log.c +++ b/log.c @@ -21,7 +21,7 @@ // // The log is a physical re-do log containing disk blocks. // The on-disk log format: -// header block, containing sector #s for block A, B, C, ... +// header block, containing block #s for block A, B, C, ... // block A // block B // block C @@ -29,10 +29,10 @@ // Log appends are synchronous. // Contents of the header block, used for both the on-disk header block -// and to keep track in memory of logged sector #s before commit. +// and to keep track in memory of logged block# before commit. struct logheader { int n; - int sector[LOGSIZE]; + int block[LOGSIZE]; }; struct log { @@ -72,7 +72,7 @@ install_trans(void) for (tail = 0; tail < log.lh.n; tail++) { struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block - struct buf *dbuf = bread(log.dev, log.lh.sector[tail]); // read dst + struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst bwrite(dbuf); // write dst to disk brelse(lbuf); @@ -89,7 +89,7 @@ read_head(void) int i; log.lh.n = lh->n; for (i = 0; i < log.lh.n; i++) { - log.lh.sector[i] = lh->sector[i]; + log.lh.block[i] = lh->block[i]; } brelse(buf); } @@ -105,7 +105,7 @@ write_head(void) int i; hb->n = log.lh.n; for (i = 0; i < log.lh.n; i++) { - hb->sector[i] = log.lh.sector[i]; + hb->block[i] = log.lh.block[i]; } bwrite(buf); brelse(buf); @@ -178,7 +178,7 @@ write_log(void) for (tail = 0; tail < log.lh.n; tail++) { struct buf *to = bread(log.dev, log.start+tail+1); // log block - struct buf *from = bread(log.dev, log.lh.sector[tail]); // cache block + struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block memmove(to->data, from->data, BSIZE); bwrite(to); // write the log brelse(from); @@ -219,10 +219,10 @@ log_write(struct buf *b) acquire(&log.lock); for (i = 0; i < log.lh.n; i++) { - if (log.lh.sector[i] == b->sector) // log absorbtion + if (log.lh.block[i] == b->blockno) // log absorbtion break; } - log.lh.sector[i] = b->sector; + log.lh.block[i] = b->blockno; if (i == log.lh.n) log.lh.n++; b->flags |= B_DIRTY; // prevent eviction diff --git a/memide.c b/memide.c index d2c5bb7..2e09e33 100644 --- a/memide.c +++ b/memide.c @@ -20,7 +20,7 @@ void ideinit(void) { memdisk = _binary_fs_img_start; - disksize = (uint)_binary_fs_img_size/512; + disksize = (uint)_binary_fs_img_size/BSIZE; } // Interrupt handler. @@ -44,15 +44,15 @@ iderw(struct buf *b) panic("iderw: nothing to do"); if(b->dev != 1) panic("iderw: request not for disk 1"); - if(b->sector >= disksize) - panic("iderw: sector out of range"); + if(b->block >= disksize) + panic("iderw: block out of range"); - p = memdisk + b->sector*512; + p = memdisk + b->block*BSIZE; if(b->flags & B_DIRTY){ b->flags &= ~B_DIRTY; - memmove(p, b->data, 512); + memmove(p, b->data, BSIZE); } else - memmove(b->data, p, 512); + memmove(b->data, p, BSIZE); b->flags |= B_VALID; } diff --git a/mkfs.c b/mkfs.c index c168377..2d2859d 100644 --- a/mkfs.c +++ b/mkfs.c @@ -13,18 +13,24 @@ #define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) -int nblocks = (995-LOGSIZE); -int nlog = LOGSIZE; -int ninodes = 200; -int size = 1024; +#define SIZE 1000 +#define NINODES 200 + +// Disk layout: +// [ boot block | sb block | inode blocks | bit map | data blocks | log ] + +int nbitmap = SIZE/(BSIZE*8) + 1; +int ninodeblocks = NINODES / IPB + 1; +int nlog = LOGSIZE; +int nmeta; // Number of meta blocks (inode, bitmap, and 2 extra) +int nblocks; // Number of data blocks int fsfd; struct superblock sb; -char zeroes[512]; -uint freeblock; -uint usedblocks; -uint bitblocks; +char zeroes[BSIZE]; uint freeinode = 1; +uint freeblock; + void balloc(int); void wsect(uint, void*); @@ -63,7 +69,7 @@ main(int argc, char *argv[]) int i, cc, fd; uint rootino, inum, off; struct dirent de; - char buf[512]; + char buf[BSIZE]; struct dinode din; @@ -74,8 +80,8 @@ main(int argc, char *argv[]) exit(1); } - assert((512 % sizeof(struct dinode)) == 0); - assert((512 % sizeof(struct dirent)) == 0); + assert((BSIZE % sizeof(struct dinode)) == 0); + assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ @@ -83,21 +89,19 @@ main(int argc, char *argv[]) exit(1); } - sb.size = xint(size); + nmeta = 2 + ninodeblocks + nbitmap; + nblocks = SIZE - nlog - nmeta; + + sb.size = xint(SIZE); sb.nblocks = xint(nblocks); // so whole disk is size sectors - sb.ninodes = xint(ninodes); + sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); - bitblocks = size/(512*8) + 1; - usedblocks = ninodes / IPB + 3 + bitblocks; - freeblock = usedblocks; + printf("nmeta %d (boot, super, inode blocks %u, bitmap blocks %u) blocks %d log %u total %d\n", nmeta, ninodeblocks, nbitmap, nblocks, nlog, SIZE); - printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, - bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); + freeblock = nmeta; // the first free block that we can allocate - assert(nblocks + usedblocks + nlog == size); - - for(i = 0; i < nblocks + usedblocks + nlog; i++) + for(i = 0; i < SIZE; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); @@ -152,7 +156,7 @@ main(int argc, char *argv[]) din.size = xint(off); winode(rootino, &din); - balloc(usedblocks); + balloc(freeblock); exit(0); } @@ -160,30 +164,26 @@ main(int argc, char *argv[]) void wsect(uint sec, void *buf) { - if(lseek(fsfd, sec * 512L, 0) != sec * 512L){ + printf("seek to %d\n", sec * BSIZE); + if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){ perror("lseek"); exit(1); } - if(write(fsfd, buf, 512) != 512){ + if(write(fsfd, buf, BSIZE) != BSIZE){ perror("write"); exit(1); } } -uint -i2b(uint inum) -{ - return (inum / IPB) + 2; -} - void winode(uint inum, struct dinode *ip) { - char buf[512]; + char buf[BSIZE]; uint bn; struct dinode *dip; - bn = i2b(inum); + bn = IBLOCK(inum); + printf("winode %d\n", bn); rsect(bn, buf); dip = ((struct dinode*)buf) + (inum % IPB); *dip = *ip; @@ -193,11 +193,11 @@ winode(uint inum, struct dinode *ip) void rinode(uint inum, struct dinode *ip) { - char buf[512]; + char buf[BSIZE]; uint bn; struct dinode *dip; - bn = i2b(inum); + bn = IBLOCK(inum); rsect(bn, buf); dip = ((struct dinode*)buf) + (inum % IPB); *ip = *dip; @@ -206,11 +206,11 @@ rinode(uint inum, struct dinode *ip) void rsect(uint sec, void *buf) { - if(lseek(fsfd, sec * 512L, 0) != sec * 512L){ + if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){ perror("lseek"); exit(1); } - if(read(fsfd, buf, 512) != 512){ + if(read(fsfd, buf, BSIZE) != BSIZE){ perror("read"); exit(1); } @@ -233,17 +233,17 @@ ialloc(ushort type) void balloc(int used) { - uchar buf[512]; + uchar buf[BSIZE]; int i; printf("balloc: first %d blocks have been allocated\n", used); - assert(used < 512*8); - bzero(buf, 512); + assert(used < BSIZE*8); + bzero(buf, BSIZE); for(i = 0; i < used; i++){ buf[i/8] = buf[i/8] | (0x1 << (i%8)); } - printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); - wsect(ninodes / IPB + 3, buf); + printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2); + wsect(ninodeblocks+2, buf); } #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -254,7 +254,7 @@ iappend(uint inum, void *xp, int n) char *p = (char*)xp; uint fbn, off, n1; struct dinode din; - char buf[512]; + char buf[BSIZE]; uint indirect[NINDIRECT]; uint x; @@ -262,32 +262,29 @@ iappend(uint inum, void *xp, int n) off = xint(din.size); while(n > 0){ - fbn = off / 512; + fbn = off / BSIZE; assert(fbn < MAXFILE); if(fbn < NDIRECT){ if(xint(din.addrs[fbn]) == 0){ din.addrs[fbn] = xint(freeblock++); - usedblocks++; } x = xint(din.addrs[fbn]); } else { if(xint(din.addrs[NDIRECT]) == 0){ // printf("allocate indirect block\n"); din.addrs[NDIRECT] = xint(freeblock++); - usedblocks++; } // printf("read indirect block\n"); rsect(xint(din.addrs[NDIRECT]), (char*)indirect); if(indirect[fbn - NDIRECT] == 0){ indirect[fbn - NDIRECT] = xint(freeblock++); - usedblocks++; wsect(xint(din.addrs[NDIRECT]), (char*)indirect); } x = xint(indirect[fbn-NDIRECT]); } - n1 = min(n, (fbn + 1) * 512 - off); + n1 = min(n, (fbn + 1) * BSIZE - off); rsect(x, buf); - bcopy(p, buf + off - (fbn * 512), n1); + bcopy(p, buf + off - (fbn * BSIZE), n1); wsect(x, buf); n -= n1; off += n1; diff --git a/param.h b/param.h index 8e007ca..1a73f42 100644 --- a/param.h +++ b/param.h @@ -8,6 +8,6 @@ #define ROOTDEV 1 // device number of file system root disk #define MAXARG 32 // max exec arguments #define MAXOPBLOCKS 10 // max # of blocks any FS op writes -#define LOGSIZE (MAXOPBLOCKS*3) // max data sectors in on-disk log +#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log #define NBUF (MAXOPBLOCKS*3) // size of disk block cache