diff options
Diffstat (limited to 'libsparse')
-rw-r--r-- | libsparse/Android.mk | 6 | ||||
-rw-r--r-- | libsparse/append2simg.c | 2 | ||||
-rw-r--r-- | libsparse/include/sparse/sparse.h | 3 | ||||
-rw-r--r-- | libsparse/sparse.c | 52 | ||||
-rw-r--r-- | libsparse/sparse_read.c | 4 |
5 files changed, 45 insertions, 22 deletions
diff --git a/libsparse/Android.mk b/libsparse/Android.mk index 0abe33d..925b98b 100644 --- a/libsparse/Android.mk +++ b/libsparse/Android.mk @@ -16,7 +16,7 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_SRC_FILES := $(libsparse_src_files) LOCAL_MODULE := libsparse_host LOCAL_STATIC_LIBRARIES := libz -LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_CFLAGS := -Werror include $(BUILD_HOST_STATIC_LIBRARY) @@ -25,7 +25,7 @@ include $(CLEAR_VARS) LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_SRC_FILES := $(libsparse_src_files) LOCAL_MODULE := libsparse -LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES := \ libz LOCAL_CFLAGS := -Werror @@ -36,7 +36,7 @@ include $(CLEAR_VARS) LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_SRC_FILES := $(libsparse_src_files) LOCAL_MODULE := libsparse_static -LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_STATIC_LIBRARIES := libz LOCAL_CFLAGS := -Werror include $(BUILD_STATIC_LIBRARY) diff --git a/libsparse/append2simg.c b/libsparse/append2simg.c index 65e6cc2..1cf827c 100644 --- a/libsparse/append2simg.c +++ b/libsparse/append2simg.c @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) exit(-1); } - sparse_output = sparse_file_import_auto(output, true); + sparse_output = sparse_file_import_auto(output, true, true); if (!sparse_output) { fprintf(stderr, "Couldn't import output file\n"); exit(-1); diff --git a/libsparse/include/sparse/sparse.h b/libsparse/include/sparse/sparse.h index 8b757d2..42d4adb 100644 --- a/libsparse/include/sparse/sparse.h +++ b/libsparse/include/sparse/sparse.h @@ -234,6 +234,7 @@ struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc); * * @fd - file descriptor to read from * @crc - verify the crc of a file in the Android sparse file format + * @verbose - whether to use verbose logging * * Reads an existing sparse or normal file into a sparse file cookie. * Attempts to determine if the file is sparse or not by looking for the sparse @@ -243,7 +244,7 @@ struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc); * * Returns a new sparse file cookie on success, NULL on error. */ -struct sparse_file *sparse_file_import_auto(int fd, bool crc); +struct sparse_file *sparse_file_import_auto(int fd, bool crc, bool verbose); /** sparse_file_resparse - rechunk an existing sparse file into smaller files * diff --git a/libsparse/sparse.c b/libsparse/sparse.c index baa30cd..311678a 100644 --- a/libsparse/sparse.c +++ b/libsparse/sparse.c @@ -101,26 +101,32 @@ unsigned int sparse_count_chunks(struct sparse_file *s) return chunks; } -static void sparse_file_write_block(struct output_file *out, +static int sparse_file_write_block(struct output_file *out, struct backed_block *bb) { + int ret = -EINVAL; + switch (backed_block_type(bb)) { case BACKED_BLOCK_DATA: - write_data_chunk(out, backed_block_len(bb), backed_block_data(bb)); + ret = write_data_chunk(out, backed_block_len(bb), backed_block_data(bb)); break; case BACKED_BLOCK_FILE: - write_file_chunk(out, backed_block_len(bb), - backed_block_filename(bb), backed_block_file_offset(bb)); + ret = write_file_chunk(out, backed_block_len(bb), + backed_block_filename(bb), + backed_block_file_offset(bb)); break; case BACKED_BLOCK_FD: - write_fd_chunk(out, backed_block_len(bb), - backed_block_fd(bb), backed_block_file_offset(bb)); + ret = write_fd_chunk(out, backed_block_len(bb), + backed_block_fd(bb), + backed_block_file_offset(bb)); break; case BACKED_BLOCK_FILL: - write_fill_chunk(out, backed_block_len(bb), - backed_block_fill_val(bb)); + ret = write_fill_chunk(out, backed_block_len(bb), + backed_block_fill_val(bb)); break; } + + return ret; } static int write_all_blocks(struct sparse_file *s, struct output_file *out) @@ -128,6 +134,7 @@ static int write_all_blocks(struct sparse_file *s, struct output_file *out) struct backed_block *bb; unsigned int last_block = 0; int64_t pad; + int ret = 0; for (bb = backed_block_iter_new(s->backed_block_list); bb; bb = backed_block_iter_next(bb)) { @@ -135,7 +142,9 @@ static int write_all_blocks(struct sparse_file *s, struct output_file *out) unsigned int blocks = backed_block_block(bb) - last_block; write_skip_chunk(out, (int64_t)blocks * s->block_size); } - sparse_file_write_block(out, bb); + ret = sparse_file_write_block(out, bb); + if (ret) + return ret; last_block = backed_block_block(bb) + DIV_ROUND_UP(backed_block_len(bb), s->block_size); } @@ -229,13 +238,15 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, struct backed_block *last_bb = NULL; struct backed_block *bb; struct backed_block *start; + unsigned int last_block = 0; int64_t file_len = 0; + int ret; /* - * overhead is sparse file header, initial skip chunk, split chunk, end - * skip chunk, and crc chunk. + * overhead is sparse file header, the potential end skip + * chunk and crc chunk. */ - int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) + + int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) + sizeof(uint32_t); len -= overhead; @@ -248,28 +259,39 @@ static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, for (bb = start; bb; bb = backed_block_iter_next(bb)) { count = 0; + if (backed_block_block(bb) > last_block) + count += sizeof(chunk_header_t); + last_block = backed_block_block(bb) + + DIV_ROUND_UP(backed_block_len(bb), to->block_size); + /* will call out_counter_write to update count */ - sparse_file_write_block(out_counter, bb); + ret = sparse_file_write_block(out_counter, bb); + if (ret) { + bb = NULL; + goto out; + } if (file_len + count > len) { /* * If the remaining available size is more than 1/8th of the * requested size, split the chunk. Results in sparse files that * are at least 7/8ths of the requested size */ + file_len += sizeof(chunk_header_t); if (!last_bb || (len - file_len > (len / 8))) { backed_block_split(from->backed_block_list, bb, len - file_len); last_bb = bb; } - goto out; + goto move; } file_len += count; last_bb = bb; } -out: +move: backed_block_list_move(from->backed_block_list, to->backed_block_list, start, last_bb); +out: output_file_close(out_counter); return bb; diff --git a/libsparse/sparse_read.c b/libsparse/sparse_read.c index 8e188e9..9b10293 100644 --- a/libsparse/sparse_read.c +++ b/libsparse/sparse_read.c @@ -472,13 +472,13 @@ struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc) return s; } -struct sparse_file *sparse_file_import_auto(int fd, bool crc) +struct sparse_file *sparse_file_import_auto(int fd, bool crc, bool verbose) { struct sparse_file *s; int64_t len; int ret; - s = sparse_file_import(fd, true, crc); + s = sparse_file_import(fd, verbose, crc); if (s) { return s; } |