| 1049 | } |
| 1050 | |
| 1051 | ssize_t Ext2Volume::Read(Ext2Node* node, size_t offset, size_t size, uint8_t *buffer){ |
| 1052 | if(offset >= node->size) return 0; |
| 1053 | if(offset + size > node->size) size = node->size - offset; |
| 1054 | |
| 1055 | uint32_t blockIndex = LocationToBlock(offset); |
| 1056 | uint32_t blockLimit = LocationToBlock(offset + size); |
| 1057 | uint8_t blockBuffer[blocksize]; |
| 1058 | |
| 1059 | if(debugLevelExt2 >= DebugLevelVerbose){ |
| 1060 | Log::Info("[Ext2] Reading: Block index: %d, Block limit: %d, Offset: %d, Size: %d, Node size: %d", blockIndex, blockLimit, offset, size, node->size); |
| 1061 | } |
| 1062 | |
| 1063 | #ifdef EXT2_ENABLE_TIMER |
| 1064 | timeval_t blktv1 = Timer::GetSystemUptimeStruct(); |
| 1065 | #endif |
| 1066 | |
| 1067 | ssize_t ret = size; |
| 1068 | Vector<uint32_t> blocks = GetInodeBlocks(blockIndex, blockLimit - blockIndex + 1, node->e2inode); |
| 1069 | |
| 1070 | #ifdef EXT2_ENABLE_TIMER |
| 1071 | timeval_t blktv2 = Timer::GetSystemUptimeStruct(); |
| 1072 | timeval_t readtv1 = Timer::GetSystemUptimeStruct(); |
| 1073 | #endif |
| 1074 | |
| 1075 | for(uint32_t block : blocks){ |
| 1076 | if(size <= 0) break; |
| 1077 | |
| 1078 | if(offset && offset % blocksize){ |
| 1079 | if(int e = ReadBlockCached(block, blockBuffer); e){ |
| 1080 | if(int e = ReadBlockCached(block, blockBuffer); e){ // Try again |
| 1081 | Log::Info("[Ext2] Error %i reading block %u", e, block); |
| 1082 | error = DiskReadError; |
| 1083 | break; |
| 1084 | } |
| 1085 | } |
| 1086 | |
| 1087 | size_t readSize = blocksize - (offset % blocksize); |
| 1088 | if(readSize > size){ |
| 1089 | readSize = size; |
| 1090 | } |
| 1091 | |
| 1092 | size_t readOffset = (offset % blocksize); |
| 1093 | |
| 1094 | if(readSize > size) readSize = size; |
| 1095 | |
| 1096 | memcpy(buffer, blockBuffer + readOffset, readSize); |
| 1097 | |
| 1098 | size -= readSize; |
| 1099 | buffer += readSize; |
| 1100 | offset += readSize; |
| 1101 | } else if(size >= blocksize){ |
| 1102 | if(int e = ReadBlockCached(block, buffer); e){ |
| 1103 | if(int e = ReadBlockCached(block, buffer); e){ // Try again |
| 1104 | Log::Info("[Ext2] Error %i reading block %u", e, block); |
| 1105 | error = DiskReadError; |
| 1106 | break; |
| 1107 | } |
| 1108 | } |
no test coverage detected