Mercurial > hg > CbC > CbC_xv6
view src/impl/fs_impl.cbc @ 312:b527f27761bf
tweak
author | menikon |
---|---|
date | Wed, 05 Feb 2020 15:35:04 +0900 |
parents | b40deb55b7db |
children | 66a6aedf60f9 |
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(...)) { goto iput_check(fs, ip, next(...)); } __code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { goto next(...); } 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 n, __code next(...)) { goto 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* dp, char* name, uint inum, __code next(...)) { goto 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, ...); }