]> Devi Nivas Git - cs3210-lab1.git/commitdiff
Disentangle block size from the disk's sector size. Set block size to 1024 to show
authorFrans Kaashoek <kaashoek@mit.edu>
Fri, 3 Apr 2015 12:22:02 +0000 (08:22 -0400)
committerFrans Kaashoek <kaashoek@mit.edu>
Fri, 3 Apr 2015 12:22:02 +0000 (08:22 -0400)
that they can be different.  Clean up mkfs, simplifying specifying fs parameters,
remove some redundancy between fs and mkfs, and fix disk layout bugs. Call blocks
in the file system blocks instead of sectors.  Passes usertests for different
block sizes.

bio.c
bootmain.c
buf.h
fs.c
fs.h
ide.c
kill.c
log.c
memide.c
mkfs.c
param.h

diff --git a/bio.c b/bio.c
index 6a28053ea6602134eaeda43123f27627e33211fb..629bb2c52c850ca17e408ce6e8ee5cebd3be8a21 100644 (file)
--- 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;
 }
 
index d24bf665e95eaad17b09a13b449e10b484aa35c8..97d525872772955ae85d4f0de78df1aea14ddfaf 100644 (file)
@@ -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 9c586f21d8aa81aad6df5a2bce1acd30b6ae587b..f18fd87686e15a2a1abdf77eb10f5fa50145e10a 100644 (file)
--- 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 1803cb489d8e9a1e3d0cb4bdc82956b49e8a9062..286252d994fc9d092b2eb56fa02b2f342c85b2a8 100644 (file)
--- 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 f191d43a66433656539b23ec60aa36a1181b52c7..e74ff5baeacbe0e8f00d9210b45ff4f2eedb72ed 100644 (file)
--- 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 6850a091059def4b38a2321771e2efac6a374ab5..96216ea17afe30cf2a23583d90eef8e82d698aef 100644 (file)
--- 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 5e601135b5aebae35efc153a85e4d1f26d725bd7..364f6af2eb7369e065c44c18c03765cfdf5d69ce 100644 (file)
--- 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 f519a8c27f5e8e21a1ef0364a19bc5e141a871fa..01aa580758a15f48462e87fca6f6556bb18cdd32 100644 (file)
--- 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
 // 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
index d2c5bb7e16015d0103cd67bf730225a75ca3f423..2e09e339cc530e9ca70ca38729fa048b87507dcc 100644 (file)
--- 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 c168377275afd5845fcd0eef1bc2c0a33d5df837..2d2859d4323afc81ee4194db7e73cd3cda8ce38c 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
 
 #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 8e007ca3f67e46d1c02bc7734a1d02916c8dad5d..1a73f42adb4ebd581f718d37565a8402fbd45ee2 100644 (file)
--- 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