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:
parent
17a856577f
commit
24437cd554
5 changed files with 73 additions and 33 deletions
1
defs.h
1
defs.h
|
@ -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
60
fs.c
|
@ -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;
|
||||
}
|
||||
|
|
2
ioapic.c
2
ioapic.c
|
@ -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);
|
||||
}
|
||||
|
|
34
syscall.c
34
syscall.c
|
@ -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
|
||||
|
|
7
userfs.c
7
userfs.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue