diff options
Diffstat (limited to 'include/sqfs/super.h')
-rw-r--r-- | include/sqfs/super.h | 231 |
1 files changed, 228 insertions, 3 deletions
diff --git a/include/sqfs/super.h b/include/sqfs/super.h index 4556d3d..5e6c00a 100644 --- a/include/sqfs/super.h +++ b/include/sqfs/super.h @@ -22,34 +22,172 @@ #include "sqfs/predef.h" +/** + * @file super.h + * + * @brief Contains on-disk data structures, identifiers and functions for the + * SquashFS super block. + */ + #define SQFS_MAGIC 0x73717368 #define SQFS_VERSION_MAJOR 4 #define SQFS_VERSION_MINOR 0 #define SQFS_DEVBLK_SIZE 4096 #define SQFS_DEFAULT_BLOCK_SIZE 131072 +/** + * @struct sqfs_super_t + * + * @brief The SquashFS super block, located at the beginning of the file system + * to describe the layout of the filesystem. + */ struct sqfs_super_t { + /** + * @brief Magic number. Must be set to SQFS_MAGIC. + */ uint32_t magic; + + /** + * @brief Total number of inodes. + */ uint32_t inode_count; + + /** + * @brief Last time the filesystem was modified. + * + * This field counts seconds (not counting leap seconds) since 00:00, + * Jan 1 1970 UTC. This field is unsigned, so it expires in the year + * 2106 (as opposed to 2038). + */ uint32_t modification_time; + + /** + * @brief The data block size in bytes. + * + * Must be a power of 2, no less than 4k and not larger than 1M. + */ uint32_t block_size; + + /** + * @brief The number of fragment blocks in the data area. + */ uint32_t fragment_entry_count; + + /** + * @brief Identifies the compressor that has been used. + * + * Valid identifiers are in the @ref E_SQFS_COMPRESSOR enum. + */ uint16_t compression_id; + + /** + * @brief The log2 of the block_size field for sanity checking + * + * Must be no less than 12 and not larger than 20. + */ uint16_t block_log; + + /** + * @brief A combination of @ref E_SQFS_SUPER_FLAGS flags + * + * Most of the flags that can be set here are informative only. + */ uint16_t flags; + + /** + * @brief The total number of unique user or group IDs. + */ uint16_t id_count; + + /** + * @brief Must be @ref SQFS_VERSION_MAJOR + */ uint16_t version_major; + + /** + * @brief Must be @ref SQFS_VERSION_MINOR + */ uint16_t version_minor; + + /** + * @brief A reference to the root inode + * + * The bits 16 to 48 hold an offset that is added to inode_table_start + * to get the location of the meta data block containing the inode. + * The lower 16 bits hold a byte offset into the uncompressed block. + */ uint64_t root_inode_ref; + + /** + * @brief Total size of the file system in bytes, not counting padding + */ uint64_t bytes_used; + + /** + * @brief On-disk location of the ID table + * + * This value must point to a location after the directory table and + * (if present) after the export and fragment tables, but before the + * xattr table. + */ uint64_t id_table_start; + + /** + * @brief On-disk location of the extended attribute table (if present) + * + * See @ref sqfs_xattr_reader_t for an overview on how SquashFS stores + * extended attributes on disk. + * + * This value must either point to a location after the ID table, or + * it must be set to 0xFFFFFFFF to indicate the table is not present. + */ uint64_t xattr_id_table_start; + + /** + * @brief On-disk location of the first meta data block containing + * the inodes + * + * This value must point to a location before the directory table. + */ uint64_t inode_table_start; + + /** + * @brief On-disk location of the first meta data block containing + * the directory entries + * + * This value must point to a location after the inode table but + * before the fragment, export, ID and xattr tables. + */ uint64_t directory_table_start; + + /** + * @brief On-disk location of the fragment table (if present) + * + * This value must either point to a location after the directory + * table, but before the export, ID and xattr tables, or it must be + * set to 0xFFFFFFFF to indicate that the table is not present. + */ uint64_t fragment_table_start; + + /** + * @brief On-disk location of the export table (if present) + * + * This value must either point to a location after directory table + * (and if present after the fragment table), but before the ID table, + * or it must be set to 0xFFFFFFFF to indicate that the table is not + * present. + */ uint64_t export_table_start; }; +/** + * @enum E_SQFS_COMPRESSOR + * + * @brief Set in @ref sqfs_super_t to identify the compresser used by the + * filesystem. + * + * Most of the flags that can be set are informative only. + */ typedef enum { SQFS_COMP_GZIP = 1, SQFS_COMP_LZMA = 2, @@ -62,17 +200,72 @@ typedef enum { SQFS_COMP_MAX = 6, } E_SQFS_COMPRESSOR; +/** + * @enum E_SQFS_SUPER_FLAGS + * + * @brief Flags that can be set in @ref sqfs_super flags field. + */ typedef enum { + /** + * @brief Set to indicate that meta data blocks holding the inodes are + * stored uncompressed. + */ SQFS_FLAG_UNCOMPRESSED_INODES = 0x0001, + + /** + * @brief Set to indicate that all data blocks are stored uncompressed. + */ SQFS_FLAG_UNCOMPRESSED_DATA = 0x0002, + + /** + * @brief Set to indicate that all fragment blocks are stored + * uncompressed. + */ SQFS_FLAG_UNCOMPRESSED_FRAGMENTS = 0x0008, + + /** + * @brief Set to indicate that there are no fragment blocks. + */ SQFS_FLAG_NO_FRAGMENTS = 0x0010, + + /** + * @brief Set to indicate that fragments have been generated for all + * files that are not a multiple of the block size in size. + */ SQFS_FLAG_ALWAYS_FRAGMENTS = 0x0020, + + /** + * @brief Set to indicate that data blocks have not been deduplicated. + */ SQFS_FLAG_DUPLICATES = 0x0040, + + /** + * @brief Set to indicate that an NFS export table is present. + */ SQFS_FLAG_EXPORTABLE = 0x0080, + + /** + * @brief Set to indicate that meta data blocks holding extended + * attributes are stored uncompressed. + */ SQFS_FLAG_UNCOMPRESSED_XATTRS = 0x0100, + + /** + * @brief Set to indicate that the filesystem does not + * contain extended attributes. + */ SQFS_FLAG_NO_XATTRS = 0x0200, + + /** + * @brief Set to indicate that a single, uncompressed meta data block + * with compressor options follows the super block. + */ SQFS_FLAG_COMPRESSOR_OPTIONS = 0x0400, + + /** + * @brief Set to indicate that meta data blocks holding the IDs are + * stored uncompressed. + */ SQFS_FLAG_UNCOMPRESSED_IDS = 0x0800, } E_SQFS_SUPER_FLAGS; @@ -80,15 +273,47 @@ typedef enum { extern "C" { #endif -/* Returns 0 on success. Prints error messages to stderr on failure. */ +/** + * @brief Initialize the SquashFS super block. + * + * @memberof sqfs_super_t + * + * @param super A pointer to a super block structure. + * @param block_size The uncompressed size of the data blocks in bytes. + * @param mtime The modification time stamp to set. + * @param compressor The compressor ID to set. + * + * @return Zero on success, an @ref E_SQFS_ERROR value if one of the + * fields does not hold a valid value. + */ SQFS_API int sqfs_super_init(sqfs_super_t *super, size_t block_size, uint32_t mtime, E_SQFS_COMPRESSOR compressor); -/* Returns 0 on success. Prints error messages to stderr on failure. */ +/** + * @brief Encode and write a SquashFS super block to disk. + * + * @memberof sqfs_super_t + * + * @param super A pointer to the super block structure to write. + * @param file A file object through which to access the filesystem image. + * + * @return Zero on success, an @ref E_SQFS_ERROR value if one of the + * fields does not hold a valid value. + */ SQFS_API int sqfs_super_write(sqfs_super_t *super, sqfs_file_t *file); -/* Returns 0 on success. Prints error messages to stderr on failure. */ +/** + * @brief Read a SquashFS super block from disk, decode it and check the fields + * + * @memberof sqfs_super_t + * + * @param super A pointer to the super block structure to fill. + * @param file A file object through which to access the filesystem image. + * + * @return Zero on success, an @ref E_SQFS_ERROR value if one of the + * fields does not hold a valid value. + */ SQFS_API int sqfs_super_read(sqfs_super_t *super, sqfs_file_t *file); #ifdef __cplusplus |