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]; }
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; }