int COPY_VALID_PAGES(int32_t old_pbn, int32_t new_pbn) { int i; int copy_page_nb = 0; unsigned int old_flash_nb = CALC_FLASH(old_pbn); unsigned int old_block_nb = CALC_BLOCK(old_pbn); unsigned int new_flash_nb = CALC_FLASH(new_pbn); unsigned int new_block_nb = CALC_BLOCK(new_pbn);; block_state_entry* old_b_s_entry = GET_BLOCK_STATE_ENTRY(old_pbn); char* valid_array = old_b_s_entry->valid_array; for(i=0;i<PAGE_NB;i++){ if(valid_array[i] == 'V'){ SSD_PAGE_READ(old_flash_nb, old_block_nb, i, -1, GC_READ, -1); SSD_PAGE_WRITE(new_flash_nb, new_block_nb, i, -1, GC_WRITE, -1); UPDATE_BLOCK_STATE_ENTRY(new_pbn, i, VALID); UPDATE_BLOCK_STATE_ENTRY(old_pbn, i, INVALID); copy_page_nb++; } } return copy_page_nb; }
int _FTL_READ(int32_t sector_nb, unsigned int length) { #ifdef FTL_DEBUG printf("[%s] Start\n",__FUNCTION__); #endif if(sector_nb + length > SECTOR_NB){ printf("Error[FTL_READ] Exceed Sector number\n"); return FAIL; } unsigned int remain = length; unsigned int lba = sector_nb; unsigned int left_skip = sector_nb % SECTORS_PER_PAGE; unsigned int right_skip; unsigned int read_sects; unsigned int phy_flash_nb; unsigned int phy_block_nb; unsigned int phy_page_nb; unsigned int ret = SUCCESS; unsigned int ret_seq, ret_ran_hot, ret_ran_cold, ret_data; int read_page_offset = 0; int io_page_nb; #ifdef FIRM_IO_BUFFER INCREASE_RB_FTL_POINTER(length); #endif while(remain > 0){ if(remain > SECTORS_PER_PAGE - left_skip){ right_skip = 0; } else{ right_skip = SECTORS_PER_PAGE - left_skip - remain; } read_sects = SECTORS_PER_PAGE - left_skip - right_skip; ret_seq = FIND_PAGE_IN_SEQ_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); if(ret_seq != SUCCESS){ ret_ran_hot = FIND_PAGE_IN_RAN_HOT_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS){ ret_ran_cold = FIND_PAGE_IN_RAN_COLD_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS){ ret_data = FIND_PAGE_IN_DATA_BLOCK(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS && ret_data != SUCCESS){ #ifdef FTL_DEBUG printf("Error[FTL_READ] No Mapping info\n"); #endif #ifdef FIRM_IO_BUFFER INCREASE_RB_LIMIT_POINTER(); #endif return FAIL; } lba += read_sects; remain -= read_sects; left_skip = 0; } io_alloc_overhead = ALLOC_IO_REQUEST(sector_nb, length, READ, &io_page_nb); remain = length; lba = sector_nb; left_skip = sector_nb % SECTORS_PER_PAGE; while(remain > 0){ if(remain > SECTORS_PER_PAGE - left_skip){ right_skip = 0; } else{ right_skip = SECTORS_PER_PAGE - left_skip - remain; } read_sects = SECTORS_PER_PAGE - left_skip - right_skip; ret_seq = FIND_PAGE_IN_SEQ_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); if(ret_seq != SUCCESS){ ret_ran_hot = FIND_PAGE_IN_RAN_HOT_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS){ ret_ran_cold = FIND_PAGE_IN_RAN_COLD_LOG(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS){ ret_data = FIND_PAGE_IN_DATA_BLOCK(lba, &phy_flash_nb, &phy_block_nb, &phy_page_nb); } if(ret_seq != SUCCESS && ret_ran_hot != SUCCESS && ret_ran_cold != SUCCESS && ret_data != SUCCESS){ #ifdef FTL_DEBUG printf("Error[FTL_READ] No Mapping info\n"); #endif } else{ ret = SSD_PAGE_READ(phy_flash_nb, phy_block_nb, phy_page_nb, read_page_offset, READ, io_page_nb); } if(ret == SUCCESS){ #ifdef FTL_DEBUG printf("[FTL_READ] Complete [%d, %d, %d] from ",phy_flash_nb, phy_block_nb, phy_page_nb); if(ret_seq == SUCCESS){ printf("SEQ Block\n"); } else if(ret_ran_hot == SUCCESS){ printf("RAN HOT Block\n"); } else if(ret_ran_cold == SUCCESS){ printf("RAN COLD Block\n"); } else if(ret_data == SUCCESS){ printf("DATA Block\n"); } else{ printf("No Map\n"); } #endif } else if(ret == FAIL){ printf("Error[FTL_READ] %d page read fail \n", phy_page_nb); } read_page_offset++; lba += read_sects; remain -= read_sects; left_skip = 0; } INCREASE_IO_REQUEST_SEQ_NB(); #ifdef FIRM_IO_BUFFER INCREASE_RB_LIMIT_POINTER(); #endif #ifdef MONITOR_ON char szTemp[1024]; sprintf(szTemp, "READ PAGE %d ", length); WRITE_LOG(szTemp); #endif #ifdef FTL_DEBUG printf("[%s] End\n",__FUNCTION__); #endif return ret; }
int _FTL_READ(int32_t sector_nb, unsigned int length) { #ifdef FTL_DEBUG printf("[%s] Start: sector_nb %d length %u\n",__FUNCTION__, sector_nb, length); #endif if(sector_nb + length > SECTOR_NB){ printf("Error[FTL_READ] Exceed Sector number\n"); return FAIL; } int32_t lpn; int32_t *ppn; int32_t lba = sector_nb; unsigned int remain = length; unsigned int left_skip = sector_nb % SECTORS_PER_PAGE; unsigned int right_skip; unsigned int read_sects; unsigned int i, real_read_length = 0; unsigned int ret = FAIL; int read_page_nb = 0; int io_page_nb; while(remain > 0){ if(remain > SECTORS_PER_PAGE - left_skip){ right_skip = 0; } else{ right_skip = SECTORS_PER_PAGE - left_skip - remain; } read_sects = SECTORS_PER_PAGE - left_skip - right_skip; lpn = lba / (int32_t)SECTORS_PER_PAGE; ppn = GET_MAPPING_INFO(lpn); if(ppn[0] == -1){ return FAIL; } real_read_length += SECTORS_PER_PAGE; if(ppn[1] != -1){ real_read_length += SECTORS_PER_PAGE; } lba += read_sects; remain -= read_sects; left_skip = 0; } io_alloc_overhead = ALLOC_IO_REQUEST(sector_nb, real_read_length, READ, &io_page_nb); remain = length; lba = sector_nb; left_skip = sector_nb % SECTORS_PER_PAGE; while(remain > 0){ if(remain > SECTORS_PER_PAGE - left_skip){ right_skip = 0; } else{ right_skip = SECTORS_PER_PAGE - left_skip - remain; } read_sects = SECTORS_PER_PAGE - left_skip - right_skip; lpn = lba / (int32_t)SECTORS_PER_PAGE; ppn = GET_MAPPING_INFO(lpn); for(i=0; i<2; i++){ if(ppn[i] == -1){ #ifdef FTL_DEBUG printf("Error[%s] No Mapping info\n",__FUNCTION__); #endif /* its legal for 2nd index to be empty*/ if(i==1) break; } //LOG("lpn %d ppn %d", lpn, ppn); ret = SSD_PAGE_READ(CALC_FLASH(ppn[i]), CALC_BLOCK(ppn[i]), CALC_PAGE(ppn[i]), read_page_nb, READ, io_page_nb); if(ret == FAIL){ printf("Error[%s] %u page read fail \n", __FUNCTION__, ppn[i]); } read_page_nb++; } lba += read_sects; remain -= read_sects; left_skip = 0; } INCREASE_IO_REQUEST_SEQ_NB(); #ifdef MONITOR_ON char szTemp[1024]; sprintf(szTemp, "READ PAGE %d ", length); WRITE_LOG(szTemp); #endif #ifdef FTL_DEBUG printf("[%s] Complete\n",__FUNCTION__); #endif return ret; }
int _FTL_OBJ_READ(object_id_t object_id, unsigned int offset, unsigned int length) { stored_object *object; page_node *current_page; int io_page_nb; int curr_io_page_nb; unsigned int ret = FAIL; object = lookup_object(object_id); // file not found if (object == NULL) return FAIL; // object not big enough if (object->size < (offset + length)) return FAIL; if(!(current_page = page_by_offset(object, offset))) { printf("Error[%s] %u lookup page by offset failed \n", __FUNCTION__, current_page->page_id); return FAIL; } // just calculate the overhead of allocating the request. io_page_nb will be the total number of pages we're gonna read io_alloc_overhead = ALLOC_IO_REQUEST(current_page->page_id * SECTORS_PER_PAGE, length, READ, &io_page_nb); for (curr_io_page_nb = 0; curr_io_page_nb < io_page_nb; curr_io_page_nb++) { // simulate the page read ret = SSD_PAGE_READ(CALC_FLASH(current_page->page_id), CALC_BLOCK(current_page->page_id), CALC_PAGE(current_page->page_id), curr_io_page_nb, READ, io_page_nb); // send a physical read action being done to the statistics gathering if (ret == SUCCESS) { FTL_STATISTICS_GATHERING(current_page->page_id, PHYSICAL_READ); } #ifdef FTL_DEBUG if (ret == FAIL) { printf("Error[%s] %u page read fail \n", __FUNCTION__, current_page->page_id); } #endif // get the next page current_page = current_page->next; } INCREASE_IO_REQUEST_SEQ_NB(); #ifdef MONITOR_ON char szTemp[1024]; sprintf(szTemp, "READ PAGE %d ", length); WRITE_LOG(szTemp); #endif #ifdef FTL_DEBUG printf("[%s] Complete\n",__FUNCTION__); #endif return ret; }