예제 #1
0
파일: inode.c 프로젝트: Arseny-N/fgfs
static int gfs_zero_inode(struct gfs_inode_info *inode)
{
	struct gfs_super_info *sb = (struct gfs_super_info *)inode->vfs_inode.i_sb->s_fs_info;
	int nblocks = sb->s_chunk_size, i;
	
	for( i = 0;i<nblocks; ++i ) {
		struct buffer_head *bh = get_inode_block(inode, i, 1);
		if(!bh)
			return -ENOMEM;
		memset(bh->b_data, 0, bh->b_size);
		put_inode_block(inode,1);
	}
	return 0;
}
예제 #2
0
int create_file(char *path, int is_dir)
{
    char *lpath = malloc(sizeof(char)*strlen(path)+1);
    char *last;
    char *ptr;
    int wd, free_inode_num, found, s;

    struct inode_block *cur_inode_block = NULL;
    struct inode *cur_inode = NULL;

    strcpy(lpath, path);

    if(strlen(lpath) == 1)
    {
        if(lpath[0] == '/')
        {
            return ERR_FILE_EXISTS;
        }
        else
        {
            return ERR_INVALID_PATH;
        }
    }

    ptr = strrchr(lpath, '/');


    if(ptr == lpath+strlen(lpath)-1)
    {
        *ptr = '\0';
        ptr = strrchr(lpath, '/');
    }

    *ptr = '\0';
    ptr++;

    last = malloc(sizeof(char)*strlen(ptr)+1);

    strcpy(last, ptr);

    wd = path_to_inode(lpath);

    DEBUG1 &&  printf("wd = %d \n", wd);

    if(wd < 0)
    {
        return ERR_INVALID_PATH;
    }
    //printf("wd inode = %d \n", wd);

    get_inode(&cur_inode_block, &cur_inode, wd);

    if(cur_inode_block == NULL || cur_inode == NULL)
    {
        DEBUG2 && 	printf("get inode failed\n");
        return ERR_INTERNAL;
    }

    found = has_file(cur_inode, last);
    //printf("found = %d \n", found);
    DEBUG1 && printf("found = %d \n", found);

    if(found != -1)
    {
        //printf("file or dir already exists!\n");
        //printf("wd = %d, last = %s \n ", wd, last);
        return ERR_FILE_EXISTS;
    }

    free_inode_num = get_free_inode();
    //printf("free inode num = %d\n", free_inode_num);

    if(free_inode_num < 0)
    {
        return ERR_MAX_FILES;
    }

    get_inode( &cur_inode_block, &cur_inode , free_inode_num);

    if(cur_inode_block == NULL || cur_inode == NULL)
    {
        return ERR_INTERNAL;
    }

    cur_inode->is_dir = is_dir;

    put_inode_block(cur_inode_block, free_inode_num);

    //free_data_block_num = get_free_datablock();
    //printf("free_data_block_num = %d\n", free_data_block_num);

    s = add_dir_to_inode(wd, last, free_inode_num);

    return s;
}
예제 #3
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;
}
예제 #4
0
//find free inode, remove from free inode list, return inode number
int get_free_inode(void)
{
    struct superblock *sb = malloc(sizeof(struct superblock));
    struct inode_block *iblock;
    struct inode *inode;

    int inode_num;
    int new_free;
    int i;

    if(! read_block(file, sb, 1))
    {
        DEBUG2 && printf("Error reading superblock\n");
        return -1;
    }

    if( (inode_num = sb->free_inode_list) == -1)
    {
        DEBUG2 && printf("Error no free inodes\n");
        return -1;
    }

    if(get_inode(&iblock, &inode, inode_num))
    {
        DEBUG2 && 	printf("ERROR: couldn't get inode \n ");
        return -1;
    }

    new_free = inode->next_free_inode;

    inode->next_free_inode = -2;
    inode->is_free=0;
    inode->num_blocks=0;
    inode->is_dir=0;

    for(i=0; i < 10 ; i++)
    {
        inode->file_blocks[i] = 0;
    }

    inode->indirect1 = 0;
    inode->indirect2 = 0;


    DEBUG1 && printf("new_free: %d \n", new_free);

    sb->free_inode_list = new_free;
    sb->files_allocated++;

    if(! write_block(file, sb, 1))
    {
        DEBUG2 && printf("Error writing superblock\n");
        return -1;
    }

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

    free(sb);
    free(iblock);

    return inode_num;
}
예제 #5
0
int delete_file(char *path)
{
    char *lpath = malloc(sizeof(char)*strlen(path)+1);
    char *orig_path = malloc(sizeof(char)*strlen(path)+1);
    char *last;
    char *ptr;
    char null_array[12];
    int wd, free_inode_num, found, s;
    int inode_num;
    struct inode_block *ib = NULL;
    struct inode *inode = NULL;
    struct inode_block *doomed_ib = NULL;
    struct inode *doomed_inode = NULL;
    struct directory *dir = NULL;
    struct datablock *datablock = NULL;
    struct directory *ldir = NULL;
    struct datablock *ldatablock = NULL;
    int doomed_inode_num;
    int i, j, k, foundit = 0;
    int cur_db_num, last_db_num;

    /*
      for(i=0;i<12;i++){
        null_array[i] = '\0';
      }
      */

    strcpy(lpath, path);
    strcpy(orig_path, path);

    if(strlen(lpath) == 1)
    {
        if(lpath[0] == '/')
        {
            return ERR_FILE_EXISTS; //update this to correct val
        }
        else
        {
            return ERR_INVALID_PATH;
        }
    }

    ptr = strrchr(lpath, '/');


    if(ptr == lpath+strlen(lpath)-1)
    {
        *ptr = '\0';
        ptr = strrchr(lpath, '/');
    }

    ptr++;

    last = malloc(sizeof(char)*strlen(ptr)+1);

    strcpy(last, ptr);

    *ptr = '\0';

    wd = path_to_inode(lpath);

    DEBUG1 && printf("lpath = %s last = %s \n", lpath, last);

    //funct to remove all data blocks

    if((doomed_inode_num = path_to_inode(orig_path)) < 0)
    {
        DEBUG1 && printf("cannot delete, does not exist\n");
        return ERR_FILE_NOT_FOUND;
    }

    if((get_inode(&doomed_ib, &doomed_inode, doomed_inode_num)) < 0)
    {
        DEBUG2 && printf("error get_inode\n");
        return -1;
    }

    if(doomed_inode->is_dir != 0 && doomed_inode->num_blocks > 0)
    {
        DEBUG1 && printf("cannot delete a none empty directory");
        return ERR_INVALID_PATH;//should be a different error
    }

    erase_inode(doomed_inode_num);


    //funct to remove from dir

    if((inode_num = path_to_inode(lpath)) < 0)
    {
        DEBUG2 && printf("error path_to_inode\n");
        return -1;
    }

    if((get_inode(&ib, &inode, inode_num)) < 0)
    {
        DEBUG2 && printf("error get_inode\n");
        return -1;
    }

    for(i=0; i<inode->num_blocks; i++)
    {
        cur_db_num = get_data_block(&datablock, inode, i);
        dir = (struct directory *)datablock;
        for(j=0; j<32; j++)
        {
            if(strcmp(last,dir->entries[j].filename) == 0 )
            {
                DEBUG1 && printf("got it!\n");
                //strcpy(dir->entries[j].filename, "");
                //dir->entries[j].inode_number = 0;
                foundit = 1;
                //write_block(file, dir, cur_db_num);
                break;
            }
        }
        if(foundit)
        {
            break;
        }
    }

    if(!foundit)
    {
        return -1;
    }

    last_db_num = get_data_block(&ldatablock, inode, inode->num_blocks-1);
    ldir = (struct directory *)ldatablock;


    if(last_db_num == cur_db_num)
    {
        for(k=0; k<32; k++)
        {
            if(dir->entries[k].inode_number == 0)
            {
                //k++;
                break;
            }
        }
        // k-1 is the one we want, even if we went all the way to the end.
        strcpy(dir->entries[j].filename, dir->entries[k-1].filename);
        dir->entries[j].inode_number = dir->entries[k-1].inode_number;
        for(i=0; i<12; i++)
        {
            dir->entries[k-1].filename[i] = '\0';
        }
        dir->entries[k-1].inode_number = 0;
        write_block(file, dir, cur_db_num);

        if(k-1 == 0)
        {
            //add last_db_num to free blocks
            if(make_free_datablock(last_db_num))
            {
                DEBUG2 && printf("couldnt free datablock\n");
            }
            //subtract a datablock from inode->num_blocks
            //WE NEED TO ADD STUFF TO SUBTRACT INDIRECTION BLOCKS
            inode->num_blocks--;
            DEBUG1 && printf("inode->num_blocks = %d \n", inode->num_blocks);
            //write the inode back
            put_inode_block(ib, inode_num);
            trim_indirection_blocks(inode_num);
        }

    }
    else
    {

        for(k=0; k<32; k++)
        {
            if(ldir->entries[k].inode_number == 0)
            {
                //k++;
                break;
            }
        }
        // k-1 is the one we want, even if we went all the way to the end.
        strcpy(dir->entries[j].filename, ldir->entries[k-1].filename);
        dir->entries[j].inode_number = ldir->entries[k-1].inode_number;
        for(i=0; i<12; i++)
        {
            ldir->entries[k-1].filename[i] = '\0';
        }
        ldir->entries[k-1].inode_number = 0;

        write_block(file, dir, cur_db_num);
        write_block(file, ldir, last_db_num);
        if(k-1 == 0)
        {
            //add last_db_num to free blocks
            if(make_free_datablock(last_db_num))
            {
                DEBUG1 && printf("couldnt free datablock\n");
            }
            //subtract a datablock from inode->num_blocks
            //WE NEED TO ADD STUFF TO SUBTRACT INDIRECTION BLOCKS
            inode->num_blocks--;
            DEBUG1 && printf("inode->num_blocks = %d \n", inode->num_blocks);
            //write the inode back
            put_inode_block(ib, inode_num);
            trim_indirection_blocks(inode_num);
        }
    }
    return SUCCESS;
}
예제 #6
0
int trim_indirection_blocks(int inode_num)
{
    struct inode_block *ib = NULL;
    struct inode *inode = NULL;
    struct indirection_block *idb = malloc(sizeof(struct indirection_block));
    int num_blocks;



    if((get_inode(&ib, &inode, inode_num)) < 0)
    {
        DEBUG2 && printf("error get_inode\n");
        return -1;
    }

    num_blocks = inode->num_blocks;


    if(num_blocks < 10 && inode->indirect1 != 0)
    {
        //remove inode->indirect1
        make_free_datablock(inode->indirect1);
        inode->indirect1 = 0;
        put_inode_block(ib, inode_num);
        return 1;
    }

    if(num_blocks < (10+128) && inode->indirect2 != 0)
    {
        //remove inode->indirect2
        make_free_datablock(inode->indirect2);
        inode->indirect2 = 0;
        put_inode_block(ib, inode_num);
        return 1;
    }

    if(num_blocks >= (10+128) && num_blocks < (10+128+(128*128)))
    {
        if(((num_blocks - (10+128)) % 128) == 0)
        {
            //remove second level indirection block
            if(!read_block(file, idb, inode->indirect2))
            {
                DEBUG2 && printf("Error reading indirection block\n");
                return -1;
            }
            if( idb->pointer[(num_blocks - (10+128)) / 128] != 0)
            {
                make_free_datablock(idb->pointer[(num_blocks - (10+128)) / 128]);
                idb->pointer[(num_blocks - (10+128)) / 128] = 0;
                return 1;
            }
            //block to remove
            //ib1->pointer[(block_num - (10+128)) / 128]

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

}
예제 #7
0
int erase_inode(int inode_num)
{
    struct inode_block *ib = NULL;
    struct inode *inode = NULL;
    struct directory *dir = NULL;
    struct datablock *datablock = NULL;
    struct indirection_block *idb = malloc(sizeof(struct indirection_block));
    struct indirection_block *idb2 = malloc(sizeof(struct indirection_block));
    struct superblock *sb = malloc(sizeof(struct superblock));
    int cur_db_num, i;

    if((get_inode(&ib, &inode, inode_num)) < 0)
    {
        DEBUG2 && printf("error get_inode\n");
        return -1;
    }

    while(inode->num_blocks > 0)
    {
        cur_db_num = get_data_block(&datablock, inode, inode->num_blocks-1);
        make_free_datablock(cur_db_num);
        inode->num_blocks--;
    }
    if(inode->indirect1 != 0)
    {
        make_free_datablock(inode->indirect1);
        inode->indirect1 = 0;
    }
    if(inode->indirect2 !=0)
    {
        if(!read_block(file, idb2, inode->indirect2))
        {
            return ERR_INTERNAL;
        }
        for(i=0; i<128; i++)
        {
            if(idb2->pointer[i] != 0)
            {
                make_free_datablock(idb2->pointer[i]);
            }
        }
        make_free_datablock(inode->indirect2);
        inode->indirect2 = 0;
    }
    for(i=0; i<10; i++)
    {
        inode->file_blocks[i] = 0;
    }
    inode->is_dir = 0;
    inode->is_free = 1;

    if(!read_block(file, sb, 1))
    {
        return ERR_INTERNAL;
    }

    inode->next_free_inode = sb->free_inode_list;
    sb->free_inode_list = inode_num;

    if(!write_block(file, sb, 1))
    {
        return ERR_INTERNAL;
    }
    put_inode_block(ib, inode_num);

}