| 206 | } |
| 207 | |
| 208 | CoTask<void> randomWrite(MetaOperator &meta, |
| 209 | storage::client::StorageClient &storage, |
| 210 | const Inode &inode, |
| 211 | uint64_t offset, |
| 212 | uint64_t length) { |
| 213 | auto stripe = std::min((uint32_t)folly::divCeil(offset + length, (uint64_t)inode.asFile().layout.chunkSize), |
| 214 | inode.asFile().layout.stripeSize); |
| 215 | if (inode.asFile().dynStripe && inode.asFile().dynStripe < stripe) { |
| 216 | auto result = co_await meta.setAttr(SetAttrReq::extendStripe(flat::UserInfo{}, inode.id, stripe)); |
| 217 | CO_ASSERT_OK(result); |
| 218 | } |
| 219 | |
| 220 | uint64_t chunkSize = inode.asFile().layout.chunkSize; |
| 221 | std::vector<uint8_t> writeData(chunkSize, 0x00); |
| 222 | std::vector<folly::SemiFuture<folly::Unit>> tasks; |
| 223 | while (length) { |
| 224 | auto offsetInChunk = offset % chunkSize; |
| 225 | auto lengthInChunk = std::min(length, chunkSize - offsetInChunk); |
| 226 | auto chunkId = inode.asFile().getChunkId(inode.id, offset); |
| 227 | auto routingInfo = storage.getMgmtdClient().getRoutingInfo()->raw(); |
| 228 | XLOGF_IF(FATAL, !routingInfo, "No routingInfo"); |
| 229 | auto chainId = inode.asFile().getChainId(inode, offset, *routingInfo); |
| 230 | XLOGF_IF(FATAL, !chainId, "resolve chainId failed: {}", chainId); |
| 231 | |
| 232 | auto task = [=, &storage, &writeData]() -> CoTask<void> { |
| 233 | auto writeIO = storage.createWriteIO(storage::ChainId(*chainId), |
| 234 | storage::ChunkId(chunkId->pack()), |
| 235 | offsetInChunk, |
| 236 | lengthInChunk, |
| 237 | chunkSize, |
| 238 | writeData.data(), |
| 239 | nullptr); |
| 240 | XLOGF(DBG, "write {} offset {}, offsetInChunk {} length {}", chunkId, offset, offsetInChunk, lengthInChunk); |
| 241 | auto result = co_await storage.write(writeIO, flat::UserInfo()); |
| 242 | CO_ASSERT_FALSE(result.hasError()) << result.error().describe(); |
| 243 | CO_ASSERT_FALSE(writeIO.result.lengthInfo.hasError()) << writeIO.result.lengthInfo.error().describe(); |
| 244 | CO_ASSERT_EQ(*writeIO.result.lengthInfo, lengthInChunk); |
| 245 | }; |
| 246 | |
| 247 | tasks.push_back(folly::coro::co_invoke(task).scheduleOn(co_await folly::coro::co_current_executor).start()); |
| 248 | |
| 249 | offset += lengthInChunk; |
| 250 | length -= lengthInChunk; |
| 251 | } |
| 252 | |
| 253 | co_await folly::collectAll(tasks.begin(), tasks.end()); |
| 254 | } |
| 255 | |
| 256 | CoTask<void> truncate(MetaOperator &meta, |
| 257 | storage::client::StorageClient &storage, |
no test coverage detected