diff options
| author | Frans Kaashoek <kaashoek@mit.edu> | 2015-06-27 12:39:13 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@mit.edu> | 2015-06-27 12:39:13 -0400 | 
| commit | 8320d61be5613fb2875be859695752b1487fda20 (patch) | |
| tree | f0a800145225ffcd97f805be47e5b41764504898 | |
| parent | de4af193c87b3a7fa8762ccaeb81a6addf168799 (diff) | |
| download | xv6-labs-8320d61be5613fb2875be859695752b1487fda20.tar.gz xv6-labs-8320d61be5613fb2875be859695752b1487fda20.tar.bz2 xv6-labs-8320d61be5613fb2875be859695752b1487fda20.zip | |
Pick up where i left off in april:
- move log into metadata part of disk, so that marking
that the log's blocks are in use falls out for free
- superblock describes the whole disk (sizes and offets)
- sizes and offsets are computed in one place (mkfs) and
the rest of the code refers to the superblock for these values,
instead of recomputing them.
| -rw-r--r-- | defs.h | 4 | ||||
| -rw-r--r-- | fs.c | 26 | ||||
| -rw-r--r-- | fs.h | 21 | ||||
| -rw-r--r-- | log.c | 8 | ||||
| -rw-r--r-- | main.c | 1 | ||||
| -rw-r--r-- | mkfs.c | 29 | ||||
| -rw-r--r-- | proc.c | 3 | 
7 files changed, 47 insertions, 45 deletions
| @@ -39,7 +39,7 @@ int             dirlink(struct inode*, char*, uint);  struct inode*   dirlookup(struct inode*, char*, uint*);  struct inode*   ialloc(uint, short);  struct inode*   idup(struct inode*); -void            iinit(void); +void            iinit(int dev);  void            ilock(struct inode*);  void            iput(struct inode*);  void            iunlock(struct inode*); @@ -81,7 +81,7 @@ void            lapicstartap(uchar, uint);  void            microdelay(int);  // log.c -void            initlog(void); +void            initlog(int dev);  void            log_write(struct buf*);  void            begin_op();  void            end_op(); @@ -22,6 +22,7 @@  #define min(a, b) ((a) < (b) ? (a) : (b))  static void itrunc(struct inode*); +struct superblock sb;   // there should be one per dev, but we run with one dev  // Read the super block.  void @@ -54,12 +55,10 @@ balloc(uint dev)  {    int b, bi, m;    struct buf *bp; -  struct superblock sb;    bp = 0; -  readsb(dev, &sb);    for(b = 0; b < sb.size; b += BPB){ -    bp = bread(dev, BBLOCK(b, sb.ninodes)); +    bp = bread(dev, BBLOCK(b, sb));      for(bi = 0; bi < BPB && b + bi < sb.size; bi++){        m = 1 << (bi % 8);        if((bp->data[bi/8] & m) == 0){  // Is block free? @@ -80,11 +79,10 @@ static void  bfree(int dev, uint b)  {    struct buf *bp; -  struct superblock sb;    int bi, m;    readsb(dev, &sb); -  bp = bread(dev, BBLOCK(b, sb.ninodes)); +  bp = bread(dev, BBLOCK(b, sb));    bi = b % BPB;    m = 1 << (bi % 8);    if((bp->data[bi/8] & m) == 0) @@ -101,8 +99,8 @@ bfree(int dev, uint b)  // its size, the number of links referring to it, and the  // list of blocks holding the file's content.  // -// The inodes are laid out sequentially on disk immediately after -// the superblock. Each inode has a number, indicating its +// The inodes are laid out sequentially on disk at +// sb.startinode. Each inode has a number, indicating its  // position on the disk.  //  // The kernel keeps a cache of in-use inodes in memory @@ -162,9 +160,12 @@ struct {  } icache;  void -iinit(void) +iinit(int dev)  {    initlock(&icache.lock, "icache"); +  readsb(dev, &sb); +  cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d inodestart %d bmap start %d\n", sb.size, +          sb.nblocks, sb.ninodes, sb.nlog, sb.logstart, sb.inodestart, sb.bmapstart);  }  static struct inode* iget(uint dev, uint inum); @@ -178,12 +179,9 @@ ialloc(uint dev, short type)    int inum;    struct buf *bp;    struct dinode *dip; -  struct superblock sb; - -  readsb(dev, &sb);    for(inum = 1; inum < sb.ninodes; inum++){ -    bp = bread(dev, IBLOCK(inum)); +    bp = bread(dev, IBLOCK(inum, sb));      dip = (struct dinode*)bp->data + inum%IPB;      if(dip->type == 0){  // a free inode        memset(dip, 0, sizeof(*dip)); @@ -204,7 +202,7 @@ iupdate(struct inode *ip)    struct buf *bp;    struct dinode *dip; -  bp = bread(ip->dev, IBLOCK(ip->inum)); +  bp = bread(ip->dev, IBLOCK(ip->inum, sb));    dip = (struct dinode*)bp->data + ip->inum%IPB;    dip->type = ip->type;    dip->major = ip->major; @@ -281,7 +279,7 @@ ilock(struct inode *ip)    release(&icache.lock);    if(!(ip->flags & I_VALID)){ -    bp = bread(ip->dev, IBLOCK(ip->inum)); +    bp = bread(ip->dev, IBLOCK(ip->inum, sb));      dip = (struct dinode*)bp->data + ip->inum%IPB;      ip->type = dip->type;      ip->major = dip->major; @@ -1,22 +1,23 @@  // On-disk file system format.   // Both the kernel and user programs use this header file. -// Block 0 is unused. -// Block 1 is super block. -// Blocks 2 through sb.ninodes/IPB hold inodes. -// Then free bitmap blocks holding sb.size bits. -// Then sb.nblocks data blocks. -// Then sb.nlog log blocks.  #define ROOTINO 1  // root i-number  #define BSIZE 512  // block size -// File system super block +// Disk layout: +// [ boot block | super block | log | inode blocks | free bit map | data blocks ] +// +// mkfs computes the super block and builds an initial file system. The super describes +// the disk layout:  struct superblock {    uint size;         // Size of file system image (blocks)    uint nblocks;      // Number of data blocks    uint ninodes;      // Number of inodes.    uint nlog;         // Number of log blocks +  uint logstart;     // Block number of first log block +  uint inodestart;   // Block number of first inode block +  uint bmapstart;    // Block number of first free map block  };  #define NDIRECT 12 @@ -37,13 +38,13 @@ struct dinode {  #define IPB           (BSIZE / sizeof(struct dinode))  // Block containing inode i -#define IBLOCK(i)     ((i) / IPB + 2) +#define IBLOCK(i, sb)     ((i) / IPB + sb.inodestart)  // Bitmap bits per block  #define BPB           (BSIZE*8) -// Block containing bit for block b -#define BBLOCK(b, ninodes) (b/BPB + (ninodes)/IPB + 3) +// Block of free map containing bit for block b +#define BBLOCK(b, sb) (b/BPB + sb.bmapstart)  // Directory is a file containing a sequence of dirent structures.  #define DIRSIZ 14 @@ -50,17 +50,17 @@ static void recover_from_log(void);  static void commit();  void -initlog(void) +initlog(int dev)  {    if (sizeof(struct logheader) >= BSIZE)      panic("initlog: too big logheader");    struct superblock sb;    initlock(&log.lock, "log"); -  readsb(ROOTDEV, &sb); -  log.start = sb.size - sb.nlog; +  readsb(dev, &sb); +  log.start = sb.logstart;    log.size = sb.nlog; -  log.dev = ROOTDEV; +  log.dev = dev;    recover_from_log();  } @@ -31,7 +31,6 @@ main(void)    tvinit();        // trap vectors    binit();         // buffer cache    fileinit();      // file table -  iinit();         // inode cache    ideinit();       // disk    if(!ismp)      timerinit();   // uniprocessor timer @@ -16,12 +16,12 @@  #define NINODES 200  // Disk layout: -// [ boot block | sb block | inode blocks | bit map | data blocks | log ] +// [ boot block | sb block | log | inode blocks | free bit map | data blocks ]  int nbitmap = FSSIZE/(BSIZE*8) + 1;  int ninodeblocks = NINODES / IPB + 1;  int nlog = LOGSIZE;   -int nmeta;    // Number of meta blocks (inode, bitmap, and 2 extra) +int nmeta;    // Number of meta blocks (boot, sb, nlog, inode, bitmap)  int nblocks;  // Number of data blocks  int fsfd; @@ -88,15 +88,20 @@ main(int argc, char *argv[])      exit(1);    } -  nmeta = 2 + ninodeblocks + nbitmap; -  nblocks = FSSIZE - nlog - nmeta; +  // 1 fs block = 1 disk sector +  nmeta = 2 + nlog + ninodeblocks + nbitmap; +  nblocks = FSSIZE - nmeta;    sb.size = xint(FSSIZE); -  sb.nblocks = xint(nblocks); // so whole disk is size sectors +  sb.nblocks = xint(nblocks);    sb.ninodes = xint(NINODES);    sb.nlog = xint(nlog); +  sb.logstart = xint(2); +  sb.inodestart = xint(2+nlog); +  sb.bmapstart = xint(2+nlog+ninodeblocks); -  printf("nmeta %d (boot, super, inode blocks %u, bitmap blocks %u) blocks %d log %u total %d\n", nmeta, ninodeblocks, nbitmap, nblocks, nlog, FSSIZE); +  printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", +         nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE);    freeblock = nmeta;     // the first free block that we can allocate @@ -180,7 +185,7 @@ winode(uint inum, struct dinode *ip)    uint bn;    struct dinode *dip; -  bn = IBLOCK(inum); +  bn = IBLOCK(inum, sb);    rsect(bn, buf);    dip = ((struct dinode*)buf) + (inum % IPB);    *dip = *ip; @@ -194,7 +199,7 @@ rinode(uint inum, struct dinode *ip)    uint bn;    struct dinode *dip; -  bn = IBLOCK(inum); +  bn = IBLOCK(inum, sb);    rsect(bn, buf);    dip = ((struct dinode*)buf) + (inum % IPB);    *ip = *dip; @@ -239,8 +244,8 @@ balloc(int used)    for(i = 0; i < used; i++){      buf[i/8] = buf[i/8] | (0x1 << (i%8));    } -  printf("balloc: write bitmap block at sector %d\n", ninodeblocks+2); -  wsect(ninodeblocks+2, buf); +  printf("balloc: write bitmap block at sector %d\n", sb.bmapstart); +  wsect(sb.bmapstart, buf);  }  #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -256,8 +261,8 @@ iappend(uint inum, void *xp, int n)    uint x;    rinode(inum, &din); -    off = xint(din.size); +  // printf("append inum %d at off %d sz %d\n", inum, off, n);    while(n > 0){      fbn = off / BSIZE;      assert(fbn < MAXFILE); @@ -268,10 +273,8 @@ iappend(uint inum, void *xp, int n)        x = xint(din.addrs[fbn]);      } else {        if(xint(din.addrs[NDIRECT]) == 0){ -        // printf("allocate indirect block\n");          din.addrs[NDIRECT] = xint(freeblock++);        } -      // printf("read indirect block\n");        rsect(xint(din.addrs[NDIRECT]), (char*)indirect);        if(indirect[fbn - NDIRECT] == 0){          indirect[fbn - NDIRECT] = xint(freeblock++); @@ -339,7 +339,8 @@ forkret(void)      // of a regular process (e.g., they call sleep), and thus cannot       // be run from main().      first = 0; -    initlog(); +    iinit(ROOTDEV); +    initlog(ROOTDEV);    }    // Return to "caller", actually trapret (see allocproc). | 
