summaryrefslogtreecommitdiff
path: root/include/sqfs/inode.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sqfs/inode.h')
-rw-r--r--include/sqfs/inode.h312
1 files changed, 312 insertions, 0 deletions
diff --git a/include/sqfs/inode.h b/include/sqfs/inode.h
index d0c49a1..0019360 100644
--- a/include/sqfs/inode.h
+++ b/include/sqfs/inode.h
@@ -22,6 +22,17 @@
#include "sqfs/predef.h"
+/**
+ * @file inode.h
+ *
+ * @brief Contains on-disk data structures used for inodes.
+ */
+
+/**
+ * @enum E_SQFS_INODE_TYPE
+ *
+ * @brief Used by @ref sqfs_inode_t to identify the inode type.
+ */
typedef enum {
SQFS_INODE_DIR = 1,
SQFS_INODE_FILE = 2,
@@ -39,91 +50,389 @@ typedef enum {
SQFS_INODE_EXT_SOCKET = 14,
} E_SQFS_INODE_TYPE;
+/**
+ * @struct sqfs_inode_t
+ *
+ * @brief Common inode structure
+ *
+ * This structure holds the fields common for all inodes. Depending on the type
+ * field, a specific inode structure follows.
+ */
struct sqfs_inode_t {
+ /**
+ * @brief An @ref E_SQFS_INODE_TYPE value.
+ */
uint16_t type;
+
+ /**
+ * @brief Mode filed holding permission bits only. The type is derived
+ * from the type field.
+ */
uint16_t mode;
+
+ /**
+ * @brief An index into the ID table where the owner UID is located.
+ */
uint16_t uid_idx;
+
+ /**
+ * @brief An index into the ID table where the owner GID is located.
+ */
uint16_t gid_idx;
+
+ /**
+ * @brief Last modifcation time.
+ *
+ * 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 mod_time;
+
+ /**
+ * @brief Unique inode number
+ */
uint32_t inode_number;
};
+/**
+ * @struct sqfs_inode_dev_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_BDEV
+ * or @ref SQFS_INODE_CDEV.
+ */
struct sqfs_inode_dev_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Device number.
+ */
uint32_t devno;
};
+/**
+ * @struct sqfs_inode_dev_ext_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_EXT_BDEV
+ * or @ref SQFS_INODE_EXT_CDEV.
+ */
struct sqfs_inode_dev_ext_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Device number.
+ */
uint32_t devno;
+
+ /**
+ * @brief Extended attribute index.
+ */
uint32_t xattr_idx;
};
+/**
+ * @struct sqfs_inode_ipc_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_FIFO
+ * or @ref SQFS_INODE_SOCKET.
+ */
struct sqfs_inode_ipc_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
};
+/**
+ * @struct sqfs_inode_ipc_ext_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_EXT_FIFO
+ * or @ref SQFS_INODE_EXT_SOCKET.
+ */
struct sqfs_inode_ipc_ext_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Extended attribute index.
+ */
uint32_t xattr_idx;
};
+/**
+ * @struct sqfs_inode_slink_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_SLINK.
+ *
+ * The declaration does not contain the flexible array member of the symlink
+ * target because @ref sqfs_inode_generic_t would otherwies be impossible to
+ * implement without violating the C standard.
+ */
struct sqfs_inode_slink_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Size of the symlink target in bytes
+ */
uint32_t target_size;
+
/*uint8_t target[];*/
};
+/**
+ * @struct sqfs_inode_slink_ext_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_EXT_SLINK.
+ *
+ * The declaration does not contain the flexible array member of the symlink
+ * target because it is wedged right in between the target size and the xattr
+ * identifier.
+ */
struct sqfs_inode_slink_ext_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Size of the symlink target in bytes
+ */
uint32_t target_size;
+
/*uint8_t target[];*/
+
+ /**
+ * @brief Extended attribute index.
+ */
uint32_t xattr_idx;
};
+/**
+ * @struct sqfs_inode_file_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_FILE.
+ *
+ * The declaration does not contain the flexible array member for the data
+ * block sizes because @ref sqfs_inode_generic_t would otherwies be impossible
+ * to implement without violating the C standard.
+ *
+ * For each data block, the inode is followed by a 32 bit integer that holds
+ * the on-disk size of the compressed block in bytes and has bit number 24
+ * set if the block is stored uncompressed.
+ *
+ * If a block size is specified as zero, it is assumed to be an entire block
+ * filled with zero bytes.
+ */
struct sqfs_inode_file_t {
+ /**
+ * @brief Absolute position of the first data block.
+ */
uint32_t blocks_start;
+
+ /**
+ * @brief Index into the fragment table or 0xFFFFFFFF if unused.
+ */
uint32_t fragment_index;
+
+ /**
+ * @brief Offset into the uncompressed fragment block or 0xFFFFFFFF
+ * if unused.
+ */
uint32_t fragment_offset;
+
+ /**
+ * @brief Total, uncompressed size of the file in bytes.
+ */
uint32_t file_size;
+
/*uint32_t block_sizes[];*/
};
+/**
+ * @struct sqfs_inode_file_ext_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_EXT_FILE.
+ *
+ * @copydoc sqfs_inode_file_t
+ */
struct sqfs_inode_file_ext_t {
+ /**
+ * @brief Absolute position of the first data block.
+ */
uint64_t blocks_start;
+
+ /**
+ * @brief Total, uncompressed size of the file in bytes.
+ */
uint64_t file_size;
+
+ /**
+ * @brief If the file is sparse, holds the number of bytes not written
+ * to disk because of the omitted sparse blocks.
+ */
uint64_t sparse;
+
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Index into the fragment table or 0xFFFFFFFF if unused.
+ */
uint32_t fragment_idx;
+
+ /**
+ * @brief Offset into the uncompressed fragment block or 0xFFFFFFFF
+ * if unused.
+ */
uint32_t fragment_offset;
+
+ /**
+ * @brief Extended attribute index.
+ */
uint32_t xattr_idx;
+
/*uint32_t block_sizes[];*/
};
+/**
+ * @struct sqfs_inode_dir_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_DIR.
+ */
struct sqfs_inode_dir_t {
+ /**
+ * @brief Offset from the directory table start to the location of the
+ * meta data block containing the first directory header.
+ */
uint32_t start_block;
+
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Combined size of all directory entries and headers in bytes.
+ */
uint16_t size;
+
+ /**
+ * @brief Offset into the uncompressed start block where the header can
+ * be found.
+ */
uint16_t offset;
+
+ /**
+ * @brief Inode number of the parent directory containing
+ * this directory inode.
+ */
uint32_t parent_inode;
};
+/**
+ * @struct sqfs_inode_dir_ext_t
+ *
+ * @brief Follows a @ref sqfs_inode_t if type is @ref SQFS_INODE_EXT_DIR.
+ */
struct sqfs_inode_dir_ext_t {
+ /**
+ * @brief Number of hard links to this node.
+ */
uint32_t nlink;
+
+ /**
+ * @brief Combined size of all directory entries and headers in bytes.
+ */
uint32_t size;
+
+ /**
+ * @brief Offset from the directory table start to the location of the
+ * meta data block containing the first directory header.
+ */
uint32_t start_block;
+
+ /**
+ * @brief Inode number of the parent directory containing
+ * this directory inode.
+ */
uint32_t parent_inode;
+
+ /**
+ * @brief Number of directory index entries following the inode
+ *
+ * This number is stored off-by one and counts the number of
+ * @ref sqfs_dir_index_t entries following the inode.
+ */
uint16_t inodex_count;
+
+ /**
+ * @brief Offset into the uncompressed start block where the header can
+ * be found.
+ */
uint16_t offset;
+
+ /**
+ * @brief Extended attribute index.
+ */
uint32_t xattr_idx;
};
+/**
+ * @struct sqfs_inode_generic_t
+ *
+ * @brief A generic inode structure that combines all others and provides
+ * additional information.
+ *
+ * A few helper functions exist for working with this. For instance,
+ * @ref sqfs_meta_reader_read_inode can read an inode from disk and assemble it
+ * into an instance of this structure. Similarly, the
+ * @ref sqfs_meta_writer_write_inode function can break it down into encoded,
+ * on-disk structures and write them to disk.
+ */
struct sqfs_inode_generic_t {
+ /**
+ * @brief The common fields for all inodes.
+ */
sqfs_inode_t base;
+
+ /**
+ * @brief A pointer into the extra field holding the symlink target.
+ *
+ * @param This string is not null terminated. The helper functions rely
+ * entirely on the length stored in the symlink inode.
+ */
char *slink_target;
+
+ /**
+ * @brief A pointer into the extra field holding file blocks sizes.
+ *
+ * For file inodes, holds the consecutive block sizes. Bit number 24 is
+ * set if the block is stored uncompressed. If it the size is zero,
+ * the block is sparse.
+ */
uint32_t *block_sizes;
+
+ /**
+ * @brief For file inodes, stores the number of blocks used.
+ */
size_t num_file_blocks;
+ /**
+ * @brief Type specific inode data.
+ */
union {
sqfs_inode_dev_t dev;
sqfs_inode_dev_ext_t dev_ext;
@@ -137,6 +446,9 @@ struct sqfs_inode_generic_t {
sqfs_inode_dir_ext_t dir_ext;
} data;
+ /**
+ * @brief Holds type specific extra data, such as symlink target.
+ */
uint8_t extra[];
};