예제 #1
0
int get_blk_pointer(blk_pointers_t* pointers, int blknum)
{
    int indirect_pointers[BLKSIZ/BLKPOINTERSIZ];
    
    // If blk num is for a direct pointer
    if(blknum < NUMDIRECTPOINTERS) {
        if(pointers->direct[blknum] == 0) {
            if( (pointers->direct[blknum] = get_free_datablock()) == 0) return -1;     
        }
        return pointers->direct[blknum];
    }
    
    // If block num is the first indirect pointer entry
    if(pointers->indirect == 0) {
        if( (pointers->indirect = get_free_datablock()) == 0) return -1;
        memset(indirect_pointers, 0, BLKSIZ);
        write_blocks(pointers->indirect, 1, (void*)indirect_pointers);
    }
    
    // If block num is an indirect pointer entry that is not the first
    read_blocks(pointers->indirect, 1, (void*)indirect_pointers);  
    if(indirect_pointers[blknum - NUMDIRECTPOINTERS] == 0) {
        if( (indirect_pointers[blknum - NUMDIRECTPOINTERS] = get_free_datablock()) == 0) return -1;
        write_blocks(pointers->indirect, 1, (void*)indirect_pointers);
    }
    return indirect_pointers[blknum - NUMDIRECTPOINTERS];
}
예제 #2
0
int add_data_block(int inode_num)
{
    struct datablock *dblock = malloc(sizeof(struct datablock));
    struct indirection_block *iblock1;
    struct indirection_block *iblock2;
    struct inode_block *iblock;
    struct inode  *inode;

    int block_num;
    int new_db_num = get_free_datablock();
    DEBUG1 && printf("new db number: %d \n", new_db_num);

    if(new_db_num < 0)
        return -1;


    get_inode(&iblock, &inode, inode_num);

    block_num = inode->num_blocks;

    if(!inode)
    {
        DEBUG2 && printf("inode is null\n");
        return -1;
    }

    if(block_num >= 0 && block_num < 10)
    {
        inode->file_blocks[block_num] = new_db_num;
        inode->num_blocks++;

        if(put_inode_block(iblock, inode_num))
        {
            return -1;
        }

        free(iblock);

        return new_db_num;
    }

    else if(block_num == 10)
    {
        //make indirection block
        struct indirection_block *ib = malloc(sizeof(struct indirection_block));

        ib->pointer[0] = new_db_num;

        int ind_block_num = get_free_datablock();
        if(ind_block_num < 0)
            return -1;
        DEBUG1 && printf("adding indirection block: %d\n", ind_block_num);

        if(!write_block(file, ib, ind_block_num))
        {
            DEBUG2 && printf("Error writing indirection block\n");
            return -1;
        }

        inode->indirect1 = ind_block_num;
        inode->num_blocks++;

        if(put_inode_block(iblock, inode_num))
        {
            return -1;
        }

        free(ib);
        free(iblock);

        return new_db_num;
    }

    else if(block_num > 10 && block_num < (10+128))
    {
        struct indirection_block *ib = malloc(sizeof(struct indirection_block));

        int ind_block_num = inode->indirect1;

        if(!read_block(file, ib, ind_block_num))
        {
            DEBUG2 && printf("Error reading indirection block\n");
            return -1;
        }

        ib->pointer[block_num - 10] = new_db_num;

        if(! write_block(file, ib, ind_block_num))
        {
            DEBUG2 && printf("Error writing indirection block\n");
            return -1;
        }

        inode->num_blocks++;

        if(put_inode_block(iblock, inode_num))
        {
            return -1;
        }

        free(ib);
        free(iblock);

        return new_db_num;
    }

    else if(block_num == (10+128))
    {
        struct indirection_block *ib1 = malloc(sizeof(struct indirection_block));
        struct indirection_block *ib2 = malloc(sizeof(struct indirection_block));

        int ind_block_num1 = get_free_datablock();
        int ind_block_num2 = get_free_datablock();

        if(ind_block_num1 < 0 || ind_block_num2 < 0)
            return -1;

        inode->indirect2 = ind_block_num1;
        inode->num_blocks++;

        ib1->pointer[0] = ind_block_num2;
        ib2->pointer[0] = new_db_num;

        if(!write_block(file, ib1, ind_block_num1))
        {
            DEBUG2 && printf("Error writing indirection block\n");
            return -1;
        }

        if(!write_block(file, ib2, ind_block_num2))
        {
            DEBUG2 && printf("Error writing indirection block\n");
            return -1;
        }

        if(put_inode_block(iblock, inode_num))
        {
            return -1;
        }

        free(ib1);
        free(ib2);
        free(iblock);

        return new_db_num;
    }

    else if(block_num > (10+128) && block_num < (10+128+(128*128)))
    {
        struct indirection_block *ib1 = malloc(sizeof(struct indirection_block));
        struct indirection_block *ib2 = malloc(sizeof(struct indirection_block));

        int ind_block_num1 = inode->indirect2;

        if( !read_block(file, ib1, ind_block_num1))
        {
            DEBUG2 && printf("error reading datablock\n");
            return -1;
        }

        if(((block_num - (10+128)) % 128) == 0)
        {
            int new_ind_block = get_free_datablock();
            ib1->pointer[(block_num - (10+128)) / 128] = new_ind_block;
            ib2->pointer[0] = new_db_num;
            inode->num_blocks++;

            if(!write_block(file, ib1, ind_block_num1))
            {
                DEBUG2 && printf("error reading datablock\n");
                return -1;
            }

            if(!write_block(file, ib2, new_ind_block))
            {
                DEBUG2 && printf("error reading datablock\n");
                return -1;
            }
            if(put_inode_block(iblock, inode_num))
            {
                return -1;
            }

            return new_db_num;
        }

        else
        {
            int ind_block_num2 = ib1->pointer[(block_num - (10+128)) / 128];

            if(!read_block(file, ib2, ind_block_num2))
            {
                DEBUG2 && printf("error reading datablock\n");
                return -1;
            }

            ib2->pointer[(block_num - (10+128)) % 128] = new_db_num;

            inode->num_blocks++;

            if( !write_block(file, ib2, ind_block_num2))
            {
                DEBUG2 && printf("error reading datablock\n");
                return -1;
            }

            if(put_inode_block(iblock, inode_num))
            {
                return -1;
            }

            return new_db_num;
        }
    }

    else
    {
        DEBUG2 && printf("Error: cannot add another block, filesize max reached\n");
        return -1;
    }

    return new_db_num;
}