Mercurial > hg > Members > menikon > CbC_xv6
changeset 246:4cf83e6ce534
add iput codeGear
author | menikon |
---|---|
date | Sat, 01 Feb 2020 18:08:31 +0900 |
parents | 5ea0b8b12aaf |
children | 1ba0ca4113e1 |
files | src/impl/fs_impl.cbc src/impl/fs_impl.h src/impl/fs_impl_private.cbc |
diffstat | 3 files changed, 134 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/impl/fs_impl.cbc Fri Jan 31 18:48:54 2020 +0900 +++ b/src/impl/fs_impl.cbc Sat Feb 01 18:08:31 2020 +0900 @@ -36,9 +36,12 @@ fs->idup = C_idupfs_impl; fs->ilock = C_ilockfs_impl; fs_impl->lockinode1 = C_lockinode1; + fs_impl->lockinode2 = C_lockinode2; fs_impl->lockinode_sleepcheck = C_lockinode_sleepcheck; fs->iunlock = C_iunlockfs_impl; fs->iput = C_iputfs_impl; + fs_impl->iput_check = C_iput_check; + fs_impl->iput_inode_nolink = C_iput_inode_nolink; fs->iunlockput = C_iunlockputfs_impl; fs->stati = C_statifs_impl; fs->readi = C_readifs_impl; @@ -117,13 +120,26 @@ } __code iunlockfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + + if (ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1) { + /* + panic("iunlock"); + goto panic(); + */ + } + + acquire(&icache.lock); + ip->flags &= ~I_BUSY; + wakeup(ip); + release(&icache.lock); goto next(...); } __code iputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { - goto next(...); + goto iput_check(fs, ip, next(...)); + } __code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) {
--- a/src/impl/fs_impl.h Fri Jan 31 18:48:54 2020 +0900 +++ b/src/impl/fs_impl.h Sat Feb 01 18:08:31 2020 +0900 @@ -13,6 +13,9 @@ __code allocinode_loopcheck(Type* fs_impl, int inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int iget_val, ...)); __code allocinode_noloop(struct fs_impl* fs_impl, int inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int iget_val, ...)); __code lockinode1(Type* fs_impl, struct inode *ip, struct buf *bp, struct dinode *dip, __code next(...)); + __code lockinode2(struct fs_impl* fs_impl, struct inode* ip, struct buf* bp, struct dinode* dip, __code next(...)); __code lockinode_sleepcheck(struct fs_impl* fs_impl, struct inode* ip, __code next(...)); + __code iput_check(struct fs_impl* fs_impl, struct inode* ip, __code next(...)); + __code iput_inode_nolink(struct fs_impl* fs_impl, struct inode* ip, __code next(...)); __code next(...); } fs_impl;
--- a/src/impl/fs_impl_private.cbc Fri Jan 31 18:48:54 2020 +0900 +++ b/src/impl/fs_impl_private.cbc Sat Feb 01 18:08:31 2020 +0900 @@ -114,11 +114,125 @@ } + +__code lockinode2(struct fs_impl* fs_impl, struct inode* ip, struct buf* bp, struct dinode* dip, __code next(...)){ //:skip + + ip->flags |= I_BUSY; + release(&icache.lock); + + if (!(ip->flags & I_VALID)) { + bp = bread(ip->dev, IBLOCK(ip->inum)); + + dip = (struct dinode*) bp->data + ip->inum % IPB; + ip->type = dip->type; + ip->major = dip->major; + ip->minor = dip->minor; + ip->nlink = dip->nlink; + ip->size = dip->size; + + memmove(ip->addrs, dip->addrs, sizeof(ip->addrs)); + brelse(bp); + ip->flags |= I_VALID; + + if (ip->type == 0) { + /* + panic("ilock: no type"); + goto panic(); + */ + } + } + goto next(...); +} __code lockinode_sleepcheck(struct fs_impl* fs_impl, struct inode* ip, __code next(...)){ if(ip->flags & I_BUSY){ sleep(ip, &icache.lock); goto lockinode_sleepcheck(fs_impl, ip, next(...)); } + goto lockinode2(fs_impl, ip, bp, dip, next(...)); +} + +__code iput_check(struct fs_impl* fs_impl, struct inode* ip, __code next(...)){ + acquire(&icache.lock); + if (ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) { + goto iput_inode_nolink(fs_impl, ip, next(...)); + } + ip->ref--; + release(&icache.lock); + goto next(...); + +} + +static void bfree (int dev, uint b) +{ + struct buf *bp; + struct superblock sb; + int bi, m; + + readsb(dev, &sb); + bp = bread(dev, BBLOCK(b, sb.ninodes)); + bi = b % BPB; + m = 1 << (bi % 8); + + if ((bp->data[bi / 8] & m) == 0) { + panic("freeing free block"); + } + + bp->data[bi / 8] &= ~m; + log_write(bp); + brelse(bp); +} + + +static void itrunc (struct inode *ip) +{ + int i, j; + struct buf *bp; + uint *a; + + for (i = 0; i < NDIRECT; i++) { + if (ip->addrs[i]) { + bfree(ip->dev, ip->addrs[i]); + ip->addrs[i] = 0; + } + } + + if (ip->addrs[NDIRECT]) { + bp = bread(ip->dev, ip->addrs[NDIRECT]); + a = (uint*) bp->data; + + for (j = 0; j < NINDIRECT; j++) { + if (a[j]) { + bfree(ip->dev, a[j]); + } + } + + brelse(bp); + bfree(ip->dev, ip->addrs[NDIRECT]); + ip->addrs[NDIRECT] = 0; + } + + ip->size = 0; + iupdate(ip); +} + +__code iput_inode_nolink(struct fs_impl* fs_impl, struct inode* ip, __code next(...)){ + + 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); goto next(...); } +