diff --git a/sqfs/pkg2sqfs.c b/sqfs/pkg2sqfs.c index 927b886..c6cda9e 100644 --- a/sqfs/pkg2sqfs.c +++ b/sqfs/pkg2sqfs.c @@ -3,12 +3,13 @@ static struct option long_opts[] = { { "block-size", required_argument, NULL, 'b' }, + { "dev-block-size", required_argument, NULL, 'B' }, { "force", no_argument, NULL, 'f' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, }; -static const char *short_opts = "b:fhV"; +static const char *short_opts = "b:B:fhV"; extern char *__progname; @@ -28,11 +29,13 @@ static const char *help_string = "\n" "Possible options:\n" "\n" -" --block-size, -b Block size to use for Squashfs image.\n" -" Defaults to %u.\n" -" --force, -f Overwrite the output file if it already exists.\n" -" --help, -h Print help text and exit.\n" -" --version, -V Print version information and exit.\n" +" --block-size, -b Block size to use for Squashfs image.\n" +" Defaults to %u.\n" +" --dev-block-size, -B Device block size to padd the image to.\n" +" Defaults to %u.\n" +" --force, -f Overwrite the output file if it exists.\n" +" --help, -h Print help text and exit.\n" +" --version, -V Print version information and exit.\n" "\n"; static void print_tree(int level, node_t *n) @@ -82,6 +85,7 @@ int main(int argc, char **argv) sqfs_info_t info; memset(&info, 0, sizeof(info)); + info.dev_blk_size = SQFS_DEVBLK_SIZE; for (;;) { i = getopt_long(argc, argv, short_opts, long_opts, NULL); @@ -97,12 +101,21 @@ int main(int argc, char **argv) return EXIT_FAILURE; } break; + case 'B': + info.dev_blk_size = strtonum(optarg, 4096, 0xFFFFFFFF, + &errstr); + if (errstr != NULL) { + fprintf(stderr, "Block size '%s': %s\n", + optarg, errstr); + return EXIT_FAILURE; + } + break; case 'f': outmode = O_WRONLY | O_CREAT | O_TRUNC; break; case 'h': printf(help_string, __progname, - SQFS_DEFAULT_BLOCK_SIZE); + SQFS_DEFAULT_BLOCK_SIZE, SQFS_DEVBLK_SIZE); exit(EXIT_SUCCESS); case 'V': printf(version_string, __progname, @@ -173,6 +186,9 @@ int main(int argc, char **argv) if (sqfs_super_write(&info)) goto out_fragments; + if (sqfs_padd_file(&info)) + goto out_fragments; + status = EXIT_SUCCESS; out_fragments: free(info.fragments); diff --git a/sqfs/pkg2sqfs.h b/sqfs/pkg2sqfs.h index 9a7dfe1..5240012 100644 --- a/sqfs/pkg2sqfs.h +++ b/sqfs/pkg2sqfs.h @@ -102,6 +102,8 @@ typedef struct { int file_block_count; file_info_t *frag_list; size_t frag_offset; + + size_t dev_blk_size; } sqfs_info_t; int pkg_data_to_sqfs(sqfs_info_t *info); @@ -134,4 +136,6 @@ int meta_writer_append(meta_writer_t *m, const void *data, size_t size); int sqfs_write_table(sqfs_info_t *info, const void *data, size_t entsize, size_t count, uint64_t *start); +int sqfs_padd_file(sqfs_info_t *info); + #endif /* PKG2SQFS_H */ diff --git a/sqfs/squashfs.h b/sqfs/squashfs.h index adda313..ecbace1 100644 --- a/sqfs/squashfs.h +++ b/sqfs/squashfs.h @@ -9,6 +9,7 @@ #define SQFS_VERSION_MINOR 0 #define SQFS_META_BLOCK_SIZE 8192 #define SQFS_DEFAULT_BLOCK_SIZE 131072 +#define SQFS_DEVBLK_SIZE 4096 typedef struct { uint32_t magic; diff --git a/sqfs/super.c b/sqfs/super.c index 0241866..8b27132 100644 --- a/sqfs/super.c +++ b/sqfs/super.c @@ -97,3 +97,39 @@ int sqfs_super_write(sqfs_info_t *info) return 0; } + +int sqfs_padd_file(sqfs_info_t *info) +{ + size_t padd_sz = info->super.bytes_used % info->dev_blk_size; + uint8_t *buffer; + ssize_t ret; + off_t off; + + if (padd_sz == 0) + return 0; + + off = lseek(info->outfd, 0, SEEK_END); + if (off == (off_t)-1) { + perror("seek on output file"); + return -1; + } + + padd_sz = info->dev_blk_size - padd_sz; + buffer = alloca(padd_sz); + memset(buffer, 0, padd_sz); + + ret = write_retry(info->outfd, buffer, padd_sz); + + if (ret < 0) { + perror("Error padding squashfs image to page size"); + return -1; + } + + if (ret == 0) { + fputs("Truncated write trying to padd squashfs image\n", + stderr); + return -1; + } + + return 0; +}