diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2014-08-28 16:06:12 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2014-08-28 16:06:12 -0400 | 
| commit | 2b2c1971fc2c3cc6fa1f2f3e7b507a3a35a0cbb8 (patch) | |
| tree | c9ec9a82671f6af27d72d545aba3746302b4b157 | |
| parent | 11183588dc69085b834e013564fc48526e23ef70 (diff) | |
| download | xv6-labs-2b2c1971fc2c3cc6fa1f2f3e7b507a3a35a0cbb8.tar.gz xv6-labs-2b2c1971fc2c3cc6fa1f2f3e7b507a3a35a0cbb8.tar.bz2 xv6-labs-2b2c1971fc2c3cc6fa1f2f3e7b507a3a35a0cbb8.zip | |
write log blocks from cache only at end of transaction
| -rw-r--r-- | log.c | 28 | 
1 files changed, 21 insertions, 7 deletions
| @@ -170,10 +170,27 @@ end_op(void)    }  } +// Copy modified blocks from cache to log. +static void  +write_log(void) +{ +  int tail; + +  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 +    memmove(to->data, from->data, BSIZE); +    bwrite(to);  // write the log +    brelse(from);  +    brelse(to); +  } +} +  static void  commit()  {    if (log.lh.n > 0) { +    write_log();     // Write modified blocks from cache to log      write_head();    // Write header to disk -- the real commit      install_trans(); // Now install writes to home locations      log.lh.n = 0;  @@ -182,8 +199,9 @@ commit()  }  // Caller has modified b->data and is done with the buffer. -// Append the block to the log and record the block number,  -// but don't write the log header (which would commit the write). +// Record the block number and pin in the cache with B_DIRTY. +// commit()/write_log() will do the disk write. +//  // log_write() replaces bwrite(); a typical use is:  //   bp = bread(...)  //   modify bp->data[] @@ -197,17 +215,13 @@ log_write(struct buf *b)    if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1)      panic("too big a transaction");    if (log.outstanding < 1) -    panic("write outside of trans"); +    panic("log_write outside of trans");    for (i = 0; i < log.lh.n; i++) {      if (log.lh.sector[i] == b->sector)   // log absorbtion        break;    }    log.lh.sector[i] = b->sector; -  struct buf *lbuf = bread(b->dev, log.start+i+1); -  memmove(lbuf->data, b->data, BSIZE); -  bwrite(lbuf); -  brelse(lbuf);    if (i == log.lh.n)      log.lh.n++;    b->flags |= B_DIRTY; // prevent eviction | 
