AU: Optionally limit the size of delta update operations.
Add a --chunk_size flag to delta_generator. If it's not -1, files will
be split into chunks of this size when generating delta payloads. This
effectively limits the size of each delta operation.
BUG=chromium:229797
TEST=unit tests; generated delta payloads and checked them through
paycheck.py.
Change-Id: I21502118088bfbac75aa8009eb144f6aaf23a83a
Reviewed-on: https://gerrit.chromium.org/gerrit/48357
Commit-Queue: Darin Petkov <petkov@chromium.org>
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/extent_mapper.cc b/extent_mapper.cc
index e02f5a2..1cfd8bb 100644
--- a/extent_mapper.cc
+++ b/extent_mapper.cc
@@ -31,40 +31,55 @@
const int kBlockSize = 4096;
}
-bool ExtentsForFileFibmap(const std::string& path, std::vector<Extent>* out) {
+bool ExtentsForFileChunkFibmap(const std::string& path,
+ off_t chunk_offset,
+ off_t chunk_size,
+ std::vector<Extent>* out) {
CHECK(out);
+ CHECK_EQ(0, chunk_offset % kBlockSize);
+ CHECK(chunk_size == -1 || chunk_size >= 0);
struct stat stbuf;
int rc = stat(path.c_str(), &stbuf);
TEST_AND_RETURN_FALSE_ERRNO(rc == 0);
TEST_AND_RETURN_FALSE(S_ISREG(stbuf.st_mode));
-
+
int fd = open(path.c_str(), O_RDONLY, 0);
TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
ScopedFdCloser fd_closer(&fd);
-
+
// Get file size in blocks
rc = fstat(fd, &stbuf);
if (rc < 0) {
perror("fstat");
return false;
}
- const int block_count = (stbuf.st_size + kBlockSize - 1) / kBlockSize;
+ CHECK_LE(chunk_offset, stbuf.st_size);
+ off_t size = stbuf.st_size - chunk_offset;
+ if (chunk_size != -1) {
+ size = std::min(size, chunk_size);
+ }
+ const int block_count = (size + kBlockSize - 1) / kBlockSize;
+ const int start_block = chunk_offset / kBlockSize;
Extent current;
current.set_start_block(0);
current.set_num_blocks(0);
- for (int i = 0; i < block_count; i++) {
+ for (int i = start_block; i < start_block + block_count; i++) {
unsigned int block32 = i;
rc = ioctl(fd, FIBMAP, &block32);
TEST_AND_RETURN_FALSE_ERRNO(rc == 0);
-
+
const uint64_t block = (block32 == 0 ? kSparseHole : block32);
-
+
graph_utils::AppendBlockToExtents(out, block);
}
return true;
}
+bool ExtentsForFileFibmap(const std::string& path, std::vector<Extent>* out) {
+ return ExtentsForFileChunkFibmap(path, 0, -1, out);
+}
+
bool GetFilesystemBlockSize(const std::string& path, uint32_t* out_blocksize) {
int fd = open(path.c_str(), O_RDONLY, 0);
TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);