aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deymo <deymo@google.com>2016-12-12 21:39:09 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-12-12 21:39:09 +0000
commit586e5080a92e38afc05d30e78c9b37a12b6ccf7c (patch)
tree79c30e3740fe95a56f81f0cf27df11fc89e7bfc7
parentec11d019bfbba513daa31caf53d33316c4deef62 (diff)
parentc647cfd881428ff760a315cf6df61238826f0cb3 (diff)
downloadsquashfs-tools-586e5080a92e38afc05d30e78c9b37a12b6ccf7c.tar.gz
Fix rounding error when generating .map files. am: 4445cd175e
am: c647cfd881 Change-Id: Iec289ed972e1e85b97d7e5039ced6e91f5cfd840
-rw-r--r--squashfs-tools/mksquashfs.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index a91fd9e..936ae05 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -863,11 +863,29 @@ static inline unsigned int get_parent_no(struct dir_info *dir)
/* ANDROID CHANGES START*/
#ifdef ANDROID
+
+/* Round up the passed |n| value to the smallest multiple of 4096 greater or
+ * equal than |n| and return the 4K-block number for that value. */
+static unsigned long long round_up_block(unsigned long long n) {
+ const unsigned long long kMapBlockSize = 4096;
+ return (n + kMapBlockSize - 1) / kMapBlockSize;
+}
+
static inline void write_block_map_entry(char *sub_path, unsigned long long start_block, unsigned long long total_size,
char * mount_point, FILE *block_map_file) {
if (block_map_file) {
- unsigned long long round_start = (start_block + (1 << 12) - 1) >> 12;
- unsigned long long round_end = ((start_block + total_size) >> 12) - 1;
+ /* We assign each 4K block based on what file the first byte of the block
+ * belongs to. The current file consists of the chunk of bytes in the
+ * interval [start_block, start_block + total_size), (closed on the left end
+ * and open on the right end). We then compute the first block whose first
+ * byte is equal to or greater than start_block as |round_start| and then
+ * the first block whose first byte is *past* this interval, as
+ * |round_end + 1|. This means that the blocks that should be assigned to
+ * the current file are in the interval [round_start, round_end + 1), or
+ * simply [round_start, round_end].
+ */
+ unsigned long long round_start = round_up_block(start_block);
+ unsigned long long round_end = round_up_block(start_block + total_size) - 1;
if (round_start && total_size && round_start <= round_end) {
fprintf(block_map_file, "/%s", mount_point);
if (sub_path[0] != '/') fprintf(block_map_file, "/");