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.feat/start
parent
de4af193c8
commit
8320d61be5
4
defs.h
4
defs.h
|
|
@ -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);
|
||||||
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();
|
||||||
|
|
|
||||||
26
fs.c
26
fs.c
|
|
@ -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)
|
||||||
{
|
{
|
||||||
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
|
||||||
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)
|
||||||
// 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 {
|
||||||
} 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)
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
|
|
|
||||||
21
fs.h
21
fs.h
|
|
@ -1,22 +1,23 @@
|
||||||
// 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 {
|
||||||
#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
|
||||||
|
|
|
||||||
8
log.c
8
log.c
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
main.c
1
main.c
|
|
@ -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
|
||||||
|
|
|
||||||
29
mkfs.c
29
mkfs.c
|
|
@ -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[])
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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++);
|
||||||
|
|
|
||||||
3
proc.c
3
proc.c
|
|
@ -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).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue