diff options
| -rw-r--r-- | bio.c | 20 | ||||
| -rw-r--r-- | bootmain.c | 2 | ||||
| -rw-r--r-- | buf.h | 4 | ||||
| -rw-r--r-- | fs.c | 2 | ||||
| -rw-r--r-- | fs.h | 2 | ||||
| -rw-r--r-- | ide.c | 20 | ||||
| -rw-r--r-- | kill.c | 2 | ||||
| -rw-r--r-- | log.c | 18 | ||||
| -rw-r--r-- | memide.c | 12 | ||||
| -rw-r--r-- | mkfs.c | 93 | ||||
| -rw-r--r-- | param.h | 2 | 
11 files changed, 91 insertions, 86 deletions
@@ -24,6 +24,7 @@  #include "defs.h"  #include "param.h"  #include "spinlock.h" +#include "fs.h"  #include "buf.h"  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.  // In either case, return B_BUSY buffer.  static struct buf* -bget(uint dev, uint sector) +bget(uint dev, uint blockno)  {    struct buf *b;    acquire(&bcache.lock);   loop: -  // Is the sector already cached? +  // Is the block already cached?    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)){          b->flags |= B_BUSY;          release(&bcache.lock); @@ -85,7 +86,7 @@ bget(uint dev, uint sector)    for(b = bcache.head.prev; b != &bcache.head; b = b->prev){      if((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0){        b->dev = dev; -      b->sector = sector; +      b->blockno = blockno;        b->flags = B_BUSY;        release(&bcache.lock);        return b; @@ -94,15 +95,16 @@ bget(uint dev, uint sector)    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* -bread(uint dev, uint sector) +bread(uint dev, uint blockno)  {    struct buf *b; -  b = bget(dev, sector); -  if(!(b->flags & B_VALID)) +  b = bget(dev, blockno); +  if(!(b->flags & B_VALID)) {      iderw(b); +  }    return b;  } @@ -1,6 +1,6 @@  // 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.  // bootmain() loads an ELF kernel image from the disk starting at  // sector 1 and then jumps to the kernel entry routine. @@ -1,11 +1,11 @@  struct buf {    int flags;    uint dev; -  uint sector; +  uint blockno;    struct buf *prev; // LRU cache list    struct buf *next;    struct buf *qnext; // disk queue -  uchar data[512]; +  uchar data[BSIZE];  };  #define B_BUSY  0x1  // buffer is locked by some process  #define B_VALID 0x2  // buffer has been read from disk @@ -16,8 +16,8 @@  #include "mmu.h"  #include "proc.h"  #include "spinlock.h" -#include "buf.h"  #include "fs.h" +#include "buf.h"  #include "file.h"  #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -9,7 +9,7 @@  // Then sb.nlog log blocks.  #define ROOTINO 1  // root i-number -#define BSIZE 512  // block size +#define BSIZE 1024  // block size  // File system super block  struct superblock { @@ -9,8 +9,10 @@  #include "x86.h"  #include "traps.h"  #include "spinlock.h" +#include "fs.h"  #include "buf.h" +#define SECTOR_SIZE   512  #define IDE_BSY       0x80  #define IDE_DRDY      0x40  #define IDE_DF        0x20 @@ -71,17 +73,21 @@ idestart(struct buf *b)  {    if(b == 0)      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);    outb(0x3f6, 0);  // generate interrupt -  outb(0x1f2, 1);  // number of sectors -  outb(0x1f3, b->sector & 0xff); -  outb(0x1f4, (b->sector >> 8) & 0xff); -  outb(0x1f5, (b->sector >> 16) & 0xff); -  outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((b->sector>>24)&0x0f)); +  outb(0x1f2, sector_per_block);  // number of sectors +  outb(0x1f3, sector & 0xff); +  outb(0x1f4, (sector >> 8) & 0xff); +  outb(0x1f5, (sector >> 16) & 0xff); +  outb(0x1f6, 0xe0 | ((b->dev&1)<<4) | ((sector>>24)&0x0f));    if(b->flags & B_DIRTY){      outb(0x1f7, IDE_CMD_WRITE); -    outsl(0x1f0, b->data, 512/4); +    outsl(0x1f0, b->data, BSIZE/4);    } else {      outb(0x1f7, IDE_CMD_READ);    } @@ -104,7 +110,7 @@ ideintr(void)    // Read data if needed.    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.    b->flags |= B_VALID; @@ -7,7 +7,7 @@ main(int argc, char **argv)  {    int i; -  if(argc < 1){ +  if(argc < 2){      printf(2, "usage: kill pid...\n");      exit();    } @@ -21,7 +21,7 @@  //  // The log is a physical re-do log containing disk blocks.  // 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 B  //   block C @@ -29,10 +29,10 @@  // Log appends are synchronous.  // 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 {    int n;    -  int sector[LOGSIZE]; +  int block[LOGSIZE];  };  struct log { @@ -72,7 +72,7 @@ install_trans(void)    for (tail = 0; tail < log.lh.n; tail++) {      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      bwrite(dbuf);  // write dst to disk      brelse(lbuf);  @@ -89,7 +89,7 @@ read_head(void)    int i;    log.lh.n = lh->n;    for (i = 0; i < log.lh.n; i++) { -    log.lh.sector[i] = lh->sector[i]; +    log.lh.block[i] = lh->block[i];    }    brelse(buf);  } @@ -105,7 +105,7 @@ write_head(void)    int i;    hb->n = log.lh.n;    for (i = 0; i < log.lh.n; i++) { -    hb->sector[i] = log.lh.sector[i]; +    hb->block[i] = log.lh.block[i];    }    bwrite(buf);    brelse(buf); @@ -178,7 +178,7 @@ write_log(void)    for (tail = 0; tail < log.lh.n; tail++) {      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);      bwrite(to);  // write the log      brelse(from);  @@ -219,10 +219,10 @@ log_write(struct buf *b)    acquire(&log.lock);    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;    } -  log.lh.sector[i] = b->sector; +  log.lh.block[i] = b->blockno;    if (i == log.lh.n)      log.lh.n++;    b->flags |= B_DIRTY; // prevent eviction @@ -20,7 +20,7 @@ void  ideinit(void)  {    memdisk = _binary_fs_img_start; -  disksize = (uint)_binary_fs_img_size/512; +  disksize = (uint)_binary_fs_img_size/BSIZE;  }  // Interrupt handler. @@ -44,15 +44,15 @@ iderw(struct buf *b)      panic("iderw: nothing to do");    if(b->dev != 1)      panic("iderw: request not for disk 1"); -  if(b->sector >= disksize) -    panic("iderw: sector out of range"); +  if(b->block >= disksize) +    panic("iderw: block out of range"); -  p = memdisk + b->sector*512; +  p = memdisk + b->block*BSIZE;    if(b->flags & B_DIRTY){      b->flags &= ~B_DIRTY; -    memmove(p, b->data, 512); +    memmove(p, b->data, BSIZE);    } else -    memmove(b->data, p, 512); +    memmove(b->data, p, BSIZE);    b->flags |= B_VALID;  } @@ -13,18 +13,24 @@  #define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) -int nblocks = (995-LOGSIZE); -int nlog = LOGSIZE; -int ninodes = 200; -int size = 1024; +#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 nmeta;    // Number of meta blocks (inode, bitmap, and 2 extra) +int nblocks;  // Number of data blocks  int fsfd;  struct superblock sb; -char zeroes[512]; -uint freeblock; -uint usedblocks; -uint bitblocks; +char zeroes[BSIZE];  uint freeinode = 1; +uint freeblock; +  void balloc(int);  void wsect(uint, void*); @@ -63,7 +69,7 @@ main(int argc, char *argv[])    int i, cc, fd;    uint rootino, inum, off;    struct dirent de; -  char buf[512]; +  char buf[BSIZE];    struct dinode din; @@ -74,8 +80,8 @@ main(int argc, char *argv[])      exit(1);    } -  assert((512 % sizeof(struct dinode)) == 0); -  assert((512 % sizeof(struct dirent)) == 0); +  assert((BSIZE % sizeof(struct dinode)) == 0); +  assert((BSIZE % sizeof(struct dirent)) == 0);    fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);    if(fsfd < 0){ @@ -83,21 +89,19 @@ main(int argc, char *argv[])      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.ninodes = xint(ninodes); +  sb.ninodes = xint(NINODES);    sb.nlog = xint(nlog); -  bitblocks = size/(512*8) + 1; -  usedblocks = ninodes / IPB + 3 + bitblocks; -  freeblock = usedblocks; +  printf("nmeta %d (boot, super, inode blocks %u, bitmap blocks %u) blocks %d log %u total %d\n", nmeta, ninodeblocks, nbitmap, nblocks, nlog, SIZE); -  printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, -         bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); +  freeblock = nmeta;     // the first free block that we can allocate -  assert(nblocks + usedblocks + nlog == size); - -  for(i = 0; i < nblocks + usedblocks + nlog; i++) +  for(i = 0; i < SIZE; i++)      wsect(i, zeroes);    memset(buf, 0, sizeof(buf)); @@ -152,7 +156,7 @@ main(int argc, char *argv[])    din.size = xint(off);    winode(rootino, &din); -  balloc(usedblocks); +  balloc(freeblock);    exit(0);  } @@ -160,30 +164,26 @@ main(int argc, char *argv[])  void  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");      exit(1);    } -  if(write(fsfd, buf, 512) != 512){ +  if(write(fsfd, buf, BSIZE) != BSIZE){      perror("write");      exit(1);    }  } -uint -i2b(uint inum) -{ -  return (inum / IPB) + 2; -} -  void  winode(uint inum, struct dinode *ip)  { -  char buf[512]; +  char buf[BSIZE];    uint bn;    struct dinode *dip; -  bn = i2b(inum); +  bn = IBLOCK(inum); +  printf("winode %d\n", bn);    rsect(bn, buf);    dip = ((struct dinode*)buf) + (inum % IPB);    *dip = *ip; @@ -193,11 +193,11 @@ winode(uint inum, struct dinode *ip)  void  rinode(uint inum, struct dinode *ip)  { -  char buf[512]; +  char buf[BSIZE];    uint bn;    struct dinode *dip; -  bn = i2b(inum); +  bn = IBLOCK(inum);    rsect(bn, buf);    dip = ((struct dinode*)buf) + (inum % IPB);    *ip = *dip; @@ -206,11 +206,11 @@ rinode(uint inum, struct dinode *ip)  void  rsect(uint sec, void *buf)  { -  if(lseek(fsfd, sec * 512L, 0) != sec * 512L){ +  if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){      perror("lseek");      exit(1);    } -  if(read(fsfd, buf, 512) != 512){ +  if(read(fsfd, buf, BSIZE) != BSIZE){      perror("read");      exit(1);    } @@ -233,17 +233,17 @@ ialloc(ushort type)  void  balloc(int used)  { -  uchar buf[512]; +  uchar buf[BSIZE];    int i;    printf("balloc: first %d blocks have been allocated\n", used); -  assert(used < 512*8); -  bzero(buf, 512); +  assert(used < BSIZE*8); +  bzero(buf, BSIZE);    for(i = 0; i < used; i++){      buf[i/8] = buf[i/8] | (0x1 << (i%8));    } -  printf("balloc: write bitmap block at sector %zu\n", ninodes/IPB + 3); -  wsect(ninodes / IPB + 3, buf); +  printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2); +  wsect(ninodeblocks+2, buf);  }  #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -254,7 +254,7 @@ iappend(uint inum, void *xp, int n)    char *p = (char*)xp;    uint fbn, off, n1;    struct dinode din; -  char buf[512]; +  char buf[BSIZE];    uint indirect[NINDIRECT];    uint x; @@ -262,32 +262,29 @@ iappend(uint inum, void *xp, int n)    off = xint(din.size);    while(n > 0){ -    fbn = off / 512; +    fbn = off / BSIZE;      assert(fbn < MAXFILE);      if(fbn < NDIRECT){        if(xint(din.addrs[fbn]) == 0){          din.addrs[fbn] = xint(freeblock++); -        usedblocks++;        }        x = xint(din.addrs[fbn]);      } else {        if(xint(din.addrs[NDIRECT]) == 0){          // printf("allocate indirect block\n");          din.addrs[NDIRECT] = xint(freeblock++); -        usedblocks++;        }        // printf("read indirect block\n");        rsect(xint(din.addrs[NDIRECT]), (char*)indirect);        if(indirect[fbn - NDIRECT] == 0){          indirect[fbn - NDIRECT] = xint(freeblock++); -        usedblocks++;          wsect(xint(din.addrs[NDIRECT]), (char*)indirect);        }        x = xint(indirect[fbn-NDIRECT]);      } -    n1 = min(n, (fbn + 1) * 512 - off); +    n1 = min(n, (fbn + 1) * BSIZE - off);      rsect(x, buf); -    bcopy(p, buf + off - (fbn * 512), n1); +    bcopy(p, buf + off - (fbn * BSIZE), n1);      wsect(x, buf);      n -= n1;      off += n1; @@ -8,6 +8,6 @@  #define ROOTDEV       1  // device number of file system root disk  #define MAXARG       32  // max exec arguments  #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  | 
