提交 8320d61b 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Pick up where i left off in april:

- 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.
上级 de4af193
...@@ -39,7 +39,7 @@ int dirlink(struct inode*, char*, uint); ...@@ -39,7 +39,7 @@ int dirlink(struct inode*, char*, uint);
struct inode* dirlookup(struct inode*, char*, uint*); struct inode* dirlookup(struct inode*, char*, uint*);
struct inode* ialloc(uint, short); struct inode* ialloc(uint, short);
struct inode* idup(struct inode*); struct inode* idup(struct inode*);
void iinit(void); void iinit(int dev);
void ilock(struct inode*); void ilock(struct inode*);
void iput(struct inode*); void iput(struct inode*);
void iunlock(struct inode*); void iunlock(struct inode*);
...@@ -81,7 +81,7 @@ void lapicstartap(uchar, uint); ...@@ -81,7 +81,7 @@ void lapicstartap(uchar, uint);
void microdelay(int); void microdelay(int);
// log.c // log.c
void initlog(void); void initlog(int dev);
void log_write(struct buf*); void log_write(struct buf*);
void begin_op(); void begin_op();
void end_op(); void end_op();
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
static void itrunc(struct inode*); static void itrunc(struct inode*);
struct superblock sb; // there should be one per dev, but we run with one dev
// Read the super block. // Read the super block.
void void
...@@ -54,12 +55,10 @@ balloc(uint dev) ...@@ -54,12 +55,10 @@ balloc(uint dev)
{ {
int b, bi, m; int b, bi, m;
struct buf *bp; struct buf *bp;
struct superblock sb;
bp = 0; bp = 0;
readsb(dev, &sb);
for(b = 0; b < sb.size; b += BPB){ 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++){ for(bi = 0; bi < BPB && b + bi < sb.size; bi++){
m = 1 << (bi % 8); m = 1 << (bi % 8);
if((bp->data[bi/8] & m) == 0){ // Is block free? if((bp->data[bi/8] & m) == 0){ // Is block free?
...@@ -80,11 +79,10 @@ static void ...@@ -80,11 +79,10 @@ static void
bfree(int dev, uint b) bfree(int dev, uint b)
{ {
struct buf *bp; struct buf *bp;
struct superblock sb;
int bi, m; int bi, m;
readsb(dev, &sb); readsb(dev, &sb);
bp = bread(dev, BBLOCK(b, sb.ninodes)); bp = bread(dev, BBLOCK(b, sb));
bi = b % BPB; bi = b % BPB;
m = 1 << (bi % 8); m = 1 << (bi % 8);
if((bp->data[bi/8] & m) == 0) if((bp->data[bi/8] & m) == 0)
...@@ -101,8 +99,8 @@ bfree(int dev, uint b) ...@@ -101,8 +99,8 @@ bfree(int dev, uint b)
// its size, the number of links referring to it, and the // its size, the number of links referring to it, and the
// list of blocks holding the file's content. // list of blocks holding the file's content.
// //
// The inodes are laid out sequentially on disk immediately after // The inodes are laid out sequentially on disk at
// the superblock. Each inode has a number, indicating its // sb.startinode. Each inode has a number, indicating its
// position on the disk. // position on the disk.
// //
// The kernel keeps a cache of in-use inodes in memory // The kernel keeps a cache of in-use inodes in memory
...@@ -162,9 +160,12 @@ struct { ...@@ -162,9 +160,12 @@ struct {
} icache; } icache;
void void
iinit(void) iinit(int dev)
{ {
initlock(&icache.lock, "icache"); 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); static struct inode* iget(uint dev, uint inum);
...@@ -178,12 +179,9 @@ ialloc(uint dev, short type) ...@@ -178,12 +179,9 @@ ialloc(uint dev, short type)
int inum; int inum;
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
struct superblock sb;
readsb(dev, &sb);
for(inum = 1; inum < sb.ninodes; inum++){ 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; dip = (struct dinode*)bp->data + inum%IPB;
if(dip->type == 0){ // a free inode if(dip->type == 0){ // a free inode
memset(dip, 0, sizeof(*dip)); memset(dip, 0, sizeof(*dip));
...@@ -204,7 +202,7 @@ iupdate(struct inode *ip) ...@@ -204,7 +202,7 @@ iupdate(struct inode *ip)
struct buf *bp; struct buf *bp;
struct dinode *dip; 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 = (struct dinode*)bp->data + ip->inum%IPB;
dip->type = ip->type; dip->type = ip->type;
dip->major = ip->major; dip->major = ip->major;
...@@ -281,7 +279,7 @@ ilock(struct inode *ip) ...@@ -281,7 +279,7 @@ ilock(struct inode *ip)
release(&icache.lock); release(&icache.lock);
if(!(ip->flags & I_VALID)){ 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; dip = (struct dinode*)bp->data + ip->inum%IPB;
ip->type = dip->type; ip->type = dip->type;
ip->major = dip->major; ip->major = dip->major;
......
// On-disk file system format. // On-disk file system format.
// Both the kernel and user programs use this header file. // 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 ROOTINO 1 // root i-number
#define BSIZE 512 // block size #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 { struct superblock {
uint size; // Size of file system image (blocks) uint size; // Size of file system image (blocks)
uint nblocks; // Number of data blocks uint nblocks; // Number of data blocks
uint ninodes; // Number of inodes. uint ninodes; // Number of inodes.
uint nlog; // Number of log blocks 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 #define NDIRECT 12
...@@ -37,13 +38,13 @@ struct dinode { ...@@ -37,13 +38,13 @@ struct dinode {
#define IPB (BSIZE / sizeof(struct dinode)) #define IPB (BSIZE / sizeof(struct dinode))
// Block containing inode i // Block containing inode i
#define IBLOCK(i) ((i) / IPB + 2) #define IBLOCK(i, sb) ((i) / IPB + sb.inodestart)
// Bitmap bits per block // Bitmap bits per block
#define BPB (BSIZE*8) #define BPB (BSIZE*8)
// Block containing bit for block b // Block of free map containing bit for block b
#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) #define BBLOCK(b, sb) (b/BPB + sb.bmapstart)
// Directory is a file containing a sequence of dirent structures. // Directory is a file containing a sequence of dirent structures.
#define DIRSIZ 14 #define DIRSIZ 14
......
...@@ -50,17 +50,17 @@ static void recover_from_log(void); ...@@ -50,17 +50,17 @@ static void recover_from_log(void);
static void commit(); static void commit();
void void
initlog(void) initlog(int dev)
{ {
if (sizeof(struct logheader) >= BSIZE) if (sizeof(struct logheader) >= BSIZE)
panic("initlog: too big logheader"); panic("initlog: too big logheader");
struct superblock sb; struct superblock sb;
initlock(&log.lock, "log"); initlock(&log.lock, "log");
readsb(ROOTDEV, &sb); readsb(dev, &sb);
log.start = sb.size - sb.nlog; log.start = sb.logstart;
log.size = sb.nlog; log.size = sb.nlog;
log.dev = ROOTDEV; log.dev = dev;
recover_from_log(); recover_from_log();
} }
......
...@@ -31,7 +31,6 @@ main(void) ...@@ -31,7 +31,6 @@ main(void)
tvinit(); // trap vectors tvinit(); // trap vectors
binit(); // buffer cache binit(); // buffer cache
fileinit(); // file table fileinit(); // file table
iinit(); // inode cache
ideinit(); // disk ideinit(); // disk
if(!ismp) if(!ismp)
timerinit(); // uniprocessor timer timerinit(); // uniprocessor timer
......
...@@ -16,12 +16,12 @@ ...@@ -16,12 +16,12 @@
#define NINODES 200 #define NINODES 200
// Disk layout: // 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 nbitmap = FSSIZE/(BSIZE*8) + 1;
int ninodeblocks = NINODES / IPB + 1; int ninodeblocks = NINODES / IPB + 1;
int nlog = LOGSIZE; 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 nblocks; // Number of data blocks
int fsfd; int fsfd;
...@@ -88,15 +88,20 @@ main(int argc, char *argv[]) ...@@ -88,15 +88,20 @@ main(int argc, char *argv[])
exit(1); exit(1);
} }
nmeta = 2 + ninodeblocks + nbitmap; // 1 fs block = 1 disk sector
nblocks = FSSIZE - nlog - nmeta; nmeta = 2 + nlog + ninodeblocks + nbitmap;
nblocks = FSSIZE - nmeta;
sb.size = xint(FSSIZE); sb.size = xint(FSSIZE);
sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.nblocks = xint(nblocks);
sb.ninodes = xint(NINODES); sb.ninodes = xint(NINODES);
sb.nlog = xint(nlog); 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 freeblock = nmeta; // the first free block that we can allocate
...@@ -180,7 +185,7 @@ winode(uint inum, struct dinode *ip) ...@@ -180,7 +185,7 @@ winode(uint inum, struct dinode *ip)
uint bn; uint bn;
struct dinode *dip; struct dinode *dip;
bn = IBLOCK(inum); bn = IBLOCK(inum, sb);
rsect(bn, buf); rsect(bn, buf);
dip = ((struct dinode*)buf) + (inum % IPB); dip = ((struct dinode*)buf) + (inum % IPB);
*dip = *ip; *dip = *ip;
...@@ -194,7 +199,7 @@ rinode(uint inum, struct dinode *ip) ...@@ -194,7 +199,7 @@ rinode(uint inum, struct dinode *ip)
uint bn; uint bn;
struct dinode *dip; struct dinode *dip;
bn = IBLOCK(inum); bn = IBLOCK(inum, sb);
rsect(bn, buf); rsect(bn, buf);
dip = ((struct dinode*)buf) + (inum % IPB); dip = ((struct dinode*)buf) + (inum % IPB);
*ip = *dip; *ip = *dip;
...@@ -239,8 +244,8 @@ balloc(int used) ...@@ -239,8 +244,8 @@ balloc(int used)
for(i = 0; i < used; i++){ for(i = 0; i < used; i++){
buf[i/8] = buf[i/8] | (0x1 << (i%8)); buf[i/8] = buf[i/8] | (0x1 << (i%8));
} }
printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2); printf("balloc: write bitmap block at sector %d\n", sb.bmapstart);
wsect(ninodeblocks+2, buf); wsect(sb.bmapstart, buf);
} }
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
...@@ -256,8 +261,8 @@ iappend(uint inum, void *xp, int n) ...@@ -256,8 +261,8 @@ iappend(uint inum, void *xp, int n)
uint x; uint x;
rinode(inum, &din); rinode(inum, &din);
off = xint(din.size); off = xint(din.size);
// printf("append inum %d at off %d sz %d\n", inum, off, n);
while(n > 0){ while(n > 0){
fbn = off / BSIZE; fbn = off / BSIZE;
assert(fbn < MAXFILE); assert(fbn < MAXFILE);
...@@ -268,10 +273,8 @@ iappend(uint inum, void *xp, int n) ...@@ -268,10 +273,8 @@ iappend(uint inum, void *xp, int n)
x = xint(din.addrs[fbn]); x = xint(din.addrs[fbn]);
} else { } else {
if(xint(din.addrs[NDIRECT]) == 0){ if(xint(din.addrs[NDIRECT]) == 0){
// printf("allocate indirect block\n");
din.addrs[NDIRECT] = xint(freeblock++); din.addrs[NDIRECT] = xint(freeblock++);
} }
// printf("read indirect block\n");
rsect(xint(din.addrs[NDIRECT]), (char*)indirect); rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
if(indirect[fbn - NDIRECT] == 0){ if(indirect[fbn - NDIRECT] == 0){
indirect[fbn - NDIRECT] = xint(freeblock++); indirect[fbn - NDIRECT] = xint(freeblock++);
......
...@@ -339,7 +339,8 @@ forkret(void) ...@@ -339,7 +339,8 @@ forkret(void)
// of a regular process (e.g., they call sleep), and thus cannot // of a regular process (e.g., they call sleep), and thus cannot
// be run from main(). // be run from main().
first = 0; first = 0;
initlog(); iinit(ROOTDEV);
initlog(ROOTDEV);
} }
// Return to "caller", actually trapret (see allocproc). // Return to "caller", actually trapret (see allocproc).
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论