]> Devi Nivas Git - cs3210-lab1.git/commitdiff
Pick up where i left off in april:
authorFrans Kaashoek <kaashoek@mit.edu>
Sat, 27 Jun 2015 16:39:13 +0000 (12:39 -0400)
committerFrans Kaashoek <kaashoek@mit.edu>
Sat, 27 Jun 2015 16:39:13 +0000 (12:39 -0400)
- move log into metadata part of disk, so that marking
that the log's blocks are in use falls out for free
- superblock describes the whole disk (sizes and offets)
- sizes and offsets are computed in one place (mkfs) and
the rest of the code refers to the superblock for these values,
instead of recomputing them.

defs.h
fs.c
fs.h
log.c
main.c
mkfs.c
proc.c

diff --git a/defs.h b/defs.h
index 43431e35da14cfe5725f39f8f8b14b0dc6afb534..b47372bc7424f948373e0f166ee5e1e2ca70d62f 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -39,7 +39,7 @@ int             dirlink(struct inode*, char*, uint);
 struct inode*   dirlookup(struct inode*, char*, uint*);
 struct inode*   ialloc(uint, short);
 struct inode*   idup(struct inode*);
-void            iinit(void);
+void            iinit(int dev);
 void            ilock(struct inode*);
 void            iput(struct inode*);
 void            iunlock(struct inode*);
@@ -81,7 +81,7 @@ void            lapicstartap(uchar, uint);
 void            microdelay(int);
 
 // log.c
-void            initlog(void);
+void            initlog(int dev);
 void            log_write(struct buf*);
 void            begin_op();
 void            end_op();
diff --git a/fs.c b/fs.c
index 286252d994fc9d092b2eb56fa02b2f342c85b2a8..025b326c4d91e027df472a8d668cdd549a806aa7 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -22,6 +22,7 @@
 
 #define min(a, b) ((a) < (b) ? (a) : (b))
 static void itrunc(struct inode*);
+struct superblock sb;   // there should be one per dev, but we run with one dev
 
 // Read the super block.
 void
