diff options
author | kaashoek <kaashoek> | 2006-08-11 18:18:38 +0000 |
---|---|---|
committer | kaashoek <kaashoek> | 2006-08-11 18:18:38 +0000 |
commit | 24437cd554995f729969299e72699e2ba5d9b068 (patch) | |
tree | e3b5aa572c9621d1f932788fc882d4e6d693473f /fs.c | |
parent | 17a856577f9db766b8ef7099d0575d378dff5dd1 (diff) | |
download | xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.tar.gz xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.tar.bz2 xv6-labs-24437cd554995f729969299e72699e2ba5d9b068.zip |
fix deadlock---iput(dp) asap
working unlink, but doesn't free dir blocks that become empty
remove out-of-date comment in ioapic
Diffstat (limited to 'fs.c')
-rw-r--r-- | fs.c | 60 |
1 files changed, 59 insertions, 1 deletions
@@ -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; +} |