Disentangle block size from the disk's sector size. Set block size to 1024 to show
that they can be different. Clean up mkfs, simplifying specifying fs parameters, remove some redundancy between fs and mkfs, and fix disk layout bugs. Call blocks in the file system blocks instead of sectors. Passes usertests for different block sizes.
This commit is contained in:
parent
7443b9649a
commit
c24ac5d763
11 changed files with 91 additions and 86 deletions
20
bio.c
20
bio.c
|
@ -24,6 +24,7 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
#include "fs.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -55,20 +56,20 @@ binit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look through buffer cache for sector on device dev.
|
// Look through buffer cache for block on device dev.
|
||||||
// If not found, allocate a buffer.
|
// If not found, allocate a buffer.
|
||||||
// In either case, return B_BUSY buffer.
|
// In either case, return B_BUSY buffer.
|
||||||
static struct buf*
|
static struct buf*
|
||||||
bget(uint dev, uint sector)
|
bget(uint dev, uint blockno)
|
||||||
{
|
{
|
||||||
struct buf *b;
|
struct buf *b;
|
||||||
|
|
||||||
acquire(&bcache.lock);
|
acquire(&bcache.lock);
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
// Is the sector already cached?
|
// Is the block already cached?
|
||||||
for(b = bcache.head.next; b != &bcache.head; b = b->next){
|
for(b = bcache.head.next; b != &bcache.head; b = b->next){
|
||||||
if(b->dev == dev && b->sector == sector){
|
if(b->dev == dev && b->blockno == blockno){
|
||||||
if(!(b->flags & B_BUSY)){
|
if(!(b->flags & B_BUSY)){
|
||||||
b->flags |= B_BUSY;
|
b->flags |= B_BUSY;
|
||||||
release(&bcache.lock);
|
release(&bcache.lock);
|
||||||
|
@ -85,7 +86,7 @@ bget(uint dev, uint sector)
|
||||||
for(b = bcache.head.prev; b != &bcache.head; b = b->prev){
|
for(b = bcache.head.prev; b != &bcache.head; b = b->prev){
|
||||||
if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){
|
if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){
|
||||||
b->dev = dev;
|
b->dev = dev;
|
||||||
b->sector = sector;
|
b->blockno = blockno;
|
||||||
b->flags = B_BUSY;
|
b->flags = B_BUSY;
|
||||||
release(&bcache.lock);
|
release(&bcache.lock);
|
||||||
return b;
|
return b;
|
||||||
|
@ -94,15 +95,16 @@ bget(uint dev, uint sector)
|
||||||
panic("bget: no buffers");
|
panic("bget: no buffers");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a B_BUSY buf with the contents of the indicated disk sector.
|
// Return a B_BUSY buf with the contents of the indicated block.
|
||||||
struct buf*
|
struct buf*
|
||||||
bread(uint dev, uint sector)
|
bread(uint dev, uint blockno)
|
||||||
{
|
{
|
||||||
struct buf *b;
|
struct buf *b;
|
||||||
|
|
||||||
b = bget(dev, sector);
|
b = bget(dev, blockno);
|
||||||
if(!(b->flags & B_VALID))
|
if(!(b->flags & B_VALID)) {
|
||||||
iderw(b);
|
iderw(b);
|
||||||
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Boot loader.
|
// Boot loader.
|
||||||
//
|
//
|
||||||
// Part of the boot sector, along with bootasm.S, which calls bootmain().
|
// Part of the boot block, along with bootasm.S, which calls bootmain().
|
||||||
// bootasm.S has put the processor into protected 32-bit mode.
|
// bootasm.S has put the processor into protected 32-bit mode.
|
||||||
// bootmain() loads an ELF kernel image from the disk starting at
|
// bootmain() loads an ELF kernel image from the disk starting at
|
||||||
// sector 1 and then jumps to the kernel entry routine.
|
// sector 1 and then jumps to the kernel entry routine.
|
||||||
|
|
4
buf.h
4
buf.h
|
@ -1,11 +1,11 @@
|
||||||
struct buf {
|
struct buf {
|
||||||
int flags;
|
int flags;
|
||||||
uint dev;
|
uint dev;
|
||||||
uint sector;
|
uint blockno;
|
||||||
struct buf *prev; // LRU cache list
|
struct buf *prev; // LRU cache list
|
||||||
struct buf *next;
|
struct buf *next;
|
||||||
struct buf *qnext; // disk queue
|
struct buf *qnext; // disk queue
|
||||||
uchar data[512];
|
uchar data[BSIZE];
|
||||||
};
|
};
|
||||||
#define B_BUSY 0x1 // buffer is locked by some process
|
#define B_BUSY 0x1 // buffer is locked by some process
|
||||||
#define B_VALID 0x2 // buffer has been read from disk
|
#define B_VALID 0x2 // buffer has been read from disk
|
||||||
|
|
2
fs.c
2
fs.c
|
@ -16,8 +16,8 @@
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
#include "buf.h"
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include "buf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
2
fs.h
2
fs.h
|
@ -9,7 +9,7 @@
|
||||||
// Then sb.nlog log blocks.
|
// Then sb.nlog log blocks.
|
||||||
|
|
||||||
#define ROOTINO 1 // root i-number
|
#define ROOTINO 1 // root i-number
|
||||||
#define BSIZE 512 // block size
|
#define BSIZE 1024 // block size
|
||||||
|
|
||||||
// File system super block
|
// File system super block
|
||||||
struct superblock {
|
struct superblock {
|
||||||
|
|
20
ide.c
20
ide.c
|
@ -9,8 +9,10 @@
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "traps.h"
|
#include "traps.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
#include "fs.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
#define IDE_BSY 0x80
|
#define IDE_BSY 0x80
|
||||||
#define IDE_DRDY 0x40
|
#define IDE_DRDY 0x40
|
||||||
#define IDE_DF 0x20
|
#define IDE_DF 0x20
|
||||||
|
@ -71,17 +73,21 @@ idestart(struct buf *b)
|
||||||
{
|
{
|
||||||
if(b == 0)
|
if(b == 0)
|
||||||
panic("idestart");
|
panic("idestart");
|
||||||
|
int sector_per_block = BSIZE/SECTOR_SIZE;
|
||||||
|
int sector = b->blockno * sector_per_block;
|
||||||
|
|
||||||
|
if (sector_per_block > 7) panic("idestart");
|
||||||
|
|
||||||
idewait(0);
|
idewait(0);
|
||||||
outb(0x3f6, 0); // generate interrupt
|
outb(0x3f6, 0); // generate interrupt
|
||||||
outb(0x1f2, 1); // number of sectors
|
outb(0x1f2, sector_per_block); // number of sectors
|
||||||
outb(0x1f3, b->sector & 0xff);
|
outb(0x1f3, sector & 0xff);
|
||||||
outb(0x1f4, (b->sector >> 8) & 0xff);
|
outb(0x1f4, (sector >> 8) & 0xff);
|
||||||
outb(0x1f5, (b->sector >> 16) & 0xff);
|
outb(0x1f5, (sector >> 16) & 0xff);
|
||||||
outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((b->sector>>24)&0x0f));
|
outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((sector>>24)&0x0f));
|
||||||
if(b->flags & B_DIRTY){
|
if(b->flags & B_DIRTY){
|
||||||
outb(0x1f7, IDE_CMD_WRITE);
|
outb(0x1f7, IDE_CMD_WRITE);
|
||||||
outsl(0x1f0, b->data, 512/4);
|
outsl(0x1f0, b->data, BSIZE/4);
|
||||||
} else {
|
} else {
|
||||||
outb(0x1f7, IDE_CMD_READ);
|
outb(0x1f7, IDE_CMD_READ);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +110,7 @@ ideintr(void)
|
||||||
|
|
||||||
// Read data if needed.
|
// Read data if needed.
|
||||||
if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
|
if(!(b->flags & B_DIRTY) && idewait(1) >= 0)
|
||||||
insl(0x1f0, b->data, 512/4);
|
insl(0x1f0, b->data, BSIZE/4);
|
||||||
|
|
||||||
// Wake process waiting for this buf.
|
// Wake process waiting for this buf.
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
|
|
2
kill.c
2
kill.c
|
@ -7,7 +7,7 @@ main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(argc < 1){
|
if(argc < 2){
|
||||||
printf(2, "usage: kill pid...\n");
|
printf(2, "usage: kill pid...\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
18
log.c
18
log.c
|
@ -21,7 +21,7 @@
|
||||||
//
|
//
|
||||||
// The log is a physical re-do log containing disk blocks.
|
// The log is a physical re-do log containing disk blocks.
|
||||||
// The on-disk log format:
|
// The on-disk log format:
|
||||||
// header block, containing sector #s for block A, B, C, ...
|
// header block, containing block #s for block A, B, C, ...
|
||||||
// block A
|
// block A
|
||||||
// block B
|
// block B
|
||||||
// block C
|
// block C
|
||||||
|
@ -29,10 +29,10 @@
|
||||||
// Log appends are synchronous.
|
// Log appends are synchronous.
|
||||||
|
|
||||||
// Contents of the header block, used for both the on-disk header block
|
// Contents of the header block, used for both the on-disk header block
|
||||||
// and to keep track in memory of logged sector #s before commit.
|
// and to keep track in memory of logged block# before commit.
|
||||||
struct logheader {
|
struct logheader {
|
||||||
int n;
|
int n;
|
||||||
int sector[LOGSIZE];
|
int block[LOGSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct log {
|
struct log {
|
||||||
|
@ -72,7 +72,7 @@ install_trans(void)
|
||||||
|
|
||||||
for (tail = 0; tail < log.lh.n; tail++) {
|
for (tail = 0; tail < log.lh.n; tail++) {
|
||||||
struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block
|
struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block
|
||||||
struct buf *dbuf = bread(log.dev, log.lh.sector[tail]); // read dst
|
struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst
|
||||||
memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
|
memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
|
||||||
bwrite(dbuf); // write dst to disk
|
bwrite(dbuf); // write dst to disk
|
||||||
brelse(lbuf);
|
brelse(lbuf);
|
||||||
|
@ -89,7 +89,7 @@ read_head(void)
|
||||||
int i;
|
int i;
|
||||||
log.lh.n = lh->n;
|
log.lh.n = lh->n;
|
||||||
for (i = 0; i < log.lh.n; i++) {
|
for (i = 0; i < log.lh.n; i++) {
|
||||||
log.lh.sector[i] = lh->sector[i];
|
log.lh.block[i] = lh->block[i];
|
||||||
}
|
}
|
||||||
brelse(buf);
|
brelse(buf);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ write_head(void)
|
||||||
int i;
|
int i;
|
||||||
hb->n = log.lh.n;
|
hb->n = log.lh.n;
|
||||||
for (i = 0; i < log.lh.n; i++) {
|
for (i = 0; i < log.lh.n; i++) {
|
||||||
hb->sector[i] = log.lh.sector[i];
|
hb->block[i] = log.lh.block[i];
|
||||||
}
|
}
|
||||||
bwrite(buf);
|
bwrite(buf);
|
||||||
brelse(buf);
|
brelse(buf);
|
||||||
|
@ -178,7 +178,7 @@ write_log(void)
|
||||||
|
|
||||||
for (tail = 0; tail < log.lh.n; tail++) {
|
for (tail = 0; tail < log.lh.n; tail++) {
|
||||||
struct buf *to = bread(log.dev, log.start+tail+1); // log block
|
struct buf *to = bread(log.dev, log.start+tail+1); // log block
|
||||||
struct buf *from = bread(log.dev, log.lh.sector[tail]); // cache block
|
struct buf *from = bread(log.dev, log.lh.block[tail]); // cache block
|
||||||
memmove(to->data, from->data, BSIZE);
|
memmove(to->data, from->data, BSIZE);
|
||||||
bwrite(to); // write the log
|
bwrite(to); // write the log
|
||||||
brelse(from);
|
brelse(from);
|
||||||
|
@ -219,10 +219,10 @@ log_write(struct buf *b)
|
||||||
|
|
||||||
acquire(&log.lock);
|
acquire(&log.lock);
|
||||||
for (i = 0; i < log.lh.n; i++) {
|
for (i = 0; i < log.lh.n; i++) {
|
||||||
if (log.lh.sector[i] == b->sector) // log absorbtion
|
if (log.lh.block[i] == b->blockno) // log absorbtion
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
log.lh.sector[i] = b->sector;
|
log.lh.block[i] = b->blockno;
|
||||||
if (i == log.lh.n)
|
if (i == log.lh.n)
|
||||||
log.lh.n++;
|
log.lh.n++;
|
||||||
b->flags |= B_DIRTY; // prevent eviction
|
b->flags |= B_DIRTY; // prevent eviction
|
||||||
|
|
12
memide.c
12
memide.c
|
@ -20,7 +20,7 @@ void
|
||||||
ideinit(void)
|
ideinit(void)
|
||||||
{
|
{
|
||||||
memdisk = _binary_fs_img_start;
|
memdisk = _binary_fs_img_start;
|
||||||
disksize = (uint)_binary_fs_img_size/512;
|
disksize = (uint)_binary_fs_img_size/BSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt handler.
|
// Interrupt handler.
|
||||||
|
@ -44,15 +44,15 @@ iderw(struct buf *b)
|
||||||
panic("iderw: nothing to do");
|
panic("iderw: nothing to do");
|
||||||
if(b->dev != 1)
|
if(b->dev != 1)
|
||||||
panic("iderw: request not for disk 1");
|
panic("iderw: request not for disk 1");
|
||||||
if(b->sector >= disksize)
|
if(b->block >= disksize)
|
||||||
panic("iderw: sector out of range");
|
panic("iderw: block out of range");
|
||||||
|
|
||||||
p = memdisk + b->sector*512;
|
p = memdisk + b->block*BSIZE;
|
||||||
|
|
||||||
if(b->flags & B_DIRTY){
|
if(b->flags & B_DIRTY){
|
||||||
b->flags &= ~B_DIRTY;
|
b->flags &= ~B_DIRTY;
|
||||||
memmove(p, b->data, 512);
|
memmove(p, b->data, BSIZE);
|
||||||
} else
|
} else
|
||||||
memmove(b->data, p, 512);
|
memmove(b->data, p, BSIZE);
|
||||||
b->flags |= B_VALID;
|
b->flags |= B_VALID;
|
||||||
}
|
}
|
||||||
|
|
91
mkfs.c
91
mkfs.c
|
@ -13,18 +13,24 @@
|
||||||
|
|
||||||
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0)
|
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0)
|
||||||
|
|
||||||
int nblocks = (995-LOGSIZE);
|
#define SIZE 1000
|
||||||
|
#define NINODES 200
|
||||||
|
|
||||||
|
// Disk layout:
|
||||||
|
// [ boot block | sb block | inode blocks | bit map | data blocks | log ]
|
||||||
|
|
||||||
|
int nbitmap = SIZE/(BSIZE*8) + 1;
|
||||||
|
int ninodeblocks = NINODES / IPB + 1;
|
||||||
int nlog = LOGSIZE;
|
int nlog = LOGSIZE;
|
||||||
int ninodes = 200;
|
int nmeta; // Number of meta blocks (inode, bitmap, and 2 extra)
|
||||||
int size = 1024;
|
int nblocks; // Number of data blocks
|
||||||
|
|
||||||
int fsfd;
|
int fsfd;
|
||||||
struct superblock sb;
|
struct superblock sb;
|
||||||
char zeroes[512];
|
char zeroes[BSIZE];
|
||||||
uint freeblock;
|
|
||||||
uint usedblocks;
|
|
||||||
uint bitblocks;
|
|
||||||
uint freeinode = 1;
|
uint freeinode = 1;
|
||||||
|
uint freeblock;
|
||||||
|
|
||||||
|
|
||||||
void balloc(int);
|
void balloc(int);
|
||||||
void wsect(uint, void*);
|
void wsect(uint, void*);
|
||||||
|
@ -63,7 +69,7 @@ main(int argc, char *argv[])
|
||||||
int i, cc, fd;
|
int i, cc, fd;
|
||||||
uint rootino, inum, off;
|
uint rootino, inum, off;
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
char buf[512];
|
char buf[BSIZE];
|
||||||
struct dinode din;
|
struct dinode din;
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,8 +80,8 @@ main(int argc, char *argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((512 % sizeof(struct dinode)) == 0);
|
assert((BSIZE % sizeof(struct dinode)) == 0);
|
||||||
assert((512 % sizeof(struct dirent)) == 0);
|
assert((BSIZE % sizeof(struct dirent)) == 0);
|
||||||
|
|
||||||
fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
|
fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
|
||||||
if(fsfd < 0){
|
if(fsfd < 0){
|
||||||
|
@ -83,21 +89,19 @@ main(int argc, char *argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.size = xint(size);
|
nmeta = 2 + ninodeblocks + nbitmap;
|
||||||
|
nblocks = SIZE - nlog - nmeta;
|
||||||
|
|
||||||
|
sb.size = xint(SIZE);
|
||||||
sb.nblocks = xint(nblocks); // so whole disk is size sectors
|
sb.nblocks = xint(nblocks); // so whole disk is size sectors
|
||||||
sb.ninodes = xint(ninodes);
|
sb.ninodes = xint(NINODES);
|
||||||
sb.nlog = xint(nlog);
|
sb.nlog = xint(nlog);
|
||||||
|
|
||||||
bitblocks = size/(512*8) + 1;
|
printf("nmeta %d (boot, super, inode blocks %u, bitmap blocks %u) blocks %d log %u total %d\n", nmeta, ninodeblocks, nbitmap, nblocks, nlog, SIZE);
|
||||||
usedblocks = ninodes / IPB + 3 + bitblocks;
|
|
||||||
freeblock = usedblocks;
|
|
||||||
|
|
||||||
printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks,
|
freeblock = nmeta; // the first free block that we can allocate
|
||||||
bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog);
|
|
||||||
|
|
||||||
assert(nblocks + usedblocks + nlog == size);
|
for(i = 0; i < SIZE; i++)
|
||||||
|
|
||||||
for(i = 0; i < nblocks + usedblocks + nlog; i++)
|
|
||||||
wsect(i, zeroes);
|
wsect(i, zeroes);
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
@ -152,7 +156,7 @@ main(int argc, char *argv[])
|
||||||
din.size = xint(off);
|
din.size = xint(off);
|
||||||
winode(rootino, &din);
|
winode(rootino, &din);
|
||||||
|
|
||||||
balloc(usedblocks);
|
balloc(freeblock);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -160,30 +164,26 @@ main(int argc, char *argv[])
|
||||||
void
|
void
|
||||||
wsect(uint sec, void *buf)
|
wsect(uint sec, void *buf)
|
||||||
{
|
{
|
||||||
if(lseek(fsfd, sec * 512L, 0) != sec * 512L){
|
printf("seek to %d\n", sec * BSIZE);
|
||||||
|
if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){
|
||||||
perror("lseek");
|
perror("lseek");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(write(fsfd, buf, 512) != 512){
|
if(write(fsfd, buf, BSIZE) != BSIZE){
|
||||||
perror("write");
|
perror("write");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint
|
|
||||||
i2b(uint inum)
|
|
||||||
{
|
|
||||||
return (inum / IPB) + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
winode(uint inum, struct dinode *ip)
|
winode(uint inum, struct dinode *ip)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[BSIZE];
|
||||||
uint bn;
|
uint bn;
|
||||||
struct dinode *dip;
|
struct dinode *dip;
|
||||||
|
|
||||||
bn = i2b(inum);
|
bn = IBLOCK(inum);
|
||||||
|
printf("winode %d\n", bn);
|
||||||
rsect(bn, buf);
|
rsect(bn, buf);
|
||||||
dip = ((struct dinode*)buf) + (inum % IPB);
|
dip = ((struct dinode*)buf) + (inum % IPB);
|
||||||
*dip = *ip;
|
*dip = *ip;
|
||||||
|
@ -193,11 +193,11 @@ winode(uint inum, struct dinode *ip)
|
||||||
void
|
void
|
||||||
rinode(uint inum, struct dinode *ip)
|
rinode(uint inum, struct dinode *ip)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[BSIZE];
|
||||||
uint bn;
|
uint bn;
|
||||||
struct dinode *dip;
|
struct dinode *dip;
|
||||||
|
|
||||||
bn = i2b(inum);
|
bn = IBLOCK(inum);
|
||||||
rsect(bn, buf);
|
rsect(bn, buf);
|
||||||
dip = ((struct dinode*)buf) + (inum % IPB);
|
dip = ((struct dinode*)buf) + (inum % IPB);
|
||||||
*ip = *dip;
|
*ip = *dip;
|
||||||
|
@ -206,11 +206,11 @@ rinode(uint inum, struct dinode *ip)
|
||||||
void
|
void
|
||||||
rsect(uint sec, void *buf)
|
rsect(uint sec, void *buf)
|
||||||
{
|
{
|
||||||
if(lseek(fsfd, sec * 512L, 0) != sec * 512L){
|
if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){
|
||||||
perror("lseek");
|
perror("lseek");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(read(fsfd, buf, 512) != 512){
|
if(read(fsfd, buf, BSIZE) != BSIZE){
|
||||||
perror("read");
|
perror("read");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -233,17 +233,17 @@ ialloc(ushort type)
|
||||||
void
|
void
|
||||||
balloc(int used)
|
balloc(int used)
|
||||||
{
|
{
|
||||||
uchar buf[512];
|
uchar buf[BSIZE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("balloc: first %d blocks have been allocated\n", used);
|
printf("balloc: first %d blocks have been allocated\n", used);
|
||||||
assert(used < 512*8);
|
assert(used < BSIZE*8);
|
||||||
bzero(buf, 512);
|
bzero(buf, BSIZE);
|
||||||
for(i = 0; i < used; i++){
|
for(i = 0; i < used; i++){
|
||||||
buf[i/8] = buf[i/8] | (0x1 << (i%8));
|
buf[i/8] = buf[i/8] | (0x1 << (i%8));
|
||||||
}
|
}
|
||||||
printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3);
|
printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2);
|
||||||
wsect(ninodes / IPB + 3, buf);
|
wsect(ninodeblocks+2, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
@ -254,7 +254,7 @@ iappend(uint inum, void *xp, int n)
|
||||||
char *p = (char*)xp;
|
char *p = (char*)xp;
|
||||||
uint fbn, off, n1;
|
uint fbn, off, n1;
|
||||||
struct dinode din;
|
struct dinode din;
|
||||||
char buf[512];
|
char buf[BSIZE];
|
||||||
uint indirect[NINDIRECT];
|
uint indirect[NINDIRECT];
|
||||||
uint x;
|
uint x;
|
||||||
|
|
||||||
|
@ -262,32 +262,29 @@ iappend(uint inum, void *xp, int n)
|
||||||
|
|
||||||
off = xint(din.size);
|
off = xint(din.size);
|
||||||
while(n > 0){
|
while(n > 0){
|
||||||
fbn = off / 512;
|
fbn = off / BSIZE;
|
||||||
assert(fbn < MAXFILE);
|
assert(fbn < MAXFILE);
|
||||||
if(fbn < NDIRECT){
|
if(fbn < NDIRECT){
|
||||||
if(xint(din.addrs[fbn]) == 0){
|
if(xint(din.addrs[fbn]) == 0){
|
||||||
din.addrs[fbn] = xint(freeblock++);
|
din.addrs[fbn] = xint(freeblock++);
|
||||||
usedblocks++;
|
|
||||||
}
|
}
|
||||||
x = xint(din.addrs[fbn]);
|
x = xint(din.addrs[fbn]);
|
||||||
} else {
|
} else {
|
||||||
if(xint(din.addrs[NDIRECT]) == 0){
|
if(xint(din.addrs[NDIRECT]) == 0){
|
||||||
// printf("allocate indirect block\n");
|
// printf("allocate indirect block\n");
|
||||||
din.addrs[NDIRECT] = xint(freeblock++);
|
din.addrs[NDIRECT] = xint(freeblock++);
|
||||||
usedblocks++;
|
|
||||||
}
|
}
|
||||||
// printf("read indirect block\n");
|
// printf("read indirect block\n");
|
||||||
rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
rsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
||||||
if(indirect[fbn - NDIRECT] == 0){
|
if(indirect[fbn - NDIRECT] == 0){
|
||||||
indirect[fbn - NDIRECT] = xint(freeblock++);
|
indirect[fbn - NDIRECT] = xint(freeblock++);
|
||||||
usedblocks++;
|
|
||||||
wsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
wsect(xint(din.addrs[NDIRECT]), (char*)indirect);
|
||||||
}
|
}
|
||||||
x = xint(indirect[fbn-NDIRECT]);
|
x = xint(indirect[fbn-NDIRECT]);
|
||||||
}
|
}
|
||||||
n1 = min(n, (fbn + 1) * 512 - off);
|
n1 = min(n, (fbn + 1) * BSIZE - off);
|
||||||
rsect(x, buf);
|
rsect(x, buf);
|
||||||
bcopy(p, buf + off - (fbn * 512), n1);
|
bcopy(p, buf + off - (fbn * BSIZE), n1);
|
||||||
wsect(x, buf);
|
wsect(x, buf);
|
||||||
n -= n1;
|
n -= n1;
|
||||||
off += n1;
|
off += n1;
|
||||||
|
|
2
param.h
2
param.h
|
@ -8,6 +8,6 @@
|
||||||
#define ROOTDEV 1 // device number of file system root disk
|
#define ROOTDEV 1 // device number of file system root disk
|
||||||
#define MAXARG 32 // max exec arguments
|
#define MAXARG 32 // max exec arguments
|
||||||
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes
|
#define MAXOPBLOCKS 10 // max # of blocks any FS op writes
|
||||||
#define LOGSIZE (MAXOPBLOCKS*3) // max data sectors in on-disk log
|
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log
|
||||||
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
|
#define NBUF (MAXOPBLOCKS*3) // size of disk block cache
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue