diff options
author | rsc <rsc> | 2006-09-07 14:28:12 +0000 |
---|---|---|
committer | rsc <rsc> | 2006-09-07 14:28:12 +0000 |
commit | bb207a1d42c9a75a64af35de4f12912176ebfc8d (patch) | |
tree | b762f80b034299b64d60d574f6eb23f6c7478068 /bio.c | |
parent | 52253dce6581ab381091720d3df9f3037ce38f7b (diff) | |
download | xv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.tar.gz xv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.tar.bz2 xv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.zip |
comments
Diffstat (limited to 'bio.c')
-rw-r--r-- | bio.c | 41 |
1 files changed, 37 insertions, 4 deletions
@@ -1,3 +1,29 @@ +// Buffer cache. +// +// The buffer cache is a linked list of buf structures +// holding cached copies of disk block contents. +// Each buf has two state bits B_BUSY and B_VALID. +// If B_BUSY is set, it means that some code is currently +// editing buf, so other code is not allowed to look at it. +// To wait for a buffer that is B_BUSY, sleep on buf. +// (See bget below.) +// +// If B_VALID is set, it means that the memory contents +// have been initialized by reading them off the disk. +// (Conversely, if B_VALID is not set, the memory contents +// of buf must be initialized, often by calling bread, +// before being used.) +// +// After making changes to a buf's memory, call bwrite to flush +// the changes out to disk, to keep the disk and memory copies +// in sync. +// +// When finished with a buffer, call brelse to release the buffer +// (i.e., clear B_BUSY), so that others can access it. +// +// Bufs that are not B_BUSY are fair game for reuse for other +// disk blocks. It is not allowed to use a buf after calling brelse. + #include "types.h" #include "param.h" #include "x86.h" @@ -10,7 +36,7 @@ struct buf buf[NBUF]; struct spinlock buf_table_lock; -// linked list of all buffers, through prev/next. +// Linked list of all buffers, through prev/next. // bufhead->next is most recently used. // bufhead->tail is least recently used. struct buf bufhead; @@ -22,6 +48,7 @@ binit(void) initlock(&buf_table_lock, "buf_table"); + // Create linked list of buffers bufhead.prev = &bufhead; bufhead.next = &bufhead; for(b = buf; b < buf+NBUF; b++){ @@ -32,7 +59,10 @@ binit(void) } } -struct buf* +// Look through buffer cache for block n on device dev. +// If not found, allocate fresh block. +// In either case, return locked buffer. +static struct buf* getblk(uint dev, uint sector) { struct buf *b; @@ -63,11 +93,12 @@ getblk(uint dev, uint sector) return b; } } - panic("getblk: no buffers"); + panic("bget: no buffers"); } } } +// Read buf's contents from disk. struct buf* bread(uint dev, uint sector) { @@ -75,7 +106,7 @@ bread(uint dev, uint sector) struct buf *b; extern struct spinlock ide_lock; - b = getblk(dev, sector); + b = bget(dev, sector); if(b->flags & B_VALID) return b; @@ -89,6 +120,7 @@ bread(uint dev, uint sector) return b; } +// Write buf's contents to disk. void bwrite(struct buf *b, uint sector) { @@ -103,6 +135,7 @@ bwrite(struct buf *b, uint sector) release(&ide_lock); } +// Release the buffer buf. void brelse(struct buf *b) { |