123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #include "update_engine/payload_consumer/extent_reader.h"
- #include <algorithm>
- #include <sys/types.h>
- #include <unistd.h>
- #include "update_engine/common/utils.h"
- #include "update_engine/payload_consumer/payload_constants.h"
- using google::protobuf::RepeatedPtrField;
- namespace chromeos_update_engine {
- bool DirectExtentReader::Init(FileDescriptorPtr fd,
- const RepeatedPtrField<Extent>& extents,
- uint32_t block_size) {
- fd_ = fd;
- extents_ = extents;
- block_size_ = block_size;
- cur_extent_ = extents_.begin();
- extents_upper_bounds_.reserve(extents_.size() + 1);
-
-
- extents_upper_bounds_.emplace_back(0);
- for (const auto& extent : extents_) {
- total_size_ += extent.num_blocks() * block_size_;
- extents_upper_bounds_.emplace_back(total_size_);
- }
- return true;
- }
- bool DirectExtentReader::Seek(uint64_t offset) {
- TEST_AND_RETURN_FALSE(offset <= total_size_);
- if (offset_ == offset) {
- return true;
- }
-
-
- auto extent_idx =
- std::upper_bound(
- extents_upper_bounds_.begin(), extents_upper_bounds_.end(), offset) -
- extents_upper_bounds_.begin() - 1;
- cur_extent_ = std::next(extents_.begin(), extent_idx);
- offset_ = offset;
- cur_extent_bytes_read_ = offset_ - extents_upper_bounds_[extent_idx];
- return true;
- }
- bool DirectExtentReader::Read(void* buffer, size_t count) {
- auto bytes = reinterpret_cast<uint8_t*>(buffer);
- uint64_t bytes_read = 0;
- while (bytes_read < count) {
- if (cur_extent_ == extents_.end()) {
- TEST_AND_RETURN_FALSE(bytes_read == count);
- }
- uint64_t cur_extent_bytes_left =
- cur_extent_->num_blocks() * block_size_ - cur_extent_bytes_read_;
- uint64_t bytes_to_read =
- std::min(count - bytes_read, cur_extent_bytes_left);
- ssize_t out_bytes_read;
- TEST_AND_RETURN_FALSE(utils::PReadAll(
- fd_,
- bytes + bytes_read,
- bytes_to_read,
- cur_extent_->start_block() * block_size_ + cur_extent_bytes_read_,
- &out_bytes_read));
- TEST_AND_RETURN_FALSE(out_bytes_read ==
- static_cast<ssize_t>(bytes_to_read));
- bytes_read += bytes_to_read;
- cur_extent_bytes_read_ += bytes_to_read;
- offset_ += bytes_to_read;
- if (cur_extent_bytes_read_ == cur_extent_->num_blocks() * block_size_) {
-
- cur_extent_++;
- cur_extent_bytes_read_ = 0;
- }
- }
- return true;
- }
- }
|