| 1141 | } |
| 1142 | |
| 1143 | ssize_t Ext2Volume::Write(Ext2Node* node, size_t offset, size_t size, uint8_t *buffer){ |
| 1144 | if(readOnly) { |
| 1145 | error = FilesystemAccessError; |
| 1146 | return -EROFS; |
| 1147 | } |
| 1148 | |
| 1149 | uint32_t blockIndex = LocationToBlock(offset); // Index of first block to write |
| 1150 | uint32_t fileBlockCount = node->e2inode.blockCount / (blocksize / 512); // Size of file in blocks |
| 1151 | uint32_t blockLimit = LocationToBlock(offset + size); // Amount of blocks to write |
| 1152 | uint8_t blockBuffer[blocksize]; // block buffer |
| 1153 | bool sync = false; // Need to sync the inode? |
| 1154 | |
| 1155 | if(blockLimit >= fileBlockCount){ |
| 1156 | if(debugLevelExt2 >= DebugLevelVerbose){ |
| 1157 | Log::Info("[Ext2] Allocating blocks for inode %d", node->inode); |
| 1158 | } |
| 1159 | for(unsigned i = fileBlockCount; i <= blockLimit; i++){ |
| 1160 | uint32_t block = AllocateBlock(); |
| 1161 | SetInodeBlock(i, node->e2inode, block); |
| 1162 | } |
| 1163 | node->e2inode.blockCount = (blockLimit + 1) * (blocksize / 512); |
| 1164 | |
| 1165 | WriteSuperblock(); |
| 1166 | sync = true; |
| 1167 | } |
| 1168 | |
| 1169 | if(offset + size > node->size){ |
| 1170 | node->size = offset + size; |
| 1171 | node->e2inode.size = node->size; |
| 1172 | |
| 1173 | sync = true; |
| 1174 | } |
| 1175 | |
| 1176 | if(sync){ |
| 1177 | SyncNode(node); |
| 1178 | } |
| 1179 | |
| 1180 | if(debugLevelExt2 >= DebugLevelVerbose){ |
| 1181 | Log::Info("[Ext2] Writing: Block index: %d, Blockcount: %d, Offset: %d, Size: %d", blockIndex, blockLimit - blockIndex + 1, offset, size); |
| 1182 | } |
| 1183 | |
| 1184 | size_t ret = size; |
| 1185 | |
| 1186 | for(; blockIndex <= blockLimit && size > 0; blockIndex++){ |
| 1187 | uint32_t block = GetInodeBlock(blockIndex, node->e2inode); |
| 1188 | |
| 1189 | if(offset % blocksize){ |
| 1190 | ReadBlockCached(block, blockBuffer); |
| 1191 | |
| 1192 | size_t writeSize = blocksize - (offset % blocksize); |
| 1193 | size_t writeOffset = (offset % blocksize); |
| 1194 | |
| 1195 | if(writeSize > size) writeSize = size; |
| 1196 | |
| 1197 | memcpy(blockBuffer + writeOffset, buffer, writeSize); |
| 1198 | WriteBlockCached(block, blockBuffer); |
| 1199 | |
| 1200 | size -= writeSize; |
nothing calls this directly
no test coverage detected