| 59 | } |
| 60 | |
| 61 | ACTOR static Future<int> read(Reference<AsyncFileEncrypted> self, void* data, int length, int64_t offset) { |
| 62 | state const uint32_t firstBlock = offset / FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE; |
| 63 | state const uint32_t lastBlock = (offset + length - 1) / FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE; |
| 64 | state uint32_t block; |
| 65 | state unsigned char* output = reinterpret_cast<unsigned char*>(data); |
| 66 | state int bytesRead = 0; |
| 67 | ASSERT(self->mode == AsyncFileEncrypted::Mode::READ_ONLY); |
| 68 | for (block = firstBlock; block <= lastBlock; ++block) { |
| 69 | state Standalone<StringRef> plaintext; |
| 70 | |
| 71 | auto cachedBlock = self->readBuffers.get(block); |
| 72 | if (cachedBlock.present()) { |
| 73 | plaintext = cachedBlock.get(); |
| 74 | } else { |
| 75 | wait(store(plaintext, readBlock(self.getPtr(), block))); |
| 76 | self->readBuffers.insert(block, plaintext); |
| 77 | } |
| 78 | auto start = (block == firstBlock) ? plaintext.begin() + (offset % FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE) |
| 79 | : plaintext.begin(); |
| 80 | auto end = (block == lastBlock) |
| 81 | ? plaintext.begin() + ((offset + length) % FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE) |
| 82 | : plaintext.end(); |
| 83 | if ((offset + length) % FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE == 0) { |
| 84 | end = plaintext.end(); |
| 85 | } |
| 86 | |
| 87 | // The block could be short if it includes or is after the end of the file. |
| 88 | end = std::min(end, plaintext.end()); |
| 89 | // If the start position is at or after the end of the block, the read is complete. |
| 90 | if (start == end || start >= plaintext.end()) { |
| 91 | break; |
| 92 | } |
| 93 | |
| 94 | std::copy(start, end, output); |
| 95 | output += (end - start); |
| 96 | bytesRead += (end - start); |
| 97 | } |
| 98 | return bytesRead; |
| 99 | } |
| 100 | |
| 101 | ACTOR static Future<Void> write(Reference<AsyncFileEncrypted> self, void const* data, int length, int64_t offset) { |
| 102 | ASSERT(self->mode == AsyncFileEncrypted::Mode::APPEND_ONLY); |