Mercurial > hg > CbC > CbC_xv6
view src/impl/fs_impl_private.cbc @ 309:c6cbe4711e02
tweak
author | menikon |
---|---|
date | Mon, 03 Feb 2020 15:29:54 +0900 |
parents | 4cf83e6ce534 |
children | b40deb55b7db |
line wrap: on
line source
#include "types.h" #include "defs.h" #include "param.h" #include "stat.h" #include "mmu.h" #include "proc.h" #include "spinlock.h" #include "buf.h" #include "fs.h" #include "file.h" #interface "fs_impl.h" /* fs_impl* createfs_impl2(); */ __code allocinode(struct fs_impl* fs_impl, uint dev, struct superblock* sb, __code next(int iget_val, ...)){ //:skip readsb(dev, sb); Gearef(cbc_context, fs_impl)->inum = 1; goto allocinode_loopcheck(fs_impl, inum, dev, sb, bp, dip, next(iget_val, ...)); } typedef struct buf buf; typedef struct dinode dinode; __code allocinode_loopcheck(struct fs_impl* fs_impl, int inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int iget_val, ...)){ //:skip if( inum < sb->ninodes){ goto allocinode_loop(fs_impl, inum, dev, type, sb, bp, dip, next(iget_val, ...)); } /* goto cbc_context->panic(...); */ } __code allocinode_loop(struct fs_impl* fs_impl, int inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int iget_val, ...)){ //:skip bp = bread(dev, IBLOCK(inum)); dip = (struct dinode*) bp->data + inum % IPB; if(dip->type = 0){ goto allocinode_noloop(fs_impl, inum, dev, sb, bp, dip, next(iget_val, ...)); } brelse(bp); inum++; goto allocinode_loopcheck(fs_impl, inum, dev, type, sb, bp, dip, next(iget_val, ...)); } struct { struct spinlock lock; struct inode inode[NINODE]; } icache; static struct inode* iget (uint dev, uint inum) { struct inode *ip, *empty; acquire(&icache.lock); // Is the inode already cached? empty = 0; for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) { ip->ref++; release(&icache.lock); return ip; } if (empty == 0 && ip->ref == 0) { // Remember empty slot. empty = ip; } } // Recycle an inode cache entry. if (empty == 0) { panic("iget: no inodes"); } ip = empty; ip->dev = dev; ip->inum = inum; ip->ref = 1; ip->flags = 0; release(&icache.lock); return ip; } __code allocinode_noloop(struct fs_impl* fs_impl, int inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int iget_val, ...)){ //:skip memset(dip, 0, sizeof(*dip)); dip->type = type; log_write(bp); brelse(bp); iget_val = iget(dev, inum); goto next(iget_val, ...); } __code lockinode1(struct fs_impl* fs_impl, struct inode* ip, struct buf* bp, struct dinode* dip, __code next(...)){ //:skip if (ip == 0 || ip->ref < 1) { /* panic("ilock"); goto panic(); */ } acquire(&icache.lock); goto lockinode_sleepcheck(fs_impl, ip, next(...)); } __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(...); }