Example #1
0
/* Establish the file system and write it to disk */
int
fs_format(mem_sblock_t sbp)
{
    blocknum_t inode_bitmap_size;
    blocknum_t block_bitmap_size;
    blocknum_t i;
    sbp->filesys_lock = semaphore_new(1);
    if (NULL == sbp->filesys_lock) {
        return -1;
    }

    fs_lock(sbp);

    /* Format super block */
    sblock_get(maindisk, sbp);
    sblock_format(sbp, disk_size);
    sblock_update(sbp);

    /* Format inode and block bitmaps */
    inode_bitmap_size = sbp->inode_bitmap_last - sbp->inode_bitmap_first + 1;
    sbp->inode_bitmap = malloc(inode_bitmap_size * DISK_BLOCK_SIZE);
    block_bitmap_size = sbp->block_bitmap_last - sbp->block_bitmap_first + 1;
    sbp->block_bitmap = malloc(block_bitmap_size * DISK_BLOCK_SIZE);
    if (NULL == sbp->block_bitmap || NULL == sbp->inode_bitmap) {
        semaphore_V(sbp->filesys_lock);
        return -1;
    }
    /* Clear bitmaps */
    bitmap_zeroall(sbp->inode_bitmap, inode_bitmap_size * BITS_PER_BLOCK);
    bitmap_zeroall(sbp->block_bitmap, block_bitmap_size * BITS_PER_BLOCK);
    /* Set file system blocks to be occupied */
    for (i = 0; i <= sbp->block_bitmap_last; ++i) {
        bitmap_set(sbp->block_bitmap, i);
    }
    /* Set inode 0 to be occupied */
    bitmap_set(sbp->inode_bitmap, 0);
    /* Push updates to disk */
    for (i = sbp->inode_bitmap_first; i <= sbp->inode_bitmap_last; ++i) {
        bpush(i, (char*) sbp->inode_bitmap + (i - sbp->inode_bitmap_first)
              * DISK_BLOCK_SIZE);
    }
    for (i = sbp->block_bitmap_first; i <= sbp->block_bitmap_last; ++i) {
        bpush(i, (char*) sbp->block_bitmap + (i - sbp->block_bitmap_first)
              * DISK_BLOCK_SIZE);
    }

    /* Count free inodes and free blocks */
    mainsb->free_inodes = bitmap_count_zero(mainsb->inode_bitmap,
                                            mainsb->total_inodes);
    mainsb->free_blocks = bitmap_count_zero(mainsb->block_bitmap,
                                            mainsb->disk_num_blocks);

    fs_unlock(sbp);
    return 0;
}
Example #2
0
void balblk() 
{
    BTint val,llink,rlink,cblk;
    int nkeys,cnkeys,result,diff;
    char tkey[ZKYLEN];

    cblk = btact->cntxt->lf.lfblk;
    /* get parent block */
    btact->cntxt->lf.lfpos = bpull();
    btact->cntxt->lf.lfblk = bpull();
    nkeys = bgtinf(btact->cntxt->lf.lfblk,ZNKEYS);
    cnkeys = bgtinf(cblk,ZNKEYS);
    if (btact->cntxt->lf.lfpos < nkeys) {
        /* check right sister block */
        bsrhbk(btact->cntxt->lf.lfblk,tkey,&btact->cntxt->lf.lfpos,&val,
               &llink,&rlink,&result);
        if (result != 0) {
            bterr("BALBLK",QBALSE,NULL);
            goto fin;
        }
        nkeys = bgtinf(rlink,ZNKEYS);
        diff = cnkeys-nkeys;
        if (abs(diff) > (int)(ZMXKEY/2)) {
            balbk1(cblk,rlink,diff,tkey,val);
            goto fin;
        }
    }
    if (btact->cntxt->lf.lfpos > 0) {
        /* check left sister block */
        btact->cntxt->lf.lfpos--;
        bsrhbk(btact->cntxt->lf.lfblk,tkey,&btact->cntxt->lf.lfpos,
               &val,&llink,&rlink,&result);
        if (result != 0) {
            bterr("BALBLK",QBALSE,NULL);
            goto fin;
        }
        nkeys = bgtinf(llink,ZNKEYS);
        diff = nkeys-cnkeys;
        if (abs(diff) > (int)(ZMXKEY/2)) {
            balbk1(llink,cblk,diff,tkey,val);
            goto fin;
        }
        btact->cntxt->lf.lfpos++;
    }
    /* no balancing possible; restore original environment */
    bpush(btact->cntxt->lf.lfblk);
    bpush(btact->cntxt->lf.lfpos);
    btact->cntxt->lf.lfblk = cblk;
fin:
    return;
}
Example #3
0
/*
 * Allocate a free inode and return a pointer to free inode
 * Return NULL if fail.
 */
