/* if offset is bigger than file_length, allocate new disk and update inode */ bool inode_update_file_length(struct inode_disk *inode_disk, off_t start_pos, off_t end_pos) { off_t size = end_pos - start_pos; off_t offset = start_pos; void *zeros = malloc(SECTOR_SIZE); int chunck_size; /* make zeros */ if(zeros == NULL) return false; memset(zeros, 0, SECTOR_SIZE); while( size > 0 ) { /* offset in the disk block */ int sector_ofs = offset % SECTOR_SIZE; /* caculate chunck size */ if( size >= SECTOR_SIZE) chunck_size = SECTOR_SIZE - sector_ofs; else { if(sector_ofs + size > SECTOR_SIZE) chunck_size = SECTOR_SIZE - sector_ofs; else chunck_size = size; } /* if sector_ofs is bigger than zero, already allocate disk block */ if(sector_ofs > 0 ) { } /* allocate new disk block */ else { struct sector_location sec_loc; block_sector_t sector_idx; /* allocate new disk block */ if(free_map_allocate(1, §or_idx) == true) { /* update disk block number */ locate_byte(offset, &sec_loc); register_sector(inode_disk, sector_idx, sec_loc); } else { free(zeros); return false; } /* init new disk block to 0 */ bc_write(sector_idx, zeros, 0, SECTOR_SIZE, 0); } /* advance */ size -= chunck_size; offset += chunck_size; } free(zeros); return true; }
int write(int fd, char *buf, int size) { return (bc_write(fd, buf, size)); }
/* update new disk block number to inode_disk */ static bool register_sector(struct inode_disk *inode_disk, block_sector_t new_sector, struct sector_location sec_loc) { switch(sec_loc.directness) { case NORMAL_DIRECT: /* update new disk block */ inode_disk->direct_map_table[sec_loc.index1] = new_sector; break; case INDIRECT: /* if use indirect first, allocate disk for indirect index block */ if(sec_loc.index1 == 0) { block_sector_t sector_idx; if(free_map_allocate(1, §or_idx)) inode_disk->indirect_block_sec = sector_idx; } /* allocate new_block and write new_sector to new_block */ block_sector_t *new_block = (block_sector_t *)malloc(SECTOR_SIZE); if(new_block == NULL) return false; new_block[sec_loc.index1] = new_sector; /* write new_block to index block */ bc_write(inode_disk->indirect_block_sec, (void *)new_block,map_table_offset(sec_loc.index1) ,4 ,map_table_offset(sec_loc.index1)); free(new_block); break; case DOUBLE_INDIRECT: /* if index1 and index2 is 0, allocate disk for index block 1 */ if(sec_loc.index1 == 0 && sec_loc.index2 ==0) { block_sector_t sector_idx; if(free_map_allocate(1, §or_idx)) inode_disk->double_indirect_block_sec = sector_idx; } /* if index2 is 0, allocate disk for index block 2 and update index block 1 */ if(sec_loc.index2 == 0 ) { /* allocate disk for index block 2 */ block_sector_t sector_idx; if(free_map_allocate(1, §or_idx) == false) return false; /* update index block 1*/ block_sector_t *new_block = (block_sector_t *)malloc(SECTOR_SIZE); if(new_block == NULL) return false; new_block[sec_loc.index1] = sector_idx; bc_write(inode_disk->double_indirect_block_sec, (void *)new_block, sec_loc.index1 * 4, 4, sec_loc.index1 * 4); free(new_block); } /* update index block 2 */ /* Value for read index_block 1 */ block_sector_t *index_block1 = (block_sector_t *)malloc(SECTOR_SIZE); if(index_block1 == NULL) return false; /* Value for update index_block 2 */ block_sector_t *new_block2 = (block_sector_t *)malloc(SECTOR_SIZE); if(new_block2 == NULL) return false; /* read index block 1 */ bc_read(inode_disk->double_indirect_block_sec, (void *)index_block1, 0, SECTOR_SIZE, 0); block_sector_t block_sector = index_block1[sec_loc.index1]; /* update index block 2*/ new_block2[sec_loc.index2] = new_sector; bc_write(block_sector, (void *)new_block2, sec_loc.index2 * 4, 4, sec_loc.index2 * 4); free(new_block2); free(index_block1); break; default: return false; } return true; }