block bitmap
balloc
This commit is contained in:
parent
0e84a0ec6e
commit
241113985f
3 changed files with 103 additions and 30 deletions
72
fs.c
72
fs.c
|
@ -16,6 +16,43 @@ struct spinlock inode_table_lock = { "inode_table" };
|
||||||
|
|
||||||
uint rootdev = 1;
|
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.
|
// returns an inode with busy set and incremented reference count.
|
||||||
struct inode *
|
struct inode *
|
||||||
iget(uint dev, uint inum)
|
iget(uint dev, uint inum)
|
||||||
|
@ -51,7 +88,7 @@ iget(uint dev, uint inum)
|
||||||
|
|
||||||
release(&inode_table_lock);
|
release(&inode_table_lock);
|
||||||
|
|
||||||
bp = bread(dev, inum / IPB + 2);
|
bp = bread(dev, IBLOCK(inum));
|
||||||
dip = &((struct dinode *)(bp->data))[inum % IPB];
|
dip = &((struct dinode *)(bp->data))[inum % IPB];
|
||||||
nip->type = dip->type;
|
nip->type = dip->type;
|
||||||
nip->major = dip->major;
|
nip->major = dip->major;
|
||||||
|
@ -76,12 +113,12 @@ ialloc(uint dev, short type)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
bp = bread(dev, 1);
|
bp = bread(dev, 1);
|
||||||
sb = (struct superblock *) bp;
|
sb = (struct superblock *) bp->data;
|
||||||
ninodes = sb->ninodes;
|
ninodes = sb->ninodes;
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
|
||||||
for (inum = 1; inum < ninodes; inum++) { // loop over inode blocks
|
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];
|
dip = &((struct dinode *)(bp->data))[inum % IPB];
|
||||||
if (dip->type == 0) { // a free inode
|
if (dip->type == 0) { // a free inode
|
||||||
break;
|
break;
|
||||||
|
@ -90,13 +127,12 @@ ialloc(uint dev, short type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inum >= ninodes) {
|
if (inum >= ninodes) {
|
||||||
cprintf ("ialloc: no inodes left\n");
|
panic ("ialloc: no inodes left\n");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cprintf ("ialloc: %d\n", inum);
|
cprintf ("ialloc: %d\n", inum);
|
||||||
dip->type = type;
|
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);
|
brelse(bp);
|
||||||
ip = iget (dev, inum);
|
ip = iget (dev, inum);
|
||||||
return ip;
|
return ip;
|
||||||
|
@ -108,14 +144,14 @@ iupdate (struct inode *ip)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
struct dinode *dip;
|
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 = &((struct dinode *)(bp->data))[ip->inum % IPB];
|
||||||
dip->type = ip->type;
|
dip->type = ip->type;
|
||||||
dip->major = ip->major;
|
dip->major = ip->major;
|
||||||
dip->minor = ip->minor;
|
dip->minor = ip->minor;
|
||||||
dip->nlink = ip->nlink;
|
dip->nlink = ip->nlink;
|
||||||
dip->size = ip->size;
|
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);
|
brelse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,10 +239,10 @@ readi(struct inode *ip, void *xdst, uint off, uint n)
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
while(n > 0 && off < ip->size){
|
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(n, ip->size - off);
|
||||||
n1 = min(n1, 512 - (off % 512));
|
n1 = min(n1, BSIZE - (off % BSIZE));
|
||||||
memmove(dst, bp->data + (off % 512), n1);
|
memmove(dst, bp->data + (off % BSIZE), n1);
|
||||||
n -= n1;
|
n -= n1;
|
||||||
off += n1;
|
off += n1;
|
||||||
dst += n1;
|
dst += n1;
|
||||||
|
@ -241,10 +277,10 @@ namei(char *path)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(off = 0; off < dp->size; off += 512){
|
for(off = 0; off < dp->size; off += BSIZE){
|
||||||
bp = bread(dp->dev, bmap(dp, off / 512));
|
bp = bread(dp->dev, bmap(dp, off / BSIZE));
|
||||||
for(ep = (struct dirent *) bp->data;
|
for(ep = (struct dirent *) bp->data;
|
||||||
ep < (struct dirent *) (bp->data + 512);
|
ep < (struct dirent *) (bp->data + BSIZE);
|
||||||
ep++){
|
ep++){
|
||||||
if(ep->inum == 0)
|
if(ep->inum == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -288,10 +324,10 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
|
||||||
ip->major = major;
|
ip->major = major;
|
||||||
ip->minor = minor;
|
ip->minor = minor;
|
||||||
|
|
||||||
for(off = 0; off < dp->size; off += 512) {
|
for(off = 0; off < dp->size; off += BSIZE) {
|
||||||
bp = bread(dp->dev, bmap(dp, off / 512));
|
bp = bread(dp->dev, bmap(dp, off / BSIZE));
|
||||||
for(ep = (struct dirent *) bp->data;
|
for(ep = (struct dirent *) bp->data;
|
||||||
ep < (struct dirent *) (bp->data + 512);
|
ep < (struct dirent *) (bp->data + BSIZE);
|
||||||
ep++){
|
ep++){
|
||||||
if(ep->inum == 0) {
|
if(ep->inum == 0) {
|
||||||
goto found;
|
goto found;
|
||||||
|
@ -304,7 +340,7 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
|
||||||
found:
|
found:
|
||||||
ep->inum = ip->inum;
|
ep->inum = ip->inum;
|
||||||
for(i = 0; i < DIRSIZ && cp[i]; i++) ep->name[i] = cp[i];
|
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);
|
brelse(bp);
|
||||||
iupdate (ip);
|
iupdate (ip);
|
||||||
return ip;
|
return ip;
|
||||||
|
|
17
fs.h
17
fs.h
|
@ -1,15 +1,16 @@
|
||||||
// on-disk file system format
|
// on-disk file system format
|
||||||
|
|
||||||
// second sector
|
#define BSIZE 512 // block size
|
||||||
|
|
||||||
|
// sector 1 (2nd sector)
|
||||||
struct superblock{
|
struct superblock{
|
||||||
int nblocks;
|
uint size;
|
||||||
int ninodes;
|
uint nblocks;
|
||||||
|
uint ninodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NDIRECT 13
|
#define NDIRECT 13
|
||||||
|
|
||||||
// inodes start at the third sector
|
|
||||||
// and blocks start at (ninodes * sizeof(dinode) + 511) / 512
|
|
||||||
struct dinode {
|
struct dinode {
|
||||||
short type;
|
short type;
|
||||||
short major;
|
short major;
|
||||||
|
@ -23,7 +24,11 @@ struct dinode {
|
||||||
#define T_FILE 2
|
#define T_FILE 2
|
||||||
#define T_DEV 3
|
#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
|
#define DIRSIZ 14
|
||||||
|
|
||||||
|
|
42
mkfs.c
42
mkfs.c
|
@ -8,15 +8,19 @@
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
int nblocks = 1009;
|
int nblocks = 1008;
|
||||||
int ninodes = 100;
|
int ninodes = 100;
|
||||||
|
int size = 1024;
|
||||||
|
|
||||||
int fsfd;
|
int fsfd;
|
||||||
struct superblock sb;
|
struct superblock sb;
|
||||||
char zeroes[512];
|
char zeroes[512];
|
||||||
uint freeblock;
|
uint freeblock;
|
||||||
|
uint usedblocks;
|
||||||
|
uint bitblocks;
|
||||||
uint freeinode = 1;
|
uint freeinode = 1;
|
||||||
|
|
||||||
|
void balloc(int);
|
||||||
void wsect(uint, void *);
|
void wsect(uint, void *);
|
||||||
void winode(uint, struct dinode *);
|
void winode(uint, struct dinode *);
|
||||||
void rsect(uint sec, void *buf);
|
void rsect(uint sec, void *buf);
|
||||||
|
@ -67,12 +71,20 @@ main(int argc, char *argv[])
|
||||||
exit(1);
|
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);
|
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(i, zeroes);
|
||||||
|
|
||||||
wsect(1, &sb);
|
wsect(1, &sb);
|
||||||
|
@ -110,6 +122,8 @@ main(int argc, char *argv[])
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
balloc(usedblocks);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +200,22 @@ ialloc(ushort type)
|
||||||
return inum;
|
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))
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -202,8 +232,10 @@ iappend(uint inum, void *xp, int n)
|
||||||
while(n > 0){
|
while(n > 0){
|
||||||
fbn = off / 512;
|
fbn = off / 512;
|
||||||
assert(fbn < NDIRECT);
|
assert(fbn < NDIRECT);
|
||||||
if(din.addrs[fbn] == 0)
|
if(din.addrs[fbn] == 0) {
|
||||||
din.addrs[fbn] = xint(freeblock++);
|
din.addrs[fbn] = xint(freeblock++);
|
||||||
|
usedblocks++;
|
||||||
|
}
|
||||||
n1 = min(n, (fbn + 1) * 512 - off);
|
n1 = min(n, (fbn + 1) * 512 - off);
|
||||||
rsect(xint(din.addrs[fbn]), buf);
|
rsect(xint(din.addrs[fbn]), buf);
|
||||||
bcopy(p, buf + off - (fbn * 512), n1);
|
bcopy(p, buf + off - (fbn * 512), n1);
|
||||||
|
|
Loading…
Reference in a new issue