aboutsummaryrefslogtreecommitdiff
path: root/squashfs-tools/lz4_wrapper.c
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@squashfs.org.uk>2013-12-31 22:58:55 +0000
committerMohamad Ayyash <mkayyash@google.com>2015-02-23 12:36:06 -0800
commitb642c41261e510bc2b314008d8b01b9902554e58 (patch)
tree5662aba61fa4de8307f2d80f0f47e0873f272dfd /squashfs-tools/lz4_wrapper.c
parentc755a2126482a6f86dcaff5c7ff3acfff9fe85ff (diff)
downloadsquashfs-tools-b642c41261e510bc2b314008d8b01b9902554e58.tar.gz
compressor: don't overload extract_options
When I added LZ4 support, I realised that Unsquashfs should check the compression options (if any) to ensure that the decompressor can decompress the filesystem. This situation never occurred before because gzip and lzo doesn't have any options, and I envisaged that xz will always implicitly be able to *decompress* any filesystem irrespective of any hitherto unimplemented compression features. In otherwords I anticipated we should check the options in mksquashfs (on append), but not on decompression with unsquashfs. LZ4 changed that because the kernel is currently using the LZ4 legacy format, and this may change, creating a situation where in the future there may be a new format, which is *not* currently understood. Therefore Unsquashfs needs to check the options too. I initially used extract_options(), but this has thrown up subtle differences in the handling of compression options between unsquashfs and mksquashfs. Specificallyx, in the handling of the presence of compression options where the compressor hasn't got an extract_options function. This is clear indication that the filesystem is newer than the code because it has compression options whereas the code hasn't any support for them. Now in mksquashfs where it is appending to the filesystem, this is a definate fail because we obviously cannot extract the options and set the compressor to the appropriate state. But, this should not be a fail for Unsquashfs, because in retro-fitting compression options to a compressor which didn't originally have them (i.e. LZO), we have to ensure that the new compression options are implicitly decompressible by the original code, because the original code doesn't check them. So for instance with LZO, we cannot allow an old Mksquashfs to append to an LZO filesystem compressed with the new compression options, but, it is perfectly possible for an old version of Unsquashfs to decompress this filesystem. So don't overload extract_options, and instead introduce a new check_options specifically for Unsquashfs, and specifically only for the decompressors (LZ4) which need to check them. Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Diffstat (limited to 'squashfs-tools/lz4_wrapper.c')
-rw-r--r--squashfs-tools/lz4_wrapper.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/squashfs-tools/lz4_wrapper.c b/squashfs-tools/lz4_wrapper.c
index 6b9c071..b87cfe0 100644
--- a/squashfs-tools/lz4_wrapper.c
+++ b/squashfs-tools/lz4_wrapper.c
@@ -144,6 +144,46 @@ failed:
}
+/*
+ * This function is a helper specifically for unsquashfs.
+ * Its purpose is to check that the compression options are
+ * understood by this version of LZ4.
+ *
+ * This is important for LZ4 because the format understood by the
+ * Linux kernel may change from the already obsolete legacy format
+ * currently supported.
+ *
+ * If this does happen, then this version of LZ4 will not be able to decode
+ * the newer format. So we need to check for this.
+ *
+ * This function returns 0 on sucessful checking of options, and
+ * -1 on error
+ */
+static int lz4_check_options(int block_size, void *buffer, int size)
+{
+ struct lz4_comp_opts *comp_opts = buffer;
+
+ /* we expect a comp_opts structure to be present */
+ if(size < sizeof(*comp_opts))
+ goto failed;
+
+ SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
+
+ /* we expect the stream format to be LZ4_LEGACY */
+ if(comp_opts->version != LZ4_LEGACY) {
+ fprintf(stderr, "lz4: unknown LZ4 version\n");
+ goto failed;
+ }
+
+ return 0;
+
+failed:
+ fprintf(stderr, "lz4: error reading stored compressor options from "
+ "filesystem!\n");
+ return -1;
+}
+
+
void lz4_display_options(void *buffer, int size)
{
struct lz4_comp_opts *comp_opts = buffer;
@@ -234,6 +274,7 @@ struct compressor lz4_comp_ops = {
.options = lz4_options,
.dump_options = lz4_dump_options,
.extract_options = lz4_extract_options,
+ .check_options = lz4_check_options,
.display_options = lz4_display_options,
.usage = lz4_usage,
.id = LZ4_COMPRESSION,