write log blocks from cache only at end of transaction

This commit is contained in:
Robert Morris 2014-08-28 16:06:12 -04:00
parent 11183588dc
commit 2b2c1971fc

28
log.c
View file

@ -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 static void
commit() commit()
{ {
if (log.lh.n > 0) { if (log.lh.n > 0) {
write_log(); // Write modified blocks from cache to log
write_head(); // Write header to disk -- the real commit write_head(); // Write header to disk -- the real commit
install_trans(); // Now install writes to home locations install_trans(); // Now install writes to home locations
log.lh.n = 0; log.lh.n = 0;
@ -182,8 +199,9 @@ commit()
} }
// Caller has modified b->data and is done with the buffer. // Caller has modified b->data and is done with the buffer.
// Append the block to the log and record the block number, // Record the block number and pin in the cache with B_DIRTY.
// but don't write the log header (which would commit the write). // commit()/write_log() will do the disk write.
//
// log_write() replaces bwrite(); a typical use is: // log_write() replaces bwrite(); a typical use is:
// bp = bread(...) // bp = bread(...)
// modify bp->data[] // modify bp->data[]
@ -197,17 +215,13 @@ log_write(struct buf *b)
if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1) if (log.lh.n >= LOGSIZE || log.lh.n >= log.size - 1)
panic("too big a transaction"); panic("too big a transaction");
if (log.outstanding < 1) if (log.outstanding < 1)
panic("write outside of trans"); panic("log_write outside of trans");
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.sector[i] == b->sector) // log absorbtion
break; break;
} }
log.lh.sector[i] = b->sector; 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) if (i == log.lh.n)
log.lh.n++; log.lh.n++;
b->flags |= B_DIRTY; // prevent eviction b->flags |= B_DIRTY; // prevent eviction