From: Ken Sumrall Date: Tue, 17 Aug 2010 02:17:38 +0000 (-0700) Subject: Add support for IEEE 802.c stylc CRC32 computation to the sparse image tools X-Git-Tag: android-x86-4.4-r1~279^2 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fsystem-extras.git;a=commitdiff_plain;h=5a6181798de5c2d882c79b27406c330a6fa7da3e Add support for IEEE 802.c stylc CRC32 computation to the sparse image tools Add support for computing the CRC32 of the data when we make a sparse image, and storing that CRC in the header. Also update the simg2img tool that reads sparse images to compute the CRC32 as it writes the image, and check to make sure it matches what's in the header. Change-Id: Iadea3a760f91fa9b1efd22a3580dd1943b1ff52e --- diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index 14702540..c7934a3d 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -14,6 +14,7 @@ libext4_utils_src_files := \ indirect.c \ uuid.c \ sha1.c \ + sparse_crc32.c LOCAL_SRC_FILES := $(libext4_utils_src_files) LOCAL_MODULE := libext4_utils @@ -63,7 +64,8 @@ include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) -LOCAL_SRC_FILES := simg2img.c +LOCAL_SRC_FILES := simg2img.c \ + sparse_crc32.c LOCAL_MODULE := simg2img include $(BUILD_HOST_EXECUTABLE) diff --git a/ext4_utils/output_file.c b/ext4_utils/output_file.c index 2705701c..3785b06e 100644 --- a/ext4_utils/output_file.c +++ b/ext4_utils/output_file.c @@ -27,6 +27,7 @@ #include "ext4_utils.h" #include "output_file.h" #include "sparse_format.h" +#include "sparse_crc32.h" #if defined(__APPLE__) && defined(__MACH__) #define lseek64 lseek @@ -148,7 +149,7 @@ static u8 *zero_buf; static int emit_skip_chunk(struct output_file *out, u64 skip_len) { chunk_header_t chunk_header; - int ret; + int ret, chunk; //DBG printf("skip chunk: 0x%llx bytes\n", skip_len); @@ -166,10 +167,17 @@ static int emit_skip_chunk(struct output_file *out, u64 skip_len) ret = out->ops->write(out, (u8 *)&chunk_header, sizeof(chunk_header)); if (ret < 0) return -1; - // KEN: TODO: CRC computation + out->cur_out_ptr += skip_len; out->chunk_cnt++; + /* Compute the CRC for all those zeroes. Do it block_size bytes at a time. */ + while (skip_len) { + chunk = (skip_len > info.block_size) ? info.block_size : skip_len; + out->crc32 = sparse_crc32(out->crc32, zero_buf, chunk); + skip_len -= chunk; + } + return 0; } @@ -231,7 +239,9 @@ static int write_chunk_raw(struct output_file *out, u64 off, u8 *data, int len) return -1; } - // KEN: TODO: CRC computation of both the raw data and and zero buf data written */ + out->crc32 = sparse_crc32(out->crc32, data, len); + if (zero_len) + out->crc32 = sparse_crc32(out->crc32, zero_buf, zero_len); out->cur_out_ptr += rnd_up_len; out->chunk_cnt++; @@ -293,6 +303,10 @@ struct output_file *open_output_file(const char *filename, int gz, int sparse) out->sparse = sparse; out->cur_out_ptr = 0ll; out->chunk_cnt = 0; + + /* Initialize the crc32 value */ + out->crc32 = 0; + if (out->sparse) { /* Write out the file header. We'll update the unknown fields * when we close the file. @@ -321,7 +335,6 @@ void pad_output_file(struct output_file *out, u64 len) * cur_out_ptr is not already at the end of the filesystem. * We also need to compute the CRC for it. */ - //KEN: TODO: CRC computation! if (len < out->cur_out_ptr) { error("attempted to pad file %llu bytes less than the current output pointer", out->cur_out_ptr - len); diff --git a/ext4_utils/simg2img.c b/ext4_utils/simg2img.c index 9c1ad370..88c67b48 100644 --- a/ext4_utils/simg2img.c +++ b/ext4_utils/simg2img.c @@ -27,6 +27,7 @@ #include "ext4_utils.h" #include "output_file.h" #include "sparse_format.h" +#include "sparse_crc32.h" #if defined(__APPLE__) && defined(__MACH__) #define lseek64 lseek @@ -36,6 +37,9 @@ #define COPY_BUF_SIZE (1024*1024) u8 *copybuf; +/* This will be malloc'ed with the size of blk_sz from the sparse file header */ +u8* zerobuf; + #define SPARSE_HEADER_MAJOR_VER 1 #define SPARSE_HEADER_LEN (sizeof(sparse_header_t)) #define CHUNK_HEADER_LEN (sizeof(chunk_header_t)) @@ -52,8 +56,15 @@ int process_raw_chunk(FILE *in, FILE *out, u32 blocks, u32 blk_sz, u32 *crc32) while (len) { chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len; - fread(copybuf, chunk, 1, in); - fwrite(copybuf, chunk, 1, out); + if (fread(copybuf, chunk, 1, in) != 1) { + fprintf(stderr, "fread returned an error copying a raw chunk\n"); + exit(-1); + } + *crc32 = sparse_crc32(*crc32, copybuf, chunk); + if (fwrite(copybuf, chunk, 1, out) != 1) { + fprintf(stderr, "fwrite returned an error copying a raw chunk\n"); + exit(-1); + } len -= chunk; } @@ -67,17 +78,26 @@ int process_skip_chunk(FILE *out, u32 blocks, u32 blk_sz, u32 *crc32) * as a 32 bit value of blocks. */ u64 len = (u64)blocks * blk_sz; - long skip_chunk; + u64 len_save; + u32 skip_chunk; /* Fseek takes the offset as a long, which may be 32 bits on some systems. * So, lets do a sequence of fseeks() with SEEK_CUR to get the file pointer * where we want it. */ + len_save = len; while (len) { skip_chunk = (len > 0x80000000) ? 0x80000000 : len; fseek(out, skip_chunk, SEEK_CUR); len -= skip_chunk; } + /* And compute the CRC of the skipped region a chunk at a time */ + len = len_save; + while (len) { + skip_chunk = (skip_chunk > blk_sz) ? blk_sz : skip_chunk; + *crc32 = sparse_crc32(*crc32, zerobuf, skip_chunk); + len -= skip_chunk; + } return blocks; } @@ -133,6 +153,11 @@ int main(int argc, char *argv[]) fseek(in, sparse_header.file_hdr_sz - SPARSE_HEADER_LEN, SEEK_CUR); } + if ( (zerobuf = malloc(sparse_header.blk_sz)) == 0) { + fprintf(stderr, "Cannot malloc zero buf\n"); + exit(-1); + } + for (i=0; i> 8); + return crc ^ ~0U; +} + diff --git a/ext4_utils/sparse_crc32.h b/ext4_utils/sparse_crc32.h new file mode 100644 index 00000000..21625bac --- /dev/null +++ b/ext4_utils/sparse_crc32.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +u32 sparse_crc32(u32 crc, const void *buf, size_t size); +