diff --git a/console.c b/console.c index fa611ef..4d678b0 100644 --- a/console.c +++ b/console.c @@ -7,6 +7,7 @@ #include "param.h" #include "traps.h" #include "spinlock.h" +#include "sleeplock.h" #include "fs.h" #include "file.h" #include "memlayout.h" diff --git a/file.c b/file.c index 85bb403..95cadb3 100644 --- a/file.c +++ b/file.c @@ -6,8 +6,9 @@ #include "defs.h" #include "param.h" #include "fs.h" -#include "file.h" #include "spinlock.h" +#include "sleeplock.h" +#include "file.h" struct devsw devsw[NDEV]; struct { diff --git a/file.h b/file.h index 5a4a463..22a6803 100644 --- a/file.h +++ b/file.h @@ -14,7 +14,8 @@ struct inode { uint dev; // Device number uint inum; // Inode number int ref; // Reference count - int flags; // I_BUSY, I_VALID + struct sleeplock lock; + int flags; // I_VALID short type; // copy of disk inode short major; @@ -23,7 +24,6 @@ struct inode { uint size; uint addrs[NDIRECT+1]; }; -#define I_BUSY 0x1 #define I_VALID 0x2 // table mapping major device number to diff --git a/fs.c b/fs.c index 26a0b3e..be8c5c5 100644 --- a/fs.c +++ b/fs.c @@ -135,9 +135,7 @@ bfree(int dev, uint b) // // * Locked: file system code may only examine and modify // the information in an inode and its content if it -// has first locked the inode. The I_BUSY flag indicates -// that the inode is locked. ilock() sets I_BUSY, -// while iunlock clears it. +// has first locked the inode. // // Thus a typical sequence is: // ip = iget(dev, inum) @@ -165,7 +163,13 @@ struct { void iinit(int dev) { + int i = 0; + initlock(&icache.lock, "icache"); + for(i = 0; i < NINODE; i++) { + initsleeplock(&icache.inode[i].lock, "inode"); + } + readsb(dev, &sb); cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\ inodestart %d bmap start %d\n", sb.size, sb.nblocks, @@ -277,11 +281,7 @@ ilock(struct inode *ip) if(ip == 0 || ip->ref < 1) panic("ilock"); - acquire(&icache.lock); - while(ip->flags & I_BUSY) - sleep(ip, &icache.lock); - ip->flags |= I_BUSY; - release(&icache.lock); + acquiresleep(&ip->lock); if(!(ip->flags & I_VALID)){ bp = bread(ip->dev, IBLOCK(ip->inum, sb)); @@ -303,13 +303,10 @@ ilock(struct inode *ip) void iunlock(struct inode *ip) { - if(ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1) + if(ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) panic("iunlock"); - acquire(&icache.lock); - ip->flags &= ~I_BUSY; - wakeup(ip); - release(&icache.lock); + releasesleep(&ip->lock); } // Drop a reference to an in-memory inode. @@ -325,16 +322,12 @@ iput(struct inode *ip) acquire(&icache.lock); if(ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0){ // inode has no links and no other references: truncate and free. - if(ip->flags & I_BUSY) - panic("iput busy"); - ip->flags |= I_BUSY; release(&icache.lock); itrunc(ip); ip->type = 0; iupdate(ip); acquire(&icache.lock); ip->flags = 0; - wakeup(ip); } ip->ref--; release(&icache.lock); diff --git a/pipe.c b/pipe.c index f76ed5c..a9f471e 100644 --- a/pipe.c +++ b/pipe.c @@ -4,8 +4,9 @@ #include "mmu.h" #include "proc.h" #include "fs.h" -#include "file.h" #include "spinlock.h" +#include "sleeplock.h" +#include "file.h" #define PIPESIZE 512 diff --git a/sysfile.c b/sysfile.c index aaeccc5..98e8c43 100644 --- a/sysfile.c +++ b/sysfile.c @@ -11,6 +11,8 @@ #include "mmu.h" #include "proc.h" #include "fs.h" +#include "spinlock.h" +#include "sleeplock.h" #include "file.h" #include "fcntl.h" diff --git a/uart.c b/uart.c index 257384a..84da397 100644 --- a/uart.c +++ b/uart.c @@ -5,6 +5,7 @@ #include "param.h" #include "traps.h" #include "spinlock.h" +#include "sleeplock.h" #include "fs.h" #include "file.h" #include "mmu.h"