aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deymo <deymo@google.com>2016-12-08 15:19:49 -0800
committerAlex Deymo <deymo@google.com>2017-01-09 16:39:55 -0800
commit6697c183c48387fb577c5ded9c52fcfa071af2a7 (patch)
tree91395583f21cfd1c75c92294dd9686dafcdb7489
parent0f96b2ccf75a02d344d63fe18a75660c8c9d6c82 (diff)
downloadsquashfs-tools-6697c183c48387fb577c5ded9c52fcfa071af2a7.tar.gz
This patch fixes the rounding of bytes to blocks in the .map file generation process so all blocks are assigned to files while still keeping the files not overlaping. This fixes the previous behavior where the last 4K-block of a file wouldn't be assigned to that block, even in the default 4k-align case leaving the last block of each file unassigned. To achieve this, we assign each block based on the first byte of the block, which prevents overlapping and assigns all the blocks. Bug: 28150981 Test: `make dist` compared system.map with the previous version. No more "gaps" observed. (cherry picked from commit 4445cd175ee8ed20fdec0537a76a6e3cb65fdb53) Change-Id: Iad20a7657f023ef5d2c63fad51e695d86671ff2f
-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, "/");