fix deadlock---iput(dp) asap

working unlink, but doesn't free dir blocks that become empty
remove out-of-date comment in ioapic
This commit is contained in:
kaashoek 2006-08-11 18:18:38 +00:00
parent 17a856577f
commit 24437cd554
5 changed files with 73 additions and 33 deletions

1
defs.h
View file

@ -118,4 +118,5 @@ struct inode * namei(char *path);
int readi(struct inode *ip, char *xdst, uint off, uint n);
int writei(struct inode *ip, char *addr, uint off, uint n);
struct inode *mknod(struct inode *, char *, short, short, short);
int unlink(char *cp);
void iupdate (struct inode *ip);

60
fs.c
View file

@ -187,7 +187,7 @@ ialloc(uint dev, short type)
}
static void
ifree(uint dev, struct inode *ip)
ifree(struct inode *ip)
{
ip->type = 0;
iupdate(ip);
@ -440,3 +440,61 @@ mknod(struct inode *dp, char *cp, short type, short major, short minor)
return ip;
}
int
unlink(char *cp)
{
int i;
struct inode *ip, *dp;
struct dirent *ep = 0;
int off;
struct buf *bp = 0;
if ((ip = namei(cp)) == 0) {
cprintf("file to be unlinked doesn't exist\n");
return -1;
}
ip->nlink--;
if (ip->nlink > 0) {
iupdate(ip);
iput(ip); // is this the right order?
return 0;
}
// free inode, its blocks, and remove dir entry
for (i = 0; i < NDIRECT; i++) {
if (ip->addrs[i] != 0) {
bfree(ip->dev, ip->addrs[i]);
ip->addrs[i] = 0;
}
}
ip->size = 0;
ip->major = 0;
ip->minor = 0;
iupdate(ip);
ifree(ip); // is this the right order?
dp = iget(rootdev, 1); // XXX should parse name
for(off = 0; off < dp->size; off += BSIZE) {
bp = bread(dp->dev, bmap(dp, off / BSIZE));
for(ep = (struct dirent *) bp->data;
ep < (struct dirent *) (bp->data + BSIZE);
ep++){
if(ep->inum == ip->inum) {
goto found;
}
}
brelse(bp);
}
panic("mknod: XXXX no dir entry free\n");
found:
ep->inum = 0;
bwrite (dp->dev, bp, bmap(dp, off/BSIZE)); // write directory block
brelse(bp);
iput(ip);
iupdate (dp);
iput(dp);
return 0;
}

View file

@ -76,7 +76,7 @@ ioapic_enable (int irq, int cpunum)
ioapic_write(io, IOAPIC_REDTBL_LO(irq), l);
h = ioapic_read(io, IOAPIC_REDTBL_HI(irq));
h &= ~IOART_DEST;
h |= (cpunum << APIC_ID_SHIFT); // for fun, disk interrupts to cpu 1
h |= (cpunum << APIC_ID_SHIFT);
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
cprintf("cpu%d: intr %d: lo 0x%x hi 0x%x\n", cpu(), irq, l, h);
}

View file

@ -265,10 +265,9 @@ sys_open(void)
if (l >= DIRSIZ)
return -1;
dp = iget(rootdev, 1); // XXX should parse name
if (dp->type != T_DIR)
return -1;
if ((ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0)) == 0)
return -1;
ip = mknod (dp, cp->mem + arg0, T_FILE, 0, 0);
iput(dp);
if (ip == 0) return -1;
} else return -1;
}
if((fd = fd_alloc()) == 0){
@ -319,45 +318,26 @@ sys_mknod(void)
return -1;
dp = iget(rootdev, 1); // XXX should parse name
if (dp->type != T_DIR) {
iput(dp);
return -1;
}
nip = mknod (dp, cp->mem + arg0, (short) arg1, (short) arg2,
(short) arg3);
iput(dp);
if (nip == 0) return -1;
iput(nip);
return 0;
return (nip == 0) ? -1 : 0;
}
int
sys_unlink(void)
{
struct proc *cp = curproc[cpu()];
struct inode *ip;
uint arg0;
int r;
if(fetcharg(0, &arg0) < 0)
return -1;
if(checkstring(arg0) < 0)
return -1;
ip = namei(cp->mem + arg0);
ip->nlink--;
if (ip->nlink <= 0) {
panic("sys_link: unimplemented\n");
}
iupdate(ip);
iput(ip);
return 0;
r = unlink(cp->mem + arg0);
return r;
}
int

View file

@ -5,7 +5,7 @@
// file system tests
char buf[2000];
char buf[3000];
char *echo_args[] = { "echo", "hello", "goodbye", 0 };
char *cat_args[] = { "cat", "README", 0 };
@ -62,13 +62,14 @@ main(void)
} else {
printf(stdout, "error: open doesnotexist failed!\n");
}
i = read(fd, buf, 10000);
i = read(fd, buf, 2000);
if (i == 2000) {
printf(stdout, "read succeeded\\n");
printf(stdout, "read succeeded\n");
} else {
printf(stdout, "read failed\n");
}
close(fd);
unlink("doesnotexist");
//exec("echo", echo_args);
printf(stdout, "about to do exec\n");
exec("cat", cat_args);