summaryrefslogtreecommitdiff
path: root/bio.c
diff options
context:
space:
mode:
authorrsc <rsc>2006-09-07 14:28:12 +0000
committerrsc <rsc>2006-09-07 14:28:12 +0000
commitbb207a1d42c9a75a64af35de4f12912176ebfc8d (patch)
treeb762f80b034299b64d60d574f6eb23f6c7478068 /bio.c
parent52253dce6581ab381091720d3df9f3037ce38f7b (diff)
downloadxv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.tar.gz
xv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.tar.bz2
xv6-labs-bb207a1d42c9a75a64af35de4f12912176ebfc8d.zip
comments
Diffstat (limited to 'bio.c')
-rw-r--r--bio.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/bio.c b/bio.c
index ab5f41f..dadd1f7 100644
--- a/bio.c
+++ b/bio.c
@@ -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)
{