summaryrefslogtreecommitdiff
path: root/fs.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-08-13 15:51:58 +0000
committerrtm <rtm>2006-08-13 15:51:58 +0000
commit17e3cf15bac0c1ac60780ce7d1d228442ff08ed9 (patch)
tree3a0f316e47341d71e9edc1715fc232a71dcb7692 /fs.c
parent8abe2bcf156cce7beec21b259a59aaaa538165c0 (diff)
downloadxv6-labs-17e3cf15bac0c1ac60780ce7d1d228442ff08ed9.tar.gz
xv6-labs-17e3cf15bac0c1ac60780ce7d1d228442ff08ed9.tar.bz2
xv6-labs-17e3cf15bac0c1ac60780ce7d1d228442ff08ed9.zip
fix iget() bug that allocated in-use inode[] entries
Diffstat (limited to 'fs.c')
-rw-r--r--fs.c50
1 files changed, 13 insertions, 37 deletions
diff --git a/fs.c b/fs.c
index 37b964d..fbb4a8c 100644
--- a/fs.c
+++ b/fs.c
@@ -54,7 +54,6 @@ balloc(uint dev)
if (b >= size)
panic("balloc: out of blocks\n");
- cprintf ("balloc: allocate block %d\n", b);
bp->data[bi/8] |= 0x1 << (bi % 8);
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
brelse(bp);
@@ -70,7 +69,6 @@ bfree(int dev, uint b)
int ninodes;
uchar m;
- cprintf ("bfree: free block %d\n", b);
bp = bread(dev, 1);
sb = (struct superblock *) bp->data;
ninodes = sb->ninodes;
@@ -93,13 +91,14 @@ bfree(int dev, uint b)
struct inode *
iget(uint dev, uint inum)
{
- struct inode *ip, *nip = 0;
+ struct inode *ip, *nip;
struct dinode *dip;
struct buf *bp;
acquire(&inode_table_lock);
loop:
+ nip = 0;
for(ip = &inode[0]; ip < &inode[NINODE]; ip++){
if(ip->count > 0 && ip->dev == dev && ip->inum == inum){
if(ip->busy){
@@ -180,11 +179,9 @@ ialloc(uint dev, short type)
brelse(bp);
}
- if (inum >= ninodes) {
+ if (inum >= ninodes)
panic ("ialloc: no inodes left\n");
- }
- cprintf ("ialloc: %d\n", inum);
dip->type = type;
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
brelse(bp);
@@ -195,7 +192,6 @@ ialloc(uint dev, short type)
static void
ifree(struct inode *ip)
{
- cprintf("ifree: %d\n", ip->inum);
ip->type = 0;
iupdate(ip);
}
@@ -220,7 +216,7 @@ ilock(struct inode *ip)
void
iunlock(struct inode *ip)
{
- if(ip->busy != 1)
+ if(ip->busy != 1 || ip->count < 1)
panic("iunlock");
acquire(&inode_table_lock);
@@ -271,7 +267,7 @@ iput(struct inode *ip)
if(ip->count < 1 || ip->busy != 1)
panic("iput");
- if ((ip->count <= 1) && (ip->nlink <= 0))
+ if ((ip->count == 1) && (ip->nlink == 0))
iunlink(ip);
acquire(&inode_table_lock);
@@ -498,8 +494,6 @@ mknod(char *cp, short type, short major, short minor)
{
struct inode *ip, *dp;
- cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
-
if ((dp = namei(cp, NAMEI_CREATE, 0)) == 0)
return 0;
@@ -525,24 +519,17 @@ unlink(char *cp)
{
struct inode *ip, *dp;
struct dirent de;
- uint off, inum, cc;
+ uint off, inum, dev;
- cprintf("unlink(%s)\n", cp);
-
- if ((dp = namei(cp, NAMEI_DELETE, &off)) == 0) {
- cprintf("unlink(%s) it doesn't exist\n", cp);
+ if ((dp = namei(cp, NAMEI_DELETE, &off)) == 0)
return -1;
- }
- if((cc = readi(dp, (char*)&de, off, sizeof(de))) != sizeof(de) ||
- de.inum == 0){
- cprintf("off %d dp->size %d cc %d de.inum %d",
- off, dp->size, cc, de.inum);
+ dev = dp->dev;
+
+ if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de) || de.inum == 0)
panic("unlink no entry");
- }
+
inum = de.inum;
- cprintf("dinum %d off %d de %s/%d\n",
- dp->inum, off, de.name, de.inum);
memset(&de, 0, sizeof(de));
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
@@ -551,9 +538,7 @@ unlink(char *cp)
iupdate(dp);
iput(dp);
- ip = iget(dp->dev, inum);
- if(ip == 0)
- panic("unlink no inode");
+ ip = iget(dev, inum);
ip->nlink--;
@@ -568,14 +553,9 @@ link(char *name1, char *name2)
{
struct inode *ip, *dp;
- cprintf("link(%s, %s)\n", name1, name2);
-
- if ((ip = namei(name1, NAMEI_LOOKUP, 0)) == 0){
- cprintf(" failed %s does not exist\n", name1);
+ if ((ip = namei(name1, NAMEI_LOOKUP, 0)) == 0)
return -1;
- }
if(ip->type == T_DIR){
- cprintf(" failed %s is a dir\n", name1);
iput(ip);
return -1;
}
@@ -583,12 +563,10 @@ link(char *name1, char *name2)
iunlock(ip);
if ((dp = namei(name2, NAMEI_CREATE, 0)) == 0) {
- cprintf(" failed %s exists\n", name2);
idecref(ip);
return -1;
}
if(dp->dev != ip->dev){
- cprintf(" cross-device link\n");
idecref(ip);
iput(dp);
return -1;
@@ -602,7 +580,5 @@ link(char *name1, char *name2)
iput(dp);
iput(ip);
- cprintf(" succeeded\n");
-
return 0;
}