diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-10-07 11:20:55 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-10-07 12:22:05 +0200 |
commit | a68eb730558fb90bc8d9524564d8f9e58f3ccac1 (patch) | |
tree | de7a678b28786ec2e47e4956d8cdb0f4466f3d5c /include/sqfs | |
parent | c7fdb2b305ed8b4deb67bfc6ef3257e7e6773397 (diff) |
Improve ABI backward & forward compatibillity
- Padd the compressor config union
- 128 bytes aught to be enough for everyone, i.e. future compressors.
- Insist that the padding space is initialized to 0. If a field gets
added to an existing compressor, it can test for 0 as a sentinel
value.
- Add a size field to the hook structure, aka "the Microsoft way".
- The explanation is in the comment.
- Don't make the Microsoft mistake of checking for >=, insist on *exact*
size match. Future users will need a fallback if their hooks are
rejected. But at least they will be rejected instead of silently not
being used.
- Add an unsupported flag check to the dir tree reader.
- Add a basic abi unit test that, for now, checks the size of the compressor
config struct fields.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'include/sqfs')
-rw-r--r-- | include/sqfs/compressor.h | 15 | ||||
-rw-r--r-- | include/sqfs/data_writer.h | 19 | ||||
-rw-r--r-- | include/sqfs/dir_reader.h | 2 |
3 files changed, 34 insertions, 2 deletions
diff --git a/include/sqfs/compressor.h b/include/sqfs/compressor.h index 46bdf58..a53fbc1 100644 --- a/include/sqfs/compressor.h +++ b/include/sqfs/compressor.h @@ -100,6 +100,11 @@ struct sqfs_compressor_t { * @struct sqfs_compressor_config_t * * @brief Configuration parameters for instantiating a compressor backend. + * + * The unused fields MUST be set to 0. The easiest way to do this is by always + * clearing the struct using memset before setting anything, or using + * @ref sqfs_compressor_config_init to set defaults and then modify the struct + * from there. */ struct sqfs_compressor_config_t { /** @@ -138,6 +143,8 @@ struct sqfs_compressor_config_t { * Default is 15, i.e. 32k window. */ sqfs_u16 window_size; + + sqfs_u32 padd0[3]; } gzip; /** @@ -150,6 +157,8 @@ struct sqfs_compressor_config_t { * Default is 15. */ sqfs_u16 level; + + sqfs_u16 padd0[7]; } zstd; /** @@ -174,6 +183,8 @@ struct sqfs_compressor_config_t { * Defaults to 9, i.e. best compression. */ sqfs_u16 level; + + sqfs_u32 padd0[3]; } lzo; /** @@ -190,7 +201,11 @@ struct sqfs_compressor_config_t { * block size. */ sqfs_u32 dict_size; + + sqfs_u32 padd0[3]; } xz; + + sqfs_u64 padd0[2]; } opt; }; diff --git a/include/sqfs/data_writer.h b/include/sqfs/data_writer.h index 210a08d..4623493 100644 --- a/include/sqfs/data_writer.h +++ b/include/sqfs/data_writer.h @@ -59,6 +59,18 @@ */ struct sqfs_block_hooks_t { /** + * @brief Set this to the size of the struct. + * + * This is required for future expandabillity while maintaining ABI + * compatibillity. At the current time, the implementation of + * @ref sqfs_data_writer_set_hooks rejects any hook struct where this + * isn't the exact size. If new hooks are added in the future, the + * struct grows and the future implementation can tell by the size + * whether the application uses the new version or the old one. + */ + size_t size; + + /** * @brief Gets called before writing a block to disk. * * If this is not NULL, it gets called before a block is written to @@ -283,10 +295,13 @@ int sqfs_data_writer_write_fragment_table(sqfs_data_writer_t *proc, * @param proc A pointer to a data writer object. * @param user_ptr A user pointer to pass to the callbacks. * @param hooks A structure containing the hooks. + * + * @return Zero on success, @ref SQFS_ERROR_UNSUPPORTED if the size field of + * the hooks doesn't match any size knwon to the library. */ SQFS_API -void sqfs_data_writer_set_hooks(sqfs_data_writer_t *proc, void *user_ptr, - const sqfs_block_hooks_t *hooks); +int sqfs_data_writer_set_hooks(sqfs_data_writer_t *proc, void *user_ptr, + const sqfs_block_hooks_t *hooks); #ifdef __cplusplus } diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index 8377fdd..ec84d98 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -99,6 +99,8 @@ typedef enum { * of parent nodes with the subtree stored at the end. */ SQFS_TREE_STORE_PARENTS = 0x40, + + SQFS_TREE_ALL_FLAGS = 0x7F, } E_SQFS_TREE_FILTER_FLAGS; /** |