summaryrefslogtreecommitdiff
path: root/bio.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-11 09:57:14 -0400
committerRobert Morris <[email protected]>2019-06-11 09:57:14 -0400
commit5753553213df8f9de851adb68377db43faecb91f (patch)
tree3b629ff54897fca414146677532cb459a2ed11ba /bio.c
parent91ba81110acd3163f7de3580b677eece0c57f5e7 (diff)
downloadxv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.gz
xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.bz2
xv6-labs-5753553213df8f9de851adb68377db43faecb91f.zip
separate source into kernel/ user/ mkfs/
Diffstat (limited to 'bio.c')
-rw-r--r--bio.c145
1 files changed, 0 insertions, 145 deletions
diff --git a/bio.c b/bio.c
deleted file mode 100644
index 90f9af9..0000000
--- a/bio.c
+++ /dev/null
@@ -1,145 +0,0 @@
-// Buffer cache.
-//
-// The buffer cache is a linked list of buf structures holding
-// cached copies of disk block contents. Caching disk blocks
-// in memory reduces the number of disk reads and also provides
-// a synchronization point for disk blocks used by multiple processes.
-//
-// Interface:
-// * To get a buffer for a particular disk block, call bread.
-// * After changing buffer data, call bwrite to write it to disk.
-// * When done with the buffer, call brelse.
-// * Do not use the buffer after calling brelse.
-// * Only one process at a time can use a buffer,
-// so do not keep them longer than necessary.
-//
-// The implementation uses two state flags internally:
-// * B_VALID: the buffer data has been read from the disk.
-// * B_DIRTY: the buffer data has been modified
-// and needs to be written to disk.
-
-#include "types.h"
-#include "param.h"
-#include "spinlock.h"
-#include "sleeplock.h"
-#include "riscv.h"
-#include "defs.h"
-#include "fs.h"
-#include "buf.h"
-
-struct {
- struct spinlock lock;
- struct buf buf[NBUF];
-
- // Linked list of all buffers, through prev/next.
- // head.next is most recently used.
- struct buf head;
-} bcache;
-
-void
-binit(void)
-{
- struct buf *b;
-
- initlock(&bcache.lock, "bcache");
-
-//PAGEBREAK!
- // Create linked list of buffers
- bcache.head.prev = &bcache.head;
- bcache.head.next = &bcache.head;
- for(b = bcache.buf; b < bcache.buf+NBUF; b++){
- b->next = bcache.head.next;
- b->prev = &bcache.head;
- initsleeplock(&b->lock, "buffer");
- bcache.head.next->prev = b;
- bcache.head.next = b;
- }
-}
-
-// Look through buffer cache for block on device dev.
-// If not found, allocate a buffer.
-// In either case, return locked buffer.
-static struct buf*
-bget(uint dev, uint blockno)
-{
- struct buf *b;
-
- acquire(&bcache.lock);
-
- // Is the block already cached?
- for(b = bcache.head.next; b != &bcache.head; b = b->next){
- if(b->dev == dev && b->blockno == blockno){
- b->refcnt++;
- release(&bcache.lock);
- acquiresleep(&b->lock);
- return b;
- }
- }
-
- // Not cached; recycle an unused buffer.
- // Even if refcnt==0, B_DIRTY indicates a buffer is in use
- // because log.c has modified it but not yet committed it.
- for(b = bcache.head.prev; b != &bcache.head; b = b->prev){
- if(b->refcnt == 0 && (b->flags & B_DIRTY) == 0) {
- b->dev = dev;
- b->blockno = blockno;
- b->flags = 0;
- b->refcnt = 1;
- release(&bcache.lock);
- acquiresleep(&b->lock);
- return b;
- }
- }
- panic("bget: no buffers");
-}
-
-// Return a locked buf with the contents of the indicated block.
-struct buf*
-bread(uint dev, uint blockno)
-{
- struct buf *b;
-
- b = bget(dev, blockno);
- if((b->flags & B_VALID) == 0) {
- ramdiskrw(b);
- }
- return b;
-}
-
-// Write b's contents to disk. Must be locked.
-void
-bwrite(struct buf *b)
-{
- if(!holdingsleep(&b->lock))
- panic("bwrite");
- b->flags |= B_DIRTY;
- ramdiskrw(b);
-}
-
-// Release a locked buffer.
-// Move to the head of the MRU list.
-void
-brelse(struct buf *b)
-{
- if(!holdingsleep(&b->lock))
- panic("brelse");
-
- releasesleep(&b->lock);
-
- acquire(&bcache.lock);
- b->refcnt--;
- if (b->refcnt == 0) {
- // no one is waiting for it.
- b->next->prev = b->prev;
- b->prev->next = b->next;
- b->next = bcache.head.next;
- b->prev = &bcache.head;
- bcache.head.next->prev = b;
- bcache.head.next = b;
- }
-
- release(&bcache.lock);
-}
-//PAGEBREAK!
-// Blank page.
-