inodenum_t
ialloc(disk_t* disk)
{
    inodenum_t free_bit = -1;
    inodenum_t block_offset = -1;

    fs_lock(mainsb);
    if (mainsb->free_inodes <= 0) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Get free inode number */
    free_bit = bitmap_next_zero(mainsb->inode_bitmap, mainsb->disk_num_blocks);
    block_offset = free_bit / BITS_PER_BLOCK;
    if (free_bit < 0 || block_offset >= mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Set the free inode to used */
    bitmap_set(mainsb->inode_bitmap, free_bit);
    bpush(block_offset + mainsb->inode_bitmap_first,
          (char*) mainsb->inode_bitmap + block_offset * DISK_BLOCK_SIZE);

    mainsb->free_inodes--;
    fs_unlock(mainsb);

    return free_bit;
}
Example #4
0
/* Set a block to used */
void
bset(blocknum_t blocknum)
{
    blocknum_t bit = -1;
    blocknum_t block_offset;

    fs_lock(mainsb);
    if (blocknum <= mainsb->block_bitmap_last || blocknum >=mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return;
    }

    /* Set the block to free */
    bit = blocknum;
    block_offset = bit / BITS_PER_BLOCK;

    if (bitmap_get(mainsb->block_bitmap, bit) == 0) {
        bitmap_set(mainsb->block_bitmap, bit);
        bpush(block_offset + mainsb->block_bitmap_first,
            (char*) mainsb->block_bitmap + block_offset * DISK_BLOCK_SIZE);
        mainsb->free_blocks--;
    }

    fs_unlock(mainsb);
}
Example #5
0
/* Get a free block number from the disk and mark the block used */
blocknum_t
balloc(disk_t* disk)
{
    blocknum_t free_bit = -1;
    blocknum_t block_offset = -1;

    /* Get super block */
    fs_lock(mainsb);
    if (mainsb->free_blocks <= 0) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Get free block number */
    free_bit = bitmap_next_zero(mainsb->block_bitmap, mainsb->disk_num_blocks);
    block_offset = free_bit / BITS_PER_BLOCK;
    if (block_offset < 0 || block_offset >= mainsb->disk_num_blocks) {
        fs_unlock(mainsb);
        return -1;
    }

    /* Set the free block to used */
    bitmap_set(mainsb->block_bitmap, free_bit);
    bpush(block_offset + mainsb->block_bitmap_first,
          (char*) mainsb->block_bitmap + block_offset * DISK_BLOCK_SIZE);

    mainsb->free_blocks--;
    fs_unlock(mainsb);

    return free_bit;
}
Example #6
0
/* Add an inode back to free list */
void
ifree(inodenum_t inum)
{
    blocknum_t bit = -1;
    blocknum_t block_offset;

    fs_lock(mainsb);

    /* Set the inode to free */
    bit = inum;
    block_offset = bit / BITS_PER_BLOCK;
    if (bitmap_get(mainsb->inode_bitmap, bit) == 1) {
        mainsb->free_inodes++;
    }
    bitmap_clear(mainsb->inode_bitmap, bit);
    bpush(block_offset + mainsb->inode_bitmap_first,
          (char*) mainsb->inode_bitmap + block_offset * DISK_BLOCK_SIZE);

    fs_unlock(mainsb);
}
Example #7
0
int bfndky(BTA *b,char *key,BTint *val)
{
    BTint cblk, link1, link2, newblk;
    int index, result, nkeys, status;
    char lkey[ZKYLEN];
    
    bterr("",0,NULL);
    status = QNOKEY;
    if ((result=bvalap("BFNDKY",b)) != 0) return(result);

    btact = b;      /* set context pointer */

    if (btact->shared) {
        if (!block()) {
            bterr("BFNDKY",QBUSY,NULL);
            goto fin;
        }
    }

    /* take local copy of key, truncating if necessary */
    strncpy(lkey,key,ZKYLEN);
    lkey[ZKYLEN-1] = '\0';
    
    /* initialise stack etc */
    btact->cntxt->lf.lfexct = FALSE;
    cblk = btact->cntxt->super.scroot;
    bstkin();
    btact->cntxt->lf.lfblk = -1;
    btact->cntxt->lf.lfpos = -1;
    strcpy(btact->cntxt->lf.lfkey,lkey);

    while (cblk >= 0) {
#if DEBUG >= 2
        fprintf(stderr,"BFNDKY: searching block " ZINTFMT "\n",cblk);
#endif      
        nkeys = bgtinf(cblk,ZNKEYS);
        if (nkeys == ZMXKEY && btact->cntxt->super.smode == 0) {
            /* split if block full and updating permitted */
            bsptbk(cblk,&newblk);
            if (newblk < 0) {
                bterr("BFNDKY",QSPLIT,NULL);
                break;
            }
            /* if split occured, then must re-examine parent */
            if (cblk != btact->cntxt->super.scroot) {
                index  = btact->cntxt->lf.lfpos;
                cblk = btact->cntxt->lf.lfblk;
                btact->cntxt->lf.lfpos = bpull();
                btact->cntxt->lf.lfblk = bpull();
            }
        }
        else {
            index = -1;
            bpush(btact->cntxt->lf.lfblk);
            bpush(btact->cntxt->lf.lfpos);
            bsrhbk(cblk,lkey,&index,val,&link1,&link2,&result);
            btact->cntxt->lf.lfblk = cblk;
            btact->cntxt->lf.lfpos = index; /* if block is empty, leave lfpos at -1 */
            if (result < 0) {
                /* must examine left block */
                cblk = link1;
                continue;
            }
            else if (result > 0) {
                /* must examine right block */
                cblk = link2;
                /* increment index to indicate this key "visited" */
                btact->cntxt->lf.lfpos++;
                continue;
            }
            else {
                status = 0;
                btact->cntxt->lf.lfexct = TRUE;
                break;
            }
        }
    }  
fin:
    if (btact->shared) bulock();
    /* non-zero status indicates no such key found */
    if (status) bterr("BFNDKY",QNOKEY,lkey);
    return(btgerr());
}