Loading Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ cc_defaults { "-Wall", "-Werror", ], cpp_std: "c++17", } cc_library { Loading otautil/rangeset.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -148,8 +148,8 @@ std::string RangeSet::ToString() const { return ""; } std::string result = std::to_string(ranges_.size() * 2); for (const auto& r : ranges_) { result += android::base::StringPrintf(",%zu,%zu", r.first, r.second); for (const auto& [begin, end] : ranges_) { result += android::base::StringPrintf(",%zu,%zu", begin, end); } return result; Loading @@ -159,11 +159,11 @@ std::string RangeSet::ToString() const { size_t RangeSet::GetBlockNumber(size_t idx) const { CHECK_LT(idx, blocks_) << "Out of bound index " << idx << " (total blocks: " << blocks_ << ")"; for (const auto& range : ranges_) { if (idx < range.second - range.first) { return range.first + idx; for (const auto& [begin, end] : ranges_) { if (idx < end - begin) { return begin + idx; } idx -= (range.second - range.first); idx -= (end - begin); } CHECK(false) << "Failed to find block number for index " << idx; Loading @@ -173,14 +173,10 @@ size_t RangeSet::GetBlockNumber(size_t idx) const { // RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" // and "5,7" are not overlapped. bool RangeSet::Overlaps(const RangeSet& other) const { for (const auto& range : ranges_) { size_t start = range.first; size_t end = range.second; for (const auto& other_range : other.ranges_) { size_t other_start = other_range.first; size_t other_end = other_range.second; // [start, end) vs [other_start, other_end) if (!(other_start >= end || start >= other_end)) { for (const auto& [begin, end] : ranges_) { for (const auto& [other_begin, other_end] : other.ranges_) { // [begin, end) vs [other_begin, other_end) if (!(other_begin >= end || begin >= other_end)) { return true; } } Loading Loading @@ -248,20 +244,20 @@ bool SortedRangeSet::Overlaps(size_t start, size_t len) const { size_t SortedRangeSet::GetOffsetInRangeSet(size_t old_offset) const { size_t old_block_start = old_offset / kBlockSize; size_t new_block_start = 0; for (const auto& range : ranges_) { for (const auto& [start, end] : ranges_) { // Find the index of old_block_start. if (old_block_start >= range.second) { new_block_start += (range.second - range.first); } else if (old_block_start >= range.first) { new_block_start += (old_block_start - range.first); if (old_block_start >= end) { new_block_start += (end - start); } else if (old_block_start >= start) { new_block_start += (old_block_start - start); return (new_block_start * kBlockSize + old_offset % kBlockSize); } else { CHECK(false) << "block_start " << old_block_start << " is missing between two ranges: " << this->ToString(); << " is missing between two ranges: " << ToString(); return 0; } } CHECK(false) << "block_start " << old_block_start << " exceeds the limit of current RangeSet: " << this->ToString(); << " exceeds the limit of current RangeSet: " << ToString(); return 0; } updater/blockimg.cpp +23 −23 Original line number Diff line number Diff line Loading @@ -463,12 +463,12 @@ static void* unzip_new_data(void* cookie) { static int ReadBlocks(const RangeSet& src, std::vector<uint8_t>* buffer, int fd) { size_t p = 0; for (const auto& range : src) { if (!check_lseek(fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { for (const auto& [begin, end] : src) { if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { return -1; } size_t size = (range.second - range.first) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!android::base::ReadFully(fd, buffer->data() + p, size)) { failure_type = errno == EIO ? kEioFailure : kFreadFailure; PLOG(ERROR) << "Failed to read " << size << " bytes of data"; Loading @@ -483,9 +483,9 @@ static int ReadBlocks(const RangeSet& src, std::vector<uint8_t>* buffer, int fd) static int WriteBlocks(const RangeSet& tgt, const std::vector<uint8_t>& buffer, int fd) { size_t written = 0; for (const auto& range : tgt) { off64_t offset = static_cast<off64_t>(range.first) * BLOCKSIZE; size_t size = (range.second - range.first) * BLOCKSIZE; for (const auto& [begin, end] : tgt) { off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!discard_blocks(fd, offset, size)) { return -1; } Loading Loading @@ -1269,9 +1269,9 @@ static int PerformCommandZero(CommandParameters& params) { memset(params.buffer.data(), 0, BLOCKSIZE); if (params.canwrite) { for (const auto& range : tgt) { off64_t offset = static_cast<off64_t>(range.first) * BLOCKSIZE; size_t size = (range.second - range.first) * BLOCKSIZE; for (const auto& [begin, end] : tgt) { off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!discard_blocks(params.fd, offset, size)) { return -1; } Loading @@ -1280,7 +1280,7 @@ static int PerformCommandZero(CommandParameters& params) { return -1; } for (size_t j = range.first; j < range.second; ++j) { for (size_t j = begin; j < end; ++j) { if (!android::base::WriteFully(params.fd, params.buffer.data(), BLOCKSIZE)) { failure_type = errno == EIO ? kEioFailure : kFwriteFailure; PLOG(ERROR) << "Failed to write " << BLOCKSIZE << " bytes of data"; Loading Loading @@ -1444,12 +1444,12 @@ static int PerformCommandErase(CommandParameters& params) { if (params.canwrite) { LOG(INFO) << " erasing " << tgt.blocks() << " blocks"; for (const auto& range : tgt) { for (const auto& [begin, end] : tgt) { uint64_t blocks[2]; // offset in bytes blocks[0] = range.first * static_cast<uint64_t>(BLOCKSIZE); blocks[0] = begin * static_cast<uint64_t>(BLOCKSIZE); // length in bytes blocks[1] = (range.second - range.first) * static_cast<uint64_t>(BLOCKSIZE); blocks[1] = (end - begin) * static_cast<uint64_t>(BLOCKSIZE); if (ioctl(params.fd, BLKDISCARD, &blocks) == -1) { PLOG(ERROR) << "BLKDISCARD ioctl failed"; Loading Loading @@ -1522,17 +1522,17 @@ static int PerformCommandComputeHashTree(CommandParameters& params) { // Iterates through every block in the source_ranges and updates the hash tree structure // accordingly. for (const auto& range : source_ranges) { for (const auto& [begin, end] : source_ranges) { uint8_t buffer[BLOCKSIZE]; if (!check_lseek(params.fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { PLOG(ERROR) << "Failed to seek to block: " << range.first; if (!check_lseek(params.fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { PLOG(ERROR) << "Failed to seek to block: " << begin; return -1; } for (size_t i = range.first; i < range.second; i++) { for (size_t i = begin; i < end; i++) { if (!android::base::ReadFully(params.fd, buffer, BLOCKSIZE)) { failure_type = errno == EIO ? kEioFailure : kFreadFailure; LOG(ERROR) << "Failed to read data in " << range.first << ":" << range.second; LOG(ERROR) << "Failed to read data in " << begin << ":" << end; return -1; } Loading Loading @@ -2046,14 +2046,14 @@ Value* RangeSha1Fn(const char* name, State* state, const std::vector<std::unique SHA1_Init(&ctx); std::vector<uint8_t> buffer(BLOCKSIZE); for (const auto& range : rs) { if (!check_lseek(fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { for (const auto& [begin, end] : rs) { if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { ErrorAbort(state, kLseekFailure, "failed to seek %s: %s", blockdev_filename->data.c_str(), strerror(errno)); return StringValue(""); } for (size_t j = range.first; j < range.second; ++j) { for (size_t j = begin; j < end; ++j) { if (!android::base::ReadFully(fd, buffer.data(), BLOCKSIZE)) { CauseCode cause_code = errno == EIO ? kEioFailure : kFreadFailure; ErrorAbort(state, cause_code, "failed to read %s: %s", blockdev_filename->data.c_str(), Loading Loading @@ -2185,8 +2185,8 @@ Value* BlockImageRecoverFn(const char* name, State* state, } uint8_t buffer[BLOCKSIZE]; for (const auto& range : rs) { for (size_t j = range.first; j < range.second; ++j) { for (const auto& [begin, end] : rs) { for (size_t j = begin; j < end; ++j) { // Stay within the data area, libfec validates and corrects metadata if (status.data_size <= static_cast<uint64_t>(j) * BLOCKSIZE) { continue; Loading Loading
Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ cc_defaults { "-Wall", "-Werror", ], cpp_std: "c++17", } cc_library { Loading
otautil/rangeset.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -148,8 +148,8 @@ std::string RangeSet::ToString() const { return ""; } std::string result = std::to_string(ranges_.size() * 2); for (const auto& r : ranges_) { result += android::base::StringPrintf(",%zu,%zu", r.first, r.second); for (const auto& [begin, end] : ranges_) { result += android::base::StringPrintf(",%zu,%zu", begin, end); } return result; Loading @@ -159,11 +159,11 @@ std::string RangeSet::ToString() const { size_t RangeSet::GetBlockNumber(size_t idx) const { CHECK_LT(idx, blocks_) << "Out of bound index " << idx << " (total blocks: " << blocks_ << ")"; for (const auto& range : ranges_) { if (idx < range.second - range.first) { return range.first + idx; for (const auto& [begin, end] : ranges_) { if (idx < end - begin) { return begin + idx; } idx -= (range.second - range.first); idx -= (end - begin); } CHECK(false) << "Failed to find block number for index " << idx; Loading @@ -173,14 +173,10 @@ size_t RangeSet::GetBlockNumber(size_t idx) const { // RangeSet has half-closed half-open bounds. For example, "3,5" contains blocks 3 and 4. So "3,5" // and "5,7" are not overlapped. bool RangeSet::Overlaps(const RangeSet& other) const { for (const auto& range : ranges_) { size_t start = range.first; size_t end = range.second; for (const auto& other_range : other.ranges_) { size_t other_start = other_range.first; size_t other_end = other_range.second; // [start, end) vs [other_start, other_end) if (!(other_start >= end || start >= other_end)) { for (const auto& [begin, end] : ranges_) { for (const auto& [other_begin, other_end] : other.ranges_) { // [begin, end) vs [other_begin, other_end) if (!(other_begin >= end || begin >= other_end)) { return true; } } Loading Loading @@ -248,20 +244,20 @@ bool SortedRangeSet::Overlaps(size_t start, size_t len) const { size_t SortedRangeSet::GetOffsetInRangeSet(size_t old_offset) const { size_t old_block_start = old_offset / kBlockSize; size_t new_block_start = 0; for (const auto& range : ranges_) { for (const auto& [start, end] : ranges_) { // Find the index of old_block_start. if (old_block_start >= range.second) { new_block_start += (range.second - range.first); } else if (old_block_start >= range.first) { new_block_start += (old_block_start - range.first); if (old_block_start >= end) { new_block_start += (end - start); } else if (old_block_start >= start) { new_block_start += (old_block_start - start); return (new_block_start * kBlockSize + old_offset % kBlockSize); } else { CHECK(false) << "block_start " << old_block_start << " is missing between two ranges: " << this->ToString(); << " is missing between two ranges: " << ToString(); return 0; } } CHECK(false) << "block_start " << old_block_start << " exceeds the limit of current RangeSet: " << this->ToString(); << " exceeds the limit of current RangeSet: " << ToString(); return 0; }
updater/blockimg.cpp +23 −23 Original line number Diff line number Diff line Loading @@ -463,12 +463,12 @@ static void* unzip_new_data(void* cookie) { static int ReadBlocks(const RangeSet& src, std::vector<uint8_t>* buffer, int fd) { size_t p = 0; for (const auto& range : src) { if (!check_lseek(fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { for (const auto& [begin, end] : src) { if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { return -1; } size_t size = (range.second - range.first) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!android::base::ReadFully(fd, buffer->data() + p, size)) { failure_type = errno == EIO ? kEioFailure : kFreadFailure; PLOG(ERROR) << "Failed to read " << size << " bytes of data"; Loading @@ -483,9 +483,9 @@ static int ReadBlocks(const RangeSet& src, std::vector<uint8_t>* buffer, int fd) static int WriteBlocks(const RangeSet& tgt, const std::vector<uint8_t>& buffer, int fd) { size_t written = 0; for (const auto& range : tgt) { off64_t offset = static_cast<off64_t>(range.first) * BLOCKSIZE; size_t size = (range.second - range.first) * BLOCKSIZE; for (const auto& [begin, end] : tgt) { off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!discard_blocks(fd, offset, size)) { return -1; } Loading Loading @@ -1269,9 +1269,9 @@ static int PerformCommandZero(CommandParameters& params) { memset(params.buffer.data(), 0, BLOCKSIZE); if (params.canwrite) { for (const auto& range : tgt) { off64_t offset = static_cast<off64_t>(range.first) * BLOCKSIZE; size_t size = (range.second - range.first) * BLOCKSIZE; for (const auto& [begin, end] : tgt) { off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; size_t size = (end - begin) * BLOCKSIZE; if (!discard_blocks(params.fd, offset, size)) { return -1; } Loading @@ -1280,7 +1280,7 @@ static int PerformCommandZero(CommandParameters& params) { return -1; } for (size_t j = range.first; j < range.second; ++j) { for (size_t j = begin; j < end; ++j) { if (!android::base::WriteFully(params.fd, params.buffer.data(), BLOCKSIZE)) { failure_type = errno == EIO ? kEioFailure : kFwriteFailure; PLOG(ERROR) << "Failed to write " << BLOCKSIZE << " bytes of data"; Loading Loading @@ -1444,12 +1444,12 @@ static int PerformCommandErase(CommandParameters& params) { if (params.canwrite) { LOG(INFO) << " erasing " << tgt.blocks() << " blocks"; for (const auto& range : tgt) { for (const auto& [begin, end] : tgt) { uint64_t blocks[2]; // offset in bytes blocks[0] = range.first * static_cast<uint64_t>(BLOCKSIZE); blocks[0] = begin * static_cast<uint64_t>(BLOCKSIZE); // length in bytes blocks[1] = (range.second - range.first) * static_cast<uint64_t>(BLOCKSIZE); blocks[1] = (end - begin) * static_cast<uint64_t>(BLOCKSIZE); if (ioctl(params.fd, BLKDISCARD, &blocks) == -1) { PLOG(ERROR) << "BLKDISCARD ioctl failed"; Loading Loading @@ -1522,17 +1522,17 @@ static int PerformCommandComputeHashTree(CommandParameters& params) { // Iterates through every block in the source_ranges and updates the hash tree structure // accordingly. for (const auto& range : source_ranges) { for (const auto& [begin, end] : source_ranges) { uint8_t buffer[BLOCKSIZE]; if (!check_lseek(params.fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { PLOG(ERROR) << "Failed to seek to block: " << range.first; if (!check_lseek(params.fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { PLOG(ERROR) << "Failed to seek to block: " << begin; return -1; } for (size_t i = range.first; i < range.second; i++) { for (size_t i = begin; i < end; i++) { if (!android::base::ReadFully(params.fd, buffer, BLOCKSIZE)) { failure_type = errno == EIO ? kEioFailure : kFreadFailure; LOG(ERROR) << "Failed to read data in " << range.first << ":" << range.second; LOG(ERROR) << "Failed to read data in " << begin << ":" << end; return -1; } Loading Loading @@ -2046,14 +2046,14 @@ Value* RangeSha1Fn(const char* name, State* state, const std::vector<std::unique SHA1_Init(&ctx); std::vector<uint8_t> buffer(BLOCKSIZE); for (const auto& range : rs) { if (!check_lseek(fd, static_cast<off64_t>(range.first) * BLOCKSIZE, SEEK_SET)) { for (const auto& [begin, end] : rs) { if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { ErrorAbort(state, kLseekFailure, "failed to seek %s: %s", blockdev_filename->data.c_str(), strerror(errno)); return StringValue(""); } for (size_t j = range.first; j < range.second; ++j) { for (size_t j = begin; j < end; ++j) { if (!android::base::ReadFully(fd, buffer.data(), BLOCKSIZE)) { CauseCode cause_code = errno == EIO ? kEioFailure : kFreadFailure; ErrorAbort(state, cause_code, "failed to read %s: %s", blockdev_filename->data.c_str(), Loading Loading @@ -2185,8 +2185,8 @@ Value* BlockImageRecoverFn(const char* name, State* state, } uint8_t buffer[BLOCKSIZE]; for (const auto& range : rs) { for (size_t j = range.first; j < range.second; ++j) { for (const auto& [begin, end] : rs) { for (size_t j = begin; j < end; ++j) { // Stay within the data area, libfec validates and corrects metadata if (status.data_size <= static_cast<uint64_t>(j) * BLOCKSIZE) { continue; Loading