diff options
author | Jeremy Compostella | 2015-04-03 07:31:19 -0500 |
---|---|---|
committer | Jeremy Compostella | 2015-04-08 03:10:17 -0500 |
commit | cfd3a03d3d147fca7a33d6f583b7047c5351fc32 (patch) | |
tree | ab6ba56dac1b2de967a248cfb90324d5d2e3ca8a /libsparse | |
parent | 27cda9a535c80470e913156e412cbf7e60c3217c (diff) | |
download | platform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.tar.gz platform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.tar.xz platform-system-core-cfd3a03d3d147fca7a33d6f583b7047c5351fc32.zip |
libsparse: move_chunks_up_to_len() does not account skip chunks
I caught the fastboot host command sending more data than the fastboot
device can accept. Fastboot host command was sending 36 surplus bytes
because of 3 skip chunks that were not taken into account in
move_chunks_up_to_len() algorithm.
Change-Id: I39a4a033c9b15893bd70e553f17116735ee4a48e
Diffstat (limited to 'libsparse')
-rw-r--r-- | libsparse/sparse.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/libsparse/sparse.c b/libsparse/sparse.c index 65c09e0d4..311678a34 100644 --- a/libsparse/sparse.c +++ b/libsparse/sparse.c | |||
@@ -238,14 +238,15 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, | |||
238 | struct backed_block *last_bb = NULL; | 238 | struct backed_block *last_bb = NULL; |
239 | struct backed_block *bb; | 239 | struct backed_block *bb; |
240 | struct backed_block *start; | 240 | struct backed_block *start; |
241 | unsigned int last_block = 0; | ||
241 | int64_t file_len = 0; | 242 | int64_t file_len = 0; |
242 | int ret; | 243 | int ret; |
243 | 244 | ||
244 | /* | 245 | /* |
245 | * overhead is sparse file header, initial skip chunk, split chunk, end | 246 | * overhead is sparse file header, the potential end skip |
246 | * skip chunk, and crc chunk. | 247 | * chunk and crc chunk. |
247 | */ | 248 | */ |
248 | int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) + | 249 | int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) + |
249 | sizeof(uint32_t); | 250 | sizeof(uint32_t); |
250 | len -= overhead; | 251 | len -= overhead; |
251 | 252 | ||
@@ -258,6 +259,11 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, | |||
258 | 259 | ||
259 | for (bb = start; bb; bb = backed_block_iter_next(bb)) { | 260 | for (bb = start; bb; bb = backed_block_iter_next(bb)) { |
260 | count = 0; | 261 | count = 0; |
262 | if (backed_block_block(bb) > last_block) | ||
263 | count += sizeof(chunk_header_t); | ||
264 | last_block = backed_block_block(bb) + | ||
265 | DIV_ROUND_UP(backed_block_len(bb), to->block_size); | ||
266 | |||
261 | /* will call out_counter_write to update count */ | 267 | /* will call out_counter_write to update count */ |
262 | ret = sparse_file_write_block(out_counter, bb); | 268 | ret = sparse_file_write_block(out_counter, bb); |
263 | if (ret) { | 269 | if (ret) { |
@@ -270,6 +276,7 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, | |||
270 | * requested size, split the chunk. Results in sparse files that | 276 | * requested size, split the chunk. Results in sparse files that |
271 | * are at least 7/8ths of the requested size | 277 | * are at least 7/8ths of the requested size |
272 | */ | 278 | */ |
279 | file_len += sizeof(chunk_header_t); | ||
273 | if (!last_bb || (len - file_len > (len / 8))) { | 280 | if (!last_bb || (len - file_len > (len / 8))) { |
274 | backed_block_split(from->backed_block_list, bb, len - file_len); | 281 | backed_block_split(from->backed_block_list, bb, len - file_len); |
275 | last_bb = bb; | 282 | last_bb = bb; |