block bitmap
balloc
This commit is contained in:
parent
0e84a0ec6e
commit
241113985f
3 changed files with 103 additions and 30 deletions
74
fs.c
74
fs.c
|
@ -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
17
fs.h
|
@ -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
42
mkfs.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue