Mercurial > hg > Members > menikon > CbC_xv6
view src/impl/fs_impl.cbc @ 258:71c7bd0d047e
build success
author | menikon |
---|---|
date | Thu, 06 Feb 2020 17:21:04 +0900 |
parents | d4ff2fb275b5 |
children | 40e9dd5ff084 |
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.dg" // ---- // typedef struct fs_impl<Impl, Isa> impl fs{ // union Data* fs_impl; // // // // // } fs_impl; // ---- fs* createfs_impl(struct Context* cbc_context) { struct fs* fs = new fs(); struct fs_impl* fs_impl = new fs_impl(); fs->fs = (union Data*)fs_impl; fs_impl->fs_impl = NULL; fs->readsb = C_readsbfs_impl; fs->iinit = C_iinitfs_impl; fs->ialloc = C_iallocfs_impl; fs_impl->allocinode = C_allocinode; fs_impl->allocinode_loop = C_allocinode_loop; fs_impl->allocinode_loopcheck = C_allocinode_loopcheck; fs_impl->allocinode_noloop = C_allocinode_noloop; fs->iupdate = C_iupdatefs_impl; 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; fs->writei = C_writeifs_impl; fs->namecmp = C_namecmpfs_impl; fs->dirlookup = C_dirlookupfs_impl; fs->dirlink = C_dirlinkfs_impl; fs->namei = C_nameifs_impl; fs->nameiparent = C_nameiparentfs_impl; return fs; } typedef struct superblock superblock; __code readsbfs_impl(struct fs_impl* fs, uint dev, struct superblock* sb, __code next(...)) { //:skip struct buf* bp; bp = bread(dev, 1); memmove(sb, bp->data, sizeof(*sb)); brelse(bp); goto next(...); } struct { struct spinlock lock; struct inode inode[NINODE]; } icache; __code iinitfs_impl(struct fs_impl* fs, __code next(...)) { initlock(&icache.lock, "icache"); goto next(...); } __code iallocfs_impl(struct fs_impl* fs, uint dev, short type, __code next(...)) { goto allocinode(fs, dev, sb, next(...)); } __code iupdatefs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { struct buf *bp; struct dinode *dip; bp = bread(ip->dev, IBLOCK(ip->inum)); dip = (struct dinode*) bp->data + ip->inum % IPB; dip->type = ip->type; dip->major = ip->major; dip->minor = ip->minor; dip->nlink = ip->nlink; dip->size = ip->size; memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); log_write(bp); brelse(bp); goto next(...); } __code idupfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { acquire(&icache.lock); ip->ref++; release(&icache.lock); goto next(ip, ...); } __code ilockfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { goto lockinode1(fs, ip, bp, dip, next(...)); } __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(...)) { if (next == C_iputfs_impl) { next = fs->next2; } goto iput_check(fs, ip, next(...)); } __code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { fs->next2 = next; goto iunlockfs_impl(ip, fs->iput, ...); } typedef struct stat stat; __code statifs_impl(struct fs_impl* fs , struct inode* ip, struct stat* st, __code next(...)) { //:skip st->dev = ip->dev; st->ino = ip->inum; st->type = ip->type; st->nlink = ip->nlink; st->size = ip->size; goto next(...); } __code readifs_impl(struct fs_impl* fs, struct inode* ip, char* dst, uint off, uint tot, uint n, __code next(int ret, ...)) { if (ip->type == T_DEV) { goto readi_check_diskinode(fs, ip, dst, n, next(...)); } if (off > ip->size || off + n < off) { ret = -1; goto next(ret, ...); } if (off + n > ip->size) { n = ip->size - off; } Gearef(cbc_context, fs)->tot = 0; goto readi_loopcheck(fs, tot, m, dst, off, n, next(...)); } __code writeifs_impl(struct fs_impl* fs, struct inode* ip, char* src, uint off, uint n, __code next(...)) { goto next(...); } __code namecmpfs_impl(struct fs_impl* fs, const char* s, const char* t, __code next(int strncmp_val, ...)) { strncmp_val = strncmp(s, t, DIRSIZ); goto next(strncmp_val, ...); } __code dirlookupfs_impl(struct fs_impl* fs, struct inode* dp, char* name, uint off, uint* poff, dirent* de, __code next(...)) { //:skip if (dp->type != T_DIR) { /* panic("dirlookup not DIR"); */ } Gearef(cbc_context, fs)->off = 0; goto dirlookup_loopcheck(fs, dp, name, off, poff, de, next(...)); } __code dirlinkfs_impl(struct fs_impl* fs, struct inode* ip, struct dirent* de, struct inode* dp, char* name, uint off, uint inum, __code next(...)) { //:skip // Check that name is not present. if ((ip = dirlookup(dp, name, 0)) != 0) { goto dirlink_namecheck(fs, ip, next(...)); } Gearef(cbc_context, fs)->off = 0; goto dirlink_loopcheck(fs, de, dp, off, next(...)); } 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; } static char* skipelem (char *path, char *name) { char *s; int len; while (*path == '/') { path++; } if (*path == 0) { return 0; } s = path; while (*path != '/' && *path != 0) { path++; } len = path - s; if (len >= DIRSIZ) { memmove(name, s, DIRSIZ); } else { memmove(name, s, len); name[len] = 0; } while (*path == '/') { path++; } return path; } static struct inode* namex (char *path, int nameiparent, char *name) { struct inode *ip, *next; if (*path == '/') { ip = iget(ROOTDEV, ROOTINO); } else { ip = idup(proc->cwd); } while ((path = skipelem(path, name)) != 0) { ilock(ip); if (ip->type != T_DIR) { iunlockput(ip); return 0; } if (nameiparent && *path == '\0') { // Stop one level early. iunlock(ip); return ip; } if ((next = dirlookup(ip, name, 0)) == 0) { iunlockput(ip); return 0; } iunlockput(ip); ip = next; } if (nameiparent) { iput(ip); return 0; } return ip; } __code nameifs_impl(struct fs_impl* fs, char* path, __code next(int namex_val, ...)) { char name[DIRSIZ]; namex_val = namex(path, 0, name); goto next(namex_val, ...); } __code nameiparentfs_impl(struct fs_impl* fs, char* path, char* name, __code next(int namex_val, ...)) { namex_val = namex(path, 1, name); goto next(namex_val, ...); }