block bitmap

balloc
This commit is contained in:
kaashoek 2006-08-09 01:09:36 +00:00
parent 0e84a0ec6e
commit 241113985f
3 changed files with 103 additions and 30 deletions

74
fs.c
View file

@ -16,6 +16,43 @@ struct spinlock inode_table_lock = { "inode_table" };
uint rootdev = 1;
static uint
balloc(uint dev)
{
int b;
struct buf *bp;
struct superblock *sb;
int bi;
int size;
int ninodes;
uchar m;
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?
break;
}
}
if (b >= size)
panic("balloc: out of blocks\n");
cprintf ("balloc: allocate block %d\n", b);
bp->data[bi/8] |= 0x1 << (bi % 8);
bwrite (dev, bp, BBLOCK(b, ninodes)); // mark it allocated on disk
return b;
}
// returns an inode with busy set and incremented reference count.
struct inode *
iget(uint dev, uint inum)
@ -51,7 +88,7 @@ iget(uint dev, uint inum)
release(&inode_table_lock);
bp = bread(dev, inum / IPB + 2);
bp = bread(dev, IBLOCK(inum));
dip = &((struct dinode *)(bp->data))[inum % IPB];
nip->type = dip->type;
nip->major = dip->major;
@ -76,12 +113,12 @@ ialloc(uint dev, short type)
struct buf *bp;
bp = bread(dev, 1);
sb = (struct superblock *) bp;
sb = (struct superblock *) bp->data;
ninodes = sb->ninodes;
brelse(bp);
for (inum = 1; inum < ninodes; inum++) { // loop over inode blocks
bp = bread(dev, inum / IPB + 2);
bp = bread(dev, IBLOCK(inum));
dip = &((struct dinode *)(bp->data))[inum % IPB];
if (dip->type == 0) { // a free inode
break;
@ -90,13 +127,12 @@ ialloc(uint dev, short type)
}
if (inum >= ninodes) {
cprintf ("ialloc: no inodes left\n");
return 0;
panic ("ialloc: no inodes left\n");
}
cprintf ("ialloc: %d\n", inum);
dip->type = type;
bwrite (dev, bp, inum / IPB + 2); // mark it allocated on the disk
bwrite (dev, bp, IBLOCK(inum)); // mark it allocated on the disk
brelse(bp);
ip = iget (dev, inum);
return ip;
@ -108,14 +144,14 @@ iupdate (struct inode *ip)
struct buf *bp;
struct dinode *dip;
bp = bread(ip->dev, ip->inum / IPB + 2);
bp = bread(ip->dev, IBLOCK(ip->inum));
dip = &((struct dinode *)(bp->data))[ip->inum % IPB];
dip->type = ip->type;
dip->major = ip->major;
dip->minor = ip->minor;
dip->nlink = ip->nlink;
dip->size = ip->size;
bwrite (ip->dev, bp, ip->inum / IPB + 2); // mark it allocated on the disk
bwrite (ip->dev, bp, IBLOCK(ip->inum)); // mark it allocated on the disk
brelse(bp);
}
@ -203,10 +239,10 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
struct buf *bp;
while(n > 0 && off < ip->size){
bp = bread(ip->dev, bmap(ip, off / 512));
bp = bread(ip->dev, bmap(ip, off / BSIZE));
n1 = min(n, ip->size - off);
n1 = min(n1, 512 - (off % 512));
memmove(dst, bp->data + (off % 512), n1);
n1 = min(n1, BSIZE - (off % BSIZE));
memmove(dst, bp->data + (off % BSIZE), n1);
n -= n1;
off += n1;
dst += n1;
@ -241,10 +277,10 @@ namei(char *path)
return 0;
}
for(off = 0; off < dp->size; off += 512){
bp = bread(dp->dev, bmap(dp, off / 512));
for(off = 0; off < dp->size; off += BSIZE){
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + 512);
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0)
continue;
@ -288,10 +324,10 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
ip->major = major;
ip->minor = minor;
for(off = 0; off < dp->size; off += 512) {
bp = bread(dp->dev, bmap(dp, off / 512));
for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + 512);
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == 0) {
goto found;
@ -304,7 +340,7 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
found:
ep->inum = ip->inum;
for(i = 0; i < DIRSIZ && cp[i]; i++) ep->name[i] = cp[i];
bwrite (dp->dev, bp, bmap(dp, off/512)); // write directory
bwrite (dp->dev, bp, bmap(dp, off/BSIZE)); // write directory
brelse(bp);
iupdate (ip);
return ip;

17
fs.h
View file

@ -1,15 +1,16 @@
// on-disk file system format
// second sector
#define BSIZE 512 // block size
// sector 1 (2nd sector)
struct superblock{
int nblocks;
int ninodes;
uint size;
uint nblocks;
uint ninodes;
};
#define NDIRECT 13
// inodes start at the third sector
// and blocks start at (ninodes * sizeof(dinode) + 511) / 512
struct dinode {
short type;
short major;
@ -23,7 +24,11 @@ struct dinode {
#define T_FILE 2
#define T_DEV 3
#define IPB (512 / sizeof(struct dinode))
// sector 0 is unused, sector 1 is superblock, inodes start at sector 2
#define IPB (BSIZE / sizeof(struct dinode))
#define IBLOCK(inum) (inum / IPB + 2) // start of inode
#define BPB (BSIZE*8)
#define BBLOCK(b,ninodes) (b/BPB + (ninodes/IPB) + 3) // start of bitmap
#define DIRSIZ 14

42
mkfs.c
View file

@ -8,15 +8,19 @@
#include "param.h"
#include "fs.h"
int nblocks = 1009;
int nblocks = 1008;
int ninodes = 100;
int size = 1024;
int fsfd;
struct superblock sb;
char zeroes[512];
uint freeblock;
uint usedblocks;
uint bitblocks;
uint freeinode = 1;
void balloc(int);
void wsect(uint, void *);
void winode(uint, struct dinode *);
void rsect(uint sec, void *buf);
@ -67,12 +71,20 @@ main(int argc, char *argv[])
exit(1);
}
sb.nblocks = xint(nblocks); // so whole disk is 1024 sectors
sb.size = xint(size);
sb.nblocks = xint(nblocks); // so whole disk is size sectors
sb.ninodes = xint(ninodes);
freeblock = ninodes / IPB + 2;
bitblocks = sb.size/(512*8) + 1;
usedblocks = ninodes / IPB + 3 + bitblocks;
freeblock = usedblocks;
for(i = 0; i < nblocks + (ninodes / IPB) + 3; i++)
printf ("used %d (bit %d ninode %d) free %d total %d\n", usedblocks,
bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks);
assert (nblocks + usedblocks == size);
for(i = 0; i < nblocks + usedblocks; i++)
wsect(i, zeroes);
wsect(1, &sb);
@ -110,6 +122,8 @@ main(int argc, char *argv[])
close(fd);
}
balloc(usedblocks);
exit(0);
}
@ -186,6 +200,22 @@ ialloc(ushort type)
return inum;
}
void
balloc(int used)
{
uchar buf[512];
int i;
printf("balloc: first %d blocks have been allocated\n", used);
assert (used < 512);
bzero(buf, 512);
for (i = 0; i < used; i++) {
buf[i/8] = buf[i/8] | (0x1 << (i%8));
}
printf("balloc: write bitmap block at sector %d\n", ninodes/IPB + 3);
wsect(ninodes / IPB + 3, buf);
}
#define min(a, b) ((a) < (b) ? (a) : (b))
void
@ -202,8 +232,10 @@ iappend(uint inum, void *xp, int n)
while(n > 0){
fbn = off / 512;
assert(fbn < NDIRECT);
if(din.addrs[fbn] == 0)
if(din.addrs[fbn] == 0) {
din.addrs[fbn] = xint(freeblock++);
usedblocks++;
}
n1 = min(n, (fbn + 1) * 512 - off);
rsect(xint(din.addrs[fbn]), buf);
bcopy(p, buf + off - (fbn * 512), n1);