summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSen Jiang <senj@google.com>2015-11-26 00:08:14 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-11-26 00:08:14 +0000
commit0ef2f7e3c2c40d2153c203173c1641e06edfe95b (patch)
tree931a9da43536b45e312264296ffc468d64806914
parent0fc620f2501b5e40fb590c6820436490a6b8f369 (diff)
parent2c1607d13402172c129d73d76a6a351e78a44328 (diff)
downloadbsdiff-nougat-dev.tar.gz
am: 2c1607d134 * commit '2c1607d13402172c129d73d76a6a351e78a44328': Fix reading extents file if not start from the beginning of a extent.
-rw-r--r--extents_file.cc9
-rw-r--r--extents_file_unittest.cc26
2 files changed, 31 insertions, 4 deletions
diff --git a/extents_file.cc b/extents_file.cc
index 2d2ea83..01d31a6 100644
--- a/extents_file.cc
+++ b/extents_file.cc
@@ -86,14 +86,15 @@ bool ExtentsFile::IOOperation(bool (FileInterface::*io_op)(T*, size_t, size_t*),
AdvancePos(0);
while (count > 0 && curr_ex_idx_ < extents_.size()) {
const ex_t& ex = extents_[curr_ex_idx_];
- size_t chunk_size = std::min(static_cast<uint64_t>(count), ex.len);
+ off_t curr_ex_off = curr_pos_ - acc_len_[curr_ex_idx_];
+ size_t chunk_size =
+ std::min(static_cast<uint64_t>(count), ex.len - curr_ex_off);
size_t chunk_processed = 0;
if (ex.off < 0) {
chunk_processed = chunk_size;
} else {
- uint64_t file_pos = ex.off + (curr_pos_ - acc_len_[curr_ex_idx_]);
- if (!file_->Seek(file_pos) ||
- !((file_.get()->*io_op))(buf, chunk_size, &chunk_processed)) {
+ if (!file_->Seek(ex.off + curr_ex_off) ||
+ !(file_.get()->*io_op)(buf, chunk_size, &chunk_processed)) {
processed += chunk_processed;
result = processed > 0;
break;
diff --git a/extents_file_unittest.cc b/extents_file_unittest.cc
index fa9ed22..73cedb2 100644
--- a/extents_file_unittest.cc
+++ b/extents_file_unittest.cc
@@ -128,6 +128,32 @@ TEST_F(ExtentsFileTest, ReadAcrossAllExtents) {
EXPECT_EQ(15U, bytes_read);
}
+TEST_F(ExtentsFileTest, MultiReadAcrossAllExtents) {
+ ExtentsFile file(std::move(mock_file_ptr_),
+ {ex_t{10, 5}, ex_t{20, 7}, {27, 3}});
+ InSequence s;
+ char* buf = reinterpret_cast<char*>(0x1234);
+
+ EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO());
+ EXPECT_CALL(*mock_file_, Seek(12)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_file_, Read(buf, 3, _)).WillOnce(SucceedIO());
+ EXPECT_CALL(*mock_file_, Seek(20)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_file_, Read(buf + 3, 5, _)).WillOnce(SucceedIO());
+ EXPECT_CALL(*mock_file_, Seek(25)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO());
+ EXPECT_CALL(*mock_file_, Seek(27)).WillOnce(Return(true));
+ EXPECT_CALL(*mock_file_, Read(buf + 2, 3, _)).WillOnce(SucceedIO());
+
+ size_t bytes_read = 0;
+ EXPECT_TRUE(file.Read(buf, 2, &bytes_read));
+ EXPECT_EQ(2U, bytes_read);
+ EXPECT_TRUE(file.Read(buf, 8, &bytes_read));
+ EXPECT_EQ(8U, bytes_read);
+ EXPECT_TRUE(file.Read(buf, 100, &bytes_read));
+ EXPECT_EQ(5U, bytes_read);
+}
+
TEST_F(ExtentsFileTest, ReadSmallChunks) {
ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}});
InSequence s;