FS cleanup.
Add utility routines bzero, readsb so that balloc, bfree fit on one page. Make balloc loop clearer.
This commit is contained in:
parent
d003d232fc
commit
a505fd6651
1 changed files with 51 additions and 45 deletions
92
fs.c
92
fs.c
|
@ -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?
|
||||||
|
bp->data[bi/8] |= m; // Mark block in use on disk.
|
||||||
|
bwrite(bp);
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
bp = bread(dev, BBLOCK(b, ninodes));
|
return b + bi;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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);
|
brelse(bp);
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue