view final_main/src/ialloc.cbc @ 17:c8fee0262ead

fix chapter5
author menikon
date Thu, 13 Feb 2020 01:50:45 +0900
parents
children
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"
#interface "Err.h"
#define min(a, b) ((a) < (b) ? (a) : (b))

/*
fs_impl* createfs_impl2();
*/

__code allocinode(struct fs_impl* fs_impl, uint dev, struct superblock* sb, __code next(...)){ //:skip

    readsb(dev, sb);
    Gearef(cbc_context, fs_impl)->inum = 1;
    goto allocinode_loopcheck(fs_impl, inum, dev, sb, bp, dip, next(...));

}

typedef struct buf buf;
typedef struct dinode dinode;

__code allocinode_loopcheck(struct fs_impl* fs_impl, uint inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...)){ //:skip
    if( inum < sb->ninodes){
        goto allocinode_loop(fs_impl, inum, dev, type, sb, bp, dip, next(...));
    }
    char* msg = "failed allocinode...";
    struct Err* err = createKernelError(&proc->cbc_context);
    Gearef(cbc_context, Err)->msg = msg;
    goto meta(cbc_context, err->panic);

}

__code allocinode_loop(struct fs_impl* fs_impl, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...)){ //: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(...));
    }

    brelse(bp);
    inum++;
    goto allocinode_loopcheck(fs_impl, inum, dev, type, sb, bp, dip, next(...));
}

struct {
    struct spinlock lock;
    struct inode inode[NINODE];
} icache;

static struct inode* iget (uint dev, uint inum)
{
    struct inode *ip, *empty;

    acquire(&icache.lock);

    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) {   
            empty = ip;
        }
    }

    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, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int ret, ...)){ //:skip

    memset(dip, 0, sizeof(*dip));
    dip->type = type;
    log_write(bp);
    brelse(bp);

    ret = iget(dev, inum);
    goto next(ret, ...);

}