FS cleanup.

Add utility routines bzero, readsb so that balloc, bfree fit on one page.
Make balloc loop clearer.
This commit is contained in:
rsc 2007-08-27 14:20:24 +00:00
parent d003d232fc
commit a505fd6651

96
fs.c
View file

@ -1,6 +1,4 @@
// File system implementation. // File system implementation. Four layers:
//
// Four layers:
// + Blocks: allocator for raw disk blocks. // + Blocks: allocator for raw disk blocks.
// + Files: inode allocator, reading, writing, metadata. // + Files: inode allocator, reading, writing, metadata.
// + Directories: inode with special contents (list of other inodes!) // + Directories: inode with special contents (list of other inodes!)
@ -28,34 +26,53 @@
#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*);
// Read the super block.
static void
readsb(int dev, struct superblock *sb)
{
struct buf *bp;
bp = bread(dev, 1);
memmove(sb, bp->data, sizeof(*sb));
brelse(bp);
}
// Zero a block.
static void
bzero(int dev, int bno)
{
struct buf *bp;
bp = bread(dev, bno);
memset(bp->data, 0, BSIZE);
bwrite(bp);
brelse(bp);
}
// Blocks. // Blocks.
// Allocate a disk block. // Allocate a disk block.
static uint static uint
balloc(uint dev) balloc(uint dev)
{ {
int b, bi, m, ninodes, size; int b, bi, m;
struct buf *bp; struct buf *bp;
struct superblock *sb; struct superblock sb;
bp = bread(dev, 1); bp = 0;
sb = (struct superblock*) bp->data; readsb(dev, &sb);
size = sb->size; for(b = 0; b < sb.size; b += BPB){
ninodes = sb->ninodes; bp = bread(dev, BBLOCK(b, sb.ninodes));
for(bi = 0; bi < BPB; bi++){
for(b = 0; b < size; b++) { m = 1 << (bi % 8);
if(b % BPB == 0) { if((bp->data[bi/8] & m) == 0){ // Is block free?
brelse(bp); bp->data[bi/8] |= m; // Mark block in use on disk.
bp = bread(dev, BBLOCK(b, ninodes)); bwrite(bp);
} brelse(bp);
bi = b % BPB; return b + bi;
m = 0x1 << (bi % 8); }
if((bp->data[bi/8] & m) == 0) { // is block free?
bp->data[bi/8] |= m;
bwrite(bp); // mark it allocated on disk
brelse(bp);
return b;
} }
brelse(bp);
} }
panic("balloc: out of blocks"); panic("balloc: out of blocks");
} }
@ -65,26 +82,19 @@ static void
bfree(int dev, uint b) bfree(int dev, uint b)
{ {
struct buf *bp; struct buf *bp;
struct superblock *sb; struct superblock sb;
int bi, m, ninodes; int bi, m;
bp = bread(dev, 1); bzero(dev, b);
sb = (struct superblock*) bp->data;
ninodes = sb->ninodes;
brelse(bp);
bp = bread(dev, b); readsb(dev, &sb);
memset(bp->data, 0, BSIZE); bp = bread(dev, BBLOCK(b, sb.ninodes));
bwrite(bp);
brelse(bp);
bp = bread(dev, BBLOCK(b, ninodes));
bi = b % BPB; bi = b % BPB;
m = 0x1 << (bi % 8); m = 1 << (bi % 8);
if((bp->data[bi/8] & m) == 0) if((bp->data[bi/8] & m) == 0)
panic("freeing free block"); panic("freeing free block");
bp->data[bi/8] &= ~m; bp->data[bi/8] &= ~m; // Mark block free on disk.
bwrite(bp); // mark it free on disk bwrite(bp);
brelse(bp); brelse(bp);
} }
@ -252,17 +262,13 @@ iunlockput(struct inode *ip)
struct inode* struct inode*
ialloc(uint dev, short type) ialloc(uint dev, short type)
{ {
int inum, ninodes; int inum;
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
struct superblock *sb; struct superblock sb;
bp = bread(dev, 1); readsb(dev, &sb);
sb = (struct superblock*)bp->data; for(inum = 1; inum < sb.ninodes; inum++) { // loop over inode blocks
ninodes = sb->ninodes;
brelse(bp);
for(inum = 1; inum < ninodes; inum++) { // loop over inode blocks
bp = bread(dev, IBLOCK(inum)); bp = bread(dev, IBLOCK(inum));
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