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