summaryrefslogtreecommitdiff
path: root/bio.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-08-12 11:38:57 +0000
committerrtm <rtm>2006-08-12 11:38:57 +0000
commit4357207237e074b5a42ee9739eadd040fd1cf296 (patch)
tree1fe657b94bdfb412c02c6c4cec089f329d69df96 /bio.c
parent1f544842ceb5af73b1f2b13222d72dd4ad7cd08a (diff)
downloadxv6-labs-4357207237e074b5a42ee9739eadd040fd1cf296.tar.gz
xv6-labs-4357207237e074b5a42ee9739eadd040fd1cf296.tar.bz2
xv6-labs-4357207237e074b5a42ee9739eadd040fd1cf296.zip
fix getblk to actually lock the block
no more cons_put system calls usertests tests two processes writing files
Diffstat (limited to 'bio.c')
-rw-r--r--bio.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/bio.c b/bio.c
index 2b17a52..7184a28 100644
--- a/bio.c
+++ b/bio.c
@@ -17,24 +17,31 @@ binit(void)
}
struct buf *
-getblk()
+getblk(uint dev, uint sector)
{
- int i;
+ struct buf *b;
acquire(&buf_table_lock);
- // XXX need to lock the block even if not caching, to
- // avoid read modify write problems.
-
while(1){
- for(i = 0; i < NBUF; i++){
- if((buf[i].flags & B_BUSY) == 0){
- buf[i].flags |= B_BUSY;
- release(&buf_table_lock);
- return buf + i;
+ for(b = buf; b < buf+NBUF; b++)
+ if((b->flags & B_BUSY) && b->dev == dev && b->sector)
+ break;
+
+ if(b < buf+NBUF){
+ sleep(buf, &buf_table_lock);
+ } else {
+ for(b = buf; b < buf+NBUF; b++){
+ if((b->flags & B_BUSY) == 0){
+ b->flags |= B_BUSY;
+ b->dev = dev;
+ b->sector = sector;
+ release(&buf_table_lock);
+ return b;
+ }
}
+ panic("getblk: no buffers");
}
- sleep(buf, &buf_table_lock);
}
}
@@ -45,7 +52,7 @@ bread(uint dev, uint sector)
struct buf *b;
extern struct spinlock ide_lock;
- b = getblk();
+ b = getblk(dev, sector);
acquire(&ide_lock);
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);