blob: 297444cec5eafbd9014a4e82dcee1b3728af8534 [file] [log] [blame]
From d88f281f827a681928609af0f917e6970c805f52 Mon Sep 17 00:00:00 2001
From: Amin Hassani <ahassani@google.com>
Date: Thu, 15 Dec 2016 10:43:15 -0800
Subject: [PATCH] mksquashfs 4K aligns the files inside the squashfs image
Files inside a squashfs image are not necessarily 4k (4096)
aligned. This patch starts each file in a 4k aligned address and pads
zero to the end of the file until it reaches the next 4k aligned
address. This will not change the size of the compressed
blocks (especially the last one) and hence it will not change how the
files are being loaded in kernel or unsquashfs. However on average this
increases the size of the squashfs image which can be calculated by the
following formula:
increased_size = (number_of_unfragmented_files_in_image + number of fragments) * 2048
The 4k alignment can be enabled by flag '-4k-align'
---
squashfs-tools/mksquashfs.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index ba28d65..a6f3bcb 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -179,6 +179,8 @@ int exit_on_error = FALSE;
/* Is filesystem stored at an offset from the start of the block device/file? */
long long start_offset = 0;
+int do_4k_align = FALSE;
+#define ALIGN_UP(bytes, size) (bytes = (bytes + size - 1) & ~(size - 1))
/* File count statistics used to print summary and fill in superblock */
unsigned int file_count = 0, sym_count = 0, dev_count = 0, dir_count = 0,
@@ -1624,6 +1626,9 @@ static void unlock_fragments()
* queue at this time.
*/
while(!queue_empty(locked_fragment)) {
+ // 4k align the start of remaining queued fragments.
+ if(do_4k_align)
+ ALIGN_UP(bytes, 4096);
write_buffer = queue_get(locked_fragment);
frg = write_buffer->block;
size = SQUASHFS_COMPRESSED_SIZE_BLOCK(fragment_table[frg].size);
@@ -2627,6 +2632,9 @@ static void *frag_deflator(void *arg)
write_buffer->size = compressed_size;
pthread_mutex_lock(&fragment_mutex);
if(fragments_locked == FALSE) {
+ // 4k align the start of each fragment.
+ if(do_4k_align)
+ ALIGN_UP(bytes, 4096);
fragment_table[file_buffer->block].size = c_byte;
fragment_table[file_buffer->block].start_block = bytes;
write_buffer->block = bytes;
@@ -3024,6 +3032,10 @@ static struct file_info *write_file_blocks(int *status, struct dir_ent *dir_ent,
struct file_info *file;
int bl_hash = 0;
+ // 4k align the start of each file.
+ if(do_4k_align)
+ ALIGN_UP(bytes, 4096);
+
if(pre_duplicate(read_size, dir_ent->inode, read_buffer, &bl_hash))
return write_file_blocks_dup(status, dir_ent, read_buffer, dup, bl_hash);
@@ -5825,9 +5837,6 @@ static void write_filesystem_tables(struct squashfs_super_block *sBlk)
SQUASHFS_INSWAP_SUPER_BLOCK(sBlk);
write_destination(fd, SQUASHFS_START, sizeof(*sBlk), sBlk);
-
- total_bytes += total_inode_bytes + total_directory_bytes +
- sizeof(struct squashfs_super_block) + total_xattr_bytes;
}
@@ -6240,6 +6249,7 @@ static void print_options(FILE *stream, char *name, int total_mem)
fprintf(stream, "create a root\n");
fprintf(stream, "\t\t\tdirectory containing that directory, rather than the\n");
fprintf(stream, "\t\t\tcontents of the directory\n");
+ fprintf(stream, "-4k-align\t\tenables 4k alignment of all files\n");
fprintf(stream, "\nFilesystem filter options:\n");
fprintf(stream, "-p <pseudo-definition>\tadd pseudo file ");
fprintf(stream, "definition. The definition should\n");
@@ -6529,6 +6539,7 @@ static void print_sqfstar_options(FILE *stream, char *name, int total_mem)
fprintf(stream, "-no-tailends\t\tdo not pack tail ends into fragments\n");
fprintf(stream, "-no-duplicates\t\tdo not perform duplicate checking\n");
fprintf(stream, "-no-hardlinks\t\tdo not hardlink files, instead store duplicates\n");
+ fprintf(stream, "-4k-align\t\tenables 4k alignment of all files\n");
fprintf(stream, "\nFilesystem filter options:\n");
fprintf(stream, "-p <pseudo-definition>\tadd pseudo file ");
fprintf(stream, "definition. The definition should\n");
@@ -6693,6 +6704,7 @@ static void print_summary()
"compressed", no_fragments ? "no" : noF ? "uncompressed" :
"compressed", no_xattrs ? "no" : noX ? "uncompressed" :
"compressed", noI || noId ? "uncompressed" : "compressed");
+ printf("\t4k %saligned\n", do_4k_align ? "" : "un");
printf("\tduplicates are %sremoved\n", duplicate_checking ? "" :
"not ");
printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", bytes / 1024.0,
@@ -8420,6 +8432,8 @@ print_compressor_options:
} else if(strcmp(argv[i], "-comp") == 0) {
/* parsed previously */
i++;
+ } else if(strcmp(argv[i], "-4k-align") == 0) {
+ do_4k_align = TRUE;
} else {
ERROR("%s: invalid option\n\n", argv[0]);
print_options(stderr, argv[0], total_mem);
--
2.43.0.472.g3155946c3a-goog