diff options
author | rtm <rtm> | 2006-08-12 11:38:57 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-08-12 11:38:57 +0000 |
commit | 4357207237e074b5a42ee9739eadd040fd1cf296 (patch) | |
tree | 1fe657b94bdfb412c02c6c4cec089f329d69df96 /bio.c | |
parent | 1f544842ceb5af73b1f2b13222d72dd4ad7cd08a (diff) | |
download | xv6-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.c | 31 |
1 files changed, 19 insertions, 12 deletions
@@ -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); |