summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--defs.h4
-rw-r--r--fs.c26
-rw-r--r--fs.h21
-rw-r--r--log.c8
-rw-r--r--main.c1
-rw-r--r--mkfs.c29
-rw-r--r--proc.c3
7 files changed, 47 insertions, 45 deletions
diff --git a/defs.h b/defs.h
index 43431e3..b47372b 100644
--- 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 286252d..025b326 100644
--- 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 f191d43..e1d7d09 100644
--- 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 01aa580..12db8ca 100644
--- 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 8a73c0f..40facc4 100644
--- 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 7197bc1..957460a 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -16,12 +16,12 @@
#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 a642f5a..3ac41f6 100644
--- 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).