/** * This function is called whenever a write event occurs. * */ static gboolean block_write_callback(void *hook_data, void *call_data) { LttEvent *e; LttTime event_time; unsigned cpu_id; lttv_block block_write; char *diskname; LttvTracefileContext *tfc = (LttvTracefileContext *)call_data; LttvTracefileState *tfs = (LttvTracefileState *)call_data; DiskPerformanceData *disk_performance = (DiskPerformanceData *)hook_data; GArray *disk_array = disk_performance->disk_array; e = ltt_tracefile_get_event(tfc->tf); event_time = ltt_event_time(e); cpu_id = ltt_event_cpu_id(e); get_event_detail(e, &block_write); diskname = major_minor_to_diskname(&block_write); sum_data(diskname, block_write.size,LTTV_WRITE_OPERATION, disk_array); return FALSE; }
static int FTL_Open(int* pagesAvailable, int* bytesPerPage) { int refreshPage; int ret; int i; uint16_t* dataVbn = pstFTLCxt->dataVbn; uint16_t* field_19C = pstFTLCxt->field_19C; void* field_3B0 = pstFTLCxt->field_3B0; uint16_t* field_1A0 = pstFTLCxt->field_1A0; void* thing; if((thing = VFL_get_maxThing()) == NULL) goto FTL_Open_Error; memcpy(pstFTLCxt->thing, thing, sizeof(pstFTLCxt->thing)); uint8_t* pageBuffer = malloc(Data->bytesPerPage); uint8_t* spareBuffer = malloc(Data->bytesPerSpare); if(!pageBuffer || !spareBuffer) { bufferPrintf("ftl: FTL_Open ran out of memory!\r\n"); return ERROR_ARG; } uint32_t ftlCxtBlock = 0xffff; uint32_t minLpn = 0xffffffff; for(i = 0; i < sizeof(pstFTLCxt->thing)/sizeof(uint16_t); i++) { ret = VFL_Read(Data->pagesPerSubBlk * pstFTLCxt->thing[i], pageBuffer, spareBuffer, TRUE, &refreshPage); if(ret == ERROR_ARG) { free(pageBuffer); free(spareBuffer); goto FTL_Open_Error; } SpareData* spareData = (SpareData*) spareBuffer; if((spareData->field_9 - 0x43) > 0xC) continue; if(ret != 0) continue; if(ftlCxtBlock != 0xffff && spareData->logicalPageNumber >= minLpn) continue; minLpn = spareData->logicalPageNumber; ftlCxtBlock = pstFTLCxt->thing[i]; } if(ftlCxtBlock == 0xffff) { bufferPrintf("ftl: Cannot find context!\r\n"); goto FTL_Open_Error_Release; } bufferPrintf("ftl: Successfully found FTL context block: %d\r\n", ftlCxtBlock); int ftlCxtFound = FALSE; for(i = Data->pagesPerSubBlk - 1; i > 0; i--) { ret = VFL_Read(Data->pagesPerSubBlk * ftlCxtBlock + i, pageBuffer, spareBuffer, TRUE, &refreshPage); if(ret == 1) { continue; } else if(ret == 0 && ((SpareData*)spareBuffer)->field_9 == 0x43) { memcpy(FTLCxtBuffer, pageBuffer, sizeof(FTLCxt)); ftlCxtFound = TRUE; break; } else { ftlCxtFound = FALSE; break; } } // Restore now possibly overwritten (by data from NAND) pointers from backed up copies pstFTLCxt->dataVbn = dataVbn; pstFTLCxt->field_19C = field_19C; pstFTLCxt->field_3B0 = field_3B0; pstFTLCxt->field_1A0 = field_1A0; for(i = 0; i < 18; i++) { pstFTLCxt->pLog[i].field_8 = pstFTLCxt->field_1A0 + (i * Data->pagesPerSubBlk); } if(!ftlCxtFound) goto FTL_Open_Error_Release; bufferPrintf("ftl: Successfully read FTL context block.\r\n"); int pagesToRead; pagesToRead = (Data->userSubBlksTotal * 2) / Data->bytesPerPage; if(((Data->userSubBlksTotal * 2) % Data->bytesPerPage) != 0) pagesToRead++; for(i = 0; i < pagesToRead; i++) { if(VFL_Read(pstFTLCxt->pages_for_dataVbn[i], pageBuffer, spareBuffer, TRUE, &refreshPage) != 0) goto FTL_Open_Error_Release; int toRead = Data->bytesPerPage; if(toRead > ((Data->userSubBlksTotal * 2) - (i * Data->bytesPerPage))) { toRead = (Data->userSubBlksTotal * 2) - (i * Data->bytesPerPage); } memcpy(((uint8_t*)pstFTLCxt->dataVbn) + (i * Data->bytesPerPage), pageBuffer, toRead); } pagesToRead = (Data->pagesPerSubBlk * 34) / Data->bytesPerPage; if(((Data->pagesPerSubBlk * 34) % Data->bytesPerPage) != 0) pagesToRead++; for(i = 0; i < pagesToRead; i++) { if(VFL_Read(pstFTLCxt->pages_for_1A0[i], pageBuffer, spareBuffer, TRUE, &refreshPage) != 0) goto FTL_Open_Error_Release; int toRead = Data->bytesPerPage; if(toRead > ((Data->pagesPerSubBlk * 34) - (i * Data->bytesPerPage))) { toRead = (Data->pagesPerSubBlk * 34) - (i * Data->bytesPerPage); } memcpy(((uint8_t*)pstFTLCxt->field_1A0) + (i * Data->bytesPerPage), pageBuffer, toRead); } pagesToRead = ((Data->userSubBlksTotal + 23) * sizeof(uint16_t)) / Data->bytesPerPage; if((((Data->userSubBlksTotal + 23) * sizeof(uint16_t)) % Data->bytesPerPage) != 0) pagesToRead++; for(i = 0; i < pagesToRead; i++) { if(VFL_Read(pstFTLCxt->pages_for_19C[i], pageBuffer, spareBuffer, TRUE, &refreshPage) != 0) goto FTL_Open_Error_Release; int toRead = Data->bytesPerPage; if(toRead > (((Data->pagesPerSubBlk + 23) * sizeof(uint16_t)) - (i * Data->bytesPerPage))) { toRead = ((Data->pagesPerSubBlk + 23) * sizeof(uint16_t)) - (i * Data->bytesPerPage); } memcpy(((uint8_t*)pstFTLCxt->field_19C) + (i * Data->bytesPerPage), pageBuffer, toRead); } int success = FALSE; bufferPrintf("ftl: Detected version %x %x\r\n", FTLCxtBuffer->versionLower, FTLCxtBuffer->versionUpper); if(FTLCxtBuffer->versionLower == 0x46560001 && FTLCxtBuffer->versionUpper == 0xB9A9FFFE) { pagesToRead = ((Data->userSubBlksTotal + 23) * sizeof(uint16_t)) / Data->bytesPerPage; if((((Data->userSubBlksTotal + 23) * sizeof(uint16_t)) % Data->bytesPerPage) != 0) pagesToRead++; success = TRUE; for(i = 0; i < pagesToRead; i++) { if(VFL_Read(pstFTLCxt->pages_for_3B0[i], pageBuffer, spareBuffer, TRUE, &refreshPage) != 0) { success = FALSE; break; } int toRead = Data->bytesPerPage; if(toRead > (((Data->pagesPerSubBlk + 23) * sizeof(uint16_t)) - (i * Data->bytesPerPage))) { toRead = ((Data->pagesPerSubBlk + 23) * sizeof(uint16_t)) - (i * Data->bytesPerPage); } memcpy(((uint8_t*)pstFTLCxt->field_3B0) + (i * Data->bytesPerPage), pageBuffer, toRead); } if((pstFTLCxt->field_3D4 + 1) == 0) { int x = pstFTLCxt->field_3D0 / Data->pagesPerSubBlk; if(x == 0 || x <= Data->userSubBlksTotal) { if(VFL_Read(pstFTLCxt->field_3D0, pageBuffer, spareBuffer, TRUE, &refreshPage) != 0) goto FTL_Open_Error_Release; sum_data(pageBuffer); } } } else { bufferPrintf("ftl: updating the FTL from seemingly compatible version\r\n"); for(i = 0; i < (Data->userSubBlksTotal + 23); i++) { pstFTLCxt->field_3B0[i] = 0x1388; } for(i = 0; i < 5; i++) { pstFTLCxt->elements2[i].field_0 = -1; pstFTLCxt->elements2[i].field_2 = -1; } pstFTLCxt->field_3C8 = 0; pstFTLCxt->field_31C = 0; FTLCxtBuffer->versionLower = 0x46560000; FTLCxtBuffer->versionUpper = 0xB9A9FFFF; success = TRUE; } if(success) { bufferPrintf("ftl: FTL successfully opened!\r\n"); free(pageBuffer); free(spareBuffer); *pagesAvailable = Data->userPagesTotal; *bytesPerPage = Data->bytesPerPage; return 0; } FTL_Open_Error_Release: free(pageBuffer); free(spareBuffer); FTL_Open_Error: bufferPrintf("ftl: FTL_Open cannot load FTLCxt!\r\n"); if(FTL_Restore() != FALSE) { *pagesAvailable = Data->userPagesTotal; *bytesPerPage = Data->bytesPerPage; return 0; } else { return ERROR_ARG; } }