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