@@ -54,12 +55,10 @@ balloc(uint dev)
 {
   int b, bi, m;
   struct buf *bp;
-  struct superblock sb;
 
   bp = 0;
-  readsb(dev, &sb);
   for(b = 0; b < sb.size; b += BPB){
-    bp = bread(dev, BBLOCK(b, sb.ninodes));
+    bp = bread(dev, BBLOCK(b, sb));
     for(bi = 0; bi < BPB && b + bi < sb.size; bi++){
       m = 1 << (bi % 8);
       if((bp->data[bi/8] & m) == 0){  // Is block free?
@@ -80,11 +79,10 @@ static void
 bfree(int dev, uint b)
 {
   struct buf *bp;
-  struct superblock sb;
   int bi, m;
 
   readsb(dev, &sb);
-  bp = bread(dev, BBLOCK(b, sb.ninodes));
+  bp = bread(dev, BBLOCK(b, sb));
   bi = b % BPB;
   m = 1 << (bi % 8);
   if((bp->data[bi/8] & m) == 0)
@@ -101,8 +99,8 @@ bfree(int dev, uint b)
 // its size, the number of links referring to it, and the
 // list of blocks holding the file's content.
 //
-// The inodes are laid out sequentially on disk immediately after
-// the superblock. Each inode has a number, indicating its
+// The inodes are laid out sequentially on disk at
+// sb.startinode. Each inode has a number, indicating its
 // position on the disk.
 //
 // The kernel keeps a cache of in-use inodes in memory
@@ -162,9 +160,12 @@ struct {
 } icache;
 
 void
-iinit(void)
+iinit(int dev)
 {
   initlock(&icache.lock, "icache");
+  readsb(dev, &sb);
+  cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d inodestart %d bmap start %d\n", sb.size,
+          sb.nblocks, sb.ninodes, sb.nlog, sb.logstart, sb.inodestart, sb.bmapstart);
 }
 
 static struct inode* iget(uint dev, uint inum);
@@ -178,12 +179,9 @@ ialloc(uint dev, short type)
   int inum;
   struct buf *bp;
   struct dinode *dip;
-  struct superblock sb;
-
-  readsb(dev, &sb);
 
   for(inum = 1; inum < sb.ninodes; inum++){
-    bp = bread(dev, IBLOCK(inum));
+    bp = bread(dev, IBLOCK(inum, sb));
     dip = (struct dinode*)bp->data + inum%IPB;
     if(dip->type == 0){  // a free inode
       memset(dip, 0, sizeof(*dip));
@@ -204,7 +202,7 @@ iupdate(struct inode *ip)
   struct buf *bp;
   struct dinode *dip;
 
-  bp = bread(ip->dev, IBLOCK(ip->inum));
+  bp = bread(ip->dev, IBLOCK(ip->inum, sb));
   dip = (struct dinode*)bp->data + ip->inum%IPB;
   dip->type = ip->type;
   dip->major = ip->major;
@@ -281,7 +279,7 @@ ilock(struct inode *ip)
   release(&icache.lock);
 
   if(!(ip->flags & I_VALID)){
-    bp = bread(ip->dev, IBLOCK(ip->inum));
+    bp = bread(ip->dev, IBLOCK(ip->inum, sb));
     dip = (struct dinode*)bp->data + ip->inum%IPB;
     ip->type = dip->type;
     ip->major = dip->major;
diff --git a/fs.h b/fs.h
index f191d43a66433656539b23ec60aa36a1181b52c7..e1d7d09c3a32c61df0152383fb855b84cec5d1d1 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -1,22 +1,23 @@
 // On-disk file system format. 
 // Both the kernel and user programs use this header file.
 
-// Block 0 is unused.
-// Block 1 is super block.
-// Blocks 2 through sb.ninodes/IPB hold inodes.
-// Then free bitmap blocks holding sb.size bits.
-// Then sb.nblocks data blocks.
-// Then sb.nlog log blocks.
 
 #define ROOTINO 1  // root i-number
 #define BSIZE 512  // block size
 
-// File system super block
+// Disk layout:
+// [ boot block | super block | log | inode blocks | free bit map | data blocks ]
+//
+// mkfs computes the super block and builds an initial file system. The super describes
+// the disk layout:
 struct superblock {
   uint size;         // Size of file system image (blocks)
   uint nblocks;      // Number of data blocks
   uint ninodes;      // Number of inodes.
   uint nlog;         // Number of log blocks
+  uint logstart;     // Block number of first log block
+  uint inodestart;   // Block number of first inode block
+  uint bmapstart;    // Block number of first free map block
 };
 
 #define NDIRECT 12
@@ -37,13 +38,13 @@ struct dinode {
 #define IPB           (BSIZE / sizeof(struct dinode))
 
 // Block containing inode i
-#define IBLOCK(i)     ((i) / IPB + 2)
+#define IBLOCK(i, sb)     ((i) / IPB + sb.inodestart)
 
 // Bitmap bits per block
 #define BPB           (BSIZE*8)
 
-// Block containing bit for block b
-#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3)
+// Block of free map containing bit for block b
+#define BBLOCK(b, sb) (b/BPB + sb.bmapstart)
 
 // Directory is a file containing a sequence of dirent structures.
 #define DIRSIZ 14
diff --git a/log.c b/log.c
index 01aa580758a15f48462e87fca6f6556bb18cdd32..12db8caec88f83a4779d7381dfcfb1daa7137c13 100644 (file)
--- a/log.c
+++ b/log.c
@@ -50,17 +50,17 @@ static void recover_from_log(void);
 static void commit();
 
 void
-initlog(void)
+initlog(int dev)
 {
   if (sizeof(struct logheader) >= BSIZE)
     panic("initlog: too big logheader");
 
   struct superblock sb;
   initlock(&log.lock, "log");
-  readsb(ROOTDEV, &sb);
-  log.start = sb.size - sb.nlog;
+  readsb(dev, &sb);
+  log.start = sb.logstart;
   log.size = sb.nlog;
-  log.dev = ROOTDEV;
+  log.dev = dev;
   recover_from_log();
 }
 
diff --git a/main.c b/main.c
index 8a73c0fc7f410876a78f4c5efd6b6ba43cb2721e..40facc444b4303125aaffe9966b55e81b61e0d08 100644 (file)
--- a/main.c
+++ b/main.c
@@ -31,7 +31,6 @@ main(void)
   tvinit();        // trap vectors
   binit();         // buffer cache
   fileinit();      // file table
-  iinit();         // inode cache
   ideinit();       // disk
   if(!ismp)
     timerinit();   // uniprocessor timer
diff --git a/mkfs.c b/mkfs.c
index 7197bc1c8bde3bd047cb8988b1efcff66f2e0b61..957460aa3d14401be946152a24e1f18e90e5a6ae 100644 (file)
--- a/mkfs.c
+++ b/mkfs.c
 #define NINODES 200
 
 // Disk layout:
-// [ boot block | sb block | inode blocks | bit map | data blocks | log ]
+// [ boot block | sb block | log | inode blocks | free bit map | data blocks ]
 
 int nbitmap = FSSIZE/(BSIZE*8) + 1;
 int ninodeblocks = NINODES / IPB + 1;
 int nlog = LOGSIZE;  
-int nmeta;    // Number of meta blocks (inode, bitmap, and 2 extra)
+int nmeta;    // Number of meta blocks (boot, sb, nlog, inode, bitmap)
 int nblocks;  // Number of data blocks
 
 int fsfd;
@@ -88,15 +88,20 @@ main(int argc, char *argv[])
     exit(1);
   }
 
-  nmeta = 2 + ninodeblocks + nbitmap;
-  nblocks = FSSIZE - nlog - nmeta;
+  // 1 fs block = 1 disk sector
+  nmeta = 2 + nlog + ninodeblocks + nbitmap;
+  nblocks = FSSIZE - nmeta;
 
   sb.size = xint(FSSIZE);
-  sb.nblocks = xint(nblocks); // so whole disk is size sectors
+  sb.nblocks = xint(nblocks);
   sb.ninodes = xint(NINODES);
   sb.nlog = xint(nlog);
+  sb.logstart = xint(2);
+  sb.inodestart = xint(2+nlog);
+  sb.bmapstart = xint(2+nlog+ninodeblocks);
 
-  printf("nmeta %d (boot, super, inode blocks %u, bitmap blocks %u) blocks %d log %u total %d\n", nmeta, ninodeblocks, nbitmap, nblocks, nlog, FSSIZE);
+  printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n",
+         nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE);
 
   freeblock = nmeta;     // the first free block that we can allocate
 
@@ -180,7 +185,7 @@ winode(uint inum, struct dinode *ip)
   uint bn;
   struct dinode *dip;
 
-  bn = IBLOCK(inum);
+  bn = IBLOCK(inum, sb);
   rsect(bn, buf);
   dip = ((struct dinode*)buf) + (inum % IPB);
   *dip = *ip;
@@ -194,7 +199,7 @@ rinode(uint inum, struct dinode *ip)
   uint bn;
   struct dinode *dip;
 
-  bn = IBLOCK(inum);
+  bn = IBLOCK(inum, sb);
   rsect(bn, buf);
   dip = ((struct dinode*)buf) + (inum % IPB);
   *ip = *dip;
@@ -239,8 +244,8 @@ balloc(int used)
   for(i = 0; i < used; i++){
     buf[i/8] = buf[i/8] | (0x1 << (i%8));
   }
-  printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2);
-  wsect(ninodeblocks+2, buf);
+  printf("balloc: write bitmap block at sector %d\n", sb.bmapstart);
+  wsect(sb.bmapstart, buf);
 }
 
 #define min(a, b) ((a) < (b) ? (a) : (b))
@@ -256,8 +261,8 @@ iappend(uint inum, void *xp, int n)
   uint x;
 
   rinode(inum, &din);
-
   off = xint(din.size);
+  // printf("append inum %d at off %d sz %d\n", inum, off, n);
   while(n > 0){
     fbn = off / BSIZE;
     assert(fbn < MAXFILE);
@@ -268,10 +273,8 @@ iappend(uint inum, void *xp, int n)
       x = xint(din.addrs[fbn]);
     } else {
       if(xint(din.addrs[NDIRECT]) == 0){
-        // printf("allocate indirect block\n");
         din.addrs[NDIRECT] = xint(freeblock++);
       }
-      // printf("read indirect block\n");
       rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
       if(indirect[fbn - NDIRECT] == 0){
         indirect[fbn - NDIRECT] = xint(freeblock++);
diff --git a/proc.c b/proc.c
index a642f5a4da13a05c49404653a2259a571273413d..3ac41f65697733f2ef3b6bcbc78f93656d47a5e7 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -339,7 +339,8 @@ forkret(void)
     // of a regular process (e.g., they call sleep), and thus cannot 
     // be run from main().
     first = 0;
-    initlog();
+    iinit(ROOTDEV);
+    initlog(ROOTDEV);
   }
   
   // Return to "caller", actually trapret (see allocproc).