uboot/fs/squashfs/sqfs_filesystem.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Copyright (C) 2020 Bootlin
   4 *
   5 * Author: Joao Marcos Costa <joaomarcos.costa@bootlin.com>
   6 */
   7
   8#ifndef SQFS_FILESYSTEM_H
   9#define SQFS_FILESYSTEM_H
  10
  11#include <asm/unaligned.h>
  12#include <fs.h>
  13#include <part.h>
  14#include <stdint.h>
  15
  16#define SQFS_UNCOMPRESSED_DATA 0x0002
  17#define SQFS_MAGIC_NUMBER 0x73717368
  18/* The three first members of squashfs_dir_index make a total of 12 bytes */
  19#define SQFS_DIR_INDEX_BASE_LENGTH 12
  20/* size of metadata (inode and directory) blocks */
  21#define SQFS_METADATA_BLOCK_SIZE 8192
  22/* Max. number of fragment entries in a metadata block is 512 */
  23#define SQFS_MAX_ENTRIES 512
  24/* Metadata blocks start by a 2-byte length header */
  25#define SQFS_HEADER_SIZE 2
  26#define SQFS_LREG_INODE_MIN_SIZE 56
  27#define SQFS_DIR_HEADER_SIZE 12
  28#define SQFS_MISC_ENTRY_TYPE -1
  29#define SQFS_EMPTY_FILE_SIZE 3
  30#define SQFS_STOP_READDIR 1
  31#define SQFS_EMPTY_DIR -1
  32/*
  33 * A directory entry object has a fixed length of 8 bytes, corresponding to its
  34 * first four members, plus the size of the entry name, which is equal to
  35 * 'entry_name' + 1 bytes.
  36 */
  37#define SQFS_ENTRY_BASE_LENGTH 8
  38/* Inode types */
  39#define SQFS_DIR_TYPE 1
  40#define SQFS_REG_TYPE 2
  41#define SQFS_SYMLINK_TYPE 3
  42#define SQFS_BLKDEV_TYPE 4
  43#define SQFS_CHRDEV_TYPE 5
  44#define SQFS_FIFO_TYPE 6
  45#define SQFS_SOCKET_TYPE 7
  46#define SQFS_LDIR_TYPE 8
  47#define SQFS_LREG_TYPE 9
  48#define SQFS_LSYMLINK_TYPE 10
  49#define SQFS_LBLKDEV_TYPE 11
  50#define SQFS_LCHRDEV_TYPE 12
  51#define SQFS_LFIFO_TYPE 13
  52#define SQFS_LSOCKET_TYPE 14
  53
  54struct squashfs_super_block {
  55        __le32 s_magic;
  56        __le32 inodes;
  57        __le32 mkfs_time;
  58        __le32 block_size;
  59        __le32 fragments;
  60        __le16 compression;
  61        __le16 block_log;
  62        __le16 flags;
  63        __le16 no_ids;
  64        __le16 s_major;
  65        __le16 s_minor;
  66        __le64 root_inode;
  67        __le64 bytes_used;
  68        __le64 id_table_start;
  69        __le64 xattr_id_table_start;
  70        __le64 inode_table_start;
  71        __le64 directory_table_start;
  72        __le64 fragment_table_start;
  73        __le64 export_table_start;
  74};
  75
  76struct squashfs_ctxt {
  77        struct disk_partition cur_part_info;
  78        struct blk_desc *cur_dev;
  79        struct squashfs_super_block *sblk;
  80#if IS_ENABLED(CONFIG_ZSTD)
  81        void *zstd_workspace;
  82#endif
  83};
  84
  85struct squashfs_directory_index {
  86        u32 index;
  87        u32 start;
  88        u32 size;
  89        char name[0];
  90};
  91
  92struct squashfs_base_inode {
  93        __le16 inode_type;
  94        __le16 mode;
  95        __le16 uid;
  96        __le16 guid;
  97        __le32 mtime;
  98        __le32 inode_number;
  99};
 100
 101struct squashfs_ipc_inode {
 102        __le16 inode_type;
 103        __le16 mode;
 104        __le16 uid;
 105        __le16 guid;
 106        __le32 mtime;
 107        __le32 inode_number;
 108        __le32 nlink;
 109};
 110
 111struct squashfs_lipc_inode {
 112        __le16 inode_type;
 113        __le16 mode;
 114        __le16 uid;
 115        __le16 guid;
 116        __le32 mtime;
 117        __le32 inode_number;
 118        __le32 nlink;
 119        __le32 xattr;
 120};
 121
 122struct squashfs_dev_inode {
 123        __le16 inode_type;
 124        __le16 mode;
 125        __le16 uid;
 126        __le16 guid;
 127        __le32 mtime;
 128        __le32 inode_number;
 129        __le32 nlink;
 130        __le32 rdev;
 131};
 132
 133struct squashfs_ldev_inode {
 134        __le16 inode_type;
 135        __le16 mode;
 136        __le16 uid;
 137        __le16 guid;
 138        __le32 mtime;
 139        __le32 inode_number;
 140        __le32 nlink;
 141        __le32 rdev;
 142        __le32 xattr;
 143};
 144
 145struct squashfs_symlink_inode {
 146        __le16 inode_type;
 147        __le16 mode;
 148        __le16 uid;
 149        __le16 guid;
 150        __le32 mtime;
 151        __le32 inode_number;
 152        __le32 nlink;
 153        __le32 symlink_size;
 154        char symlink[0];
 155};
 156
 157struct squashfs_reg_inode {
 158        __le16 inode_type;
 159        __le16 mode;
 160        __le16 uid;
 161        __le16 guid;
 162        __le32 mtime;
 163        __le32 inode_number;
 164        __le32 start_block;
 165        __le32 fragment;
 166        __le32 offset;
 167        __le32 file_size;
 168        __le32 block_list[0];
 169};
 170
 171struct squashfs_lreg_inode {
 172        __le16 inode_type;
 173        __le16 mode;
 174        __le16 uid;
 175        __le16 guid;
 176        __le32 mtime;
 177        __le32 inode_number;
 178        __le64 start_block;
 179        __le64 file_size;
 180        __le64 sparse;
 181        __le32 nlink;
 182        __le32 fragment;
 183        __le32 offset;
 184        __le32 xattr;
 185        __le32 block_list[0];
 186};
 187
 188struct squashfs_dir_inode {
 189        __le16 inode_type;
 190        __le16 mode;
 191        __le16 uid;
 192        __le16 guid;
 193        __le32 mtime;
 194        __le32 inode_number;
 195        __le32 start_block;
 196        __le32 nlink;
 197        __le16 file_size;
 198        __le16 offset;
 199        __le32 parent_inode;
 200};
 201
 202struct squashfs_ldir_inode {
 203        __le16 inode_type;
 204        __le16 mode;
 205        __le16 uid;
 206        __le16 guid;
 207        __le32 mtime;
 208        __le32 inode_number;
 209        __le32 nlink;
 210        __le32 file_size;
 211        __le32 start_block;
 212        __le32 parent_inode;
 213        __le16 i_count;
 214        __le16 offset;
 215        __le32 xattr;
 216        struct squashfs_directory_index index[0];
 217};
 218
 219union squashfs_inode {
 220        struct squashfs_base_inode *base;
 221        struct squashfs_dev_inode *dev;
 222        struct squashfs_ldev_inode *ldev;
 223        struct squashfs_symlink_inode *symlink;
 224        struct squashfs_reg_inode *reg;
 225        struct squashfs_lreg_inode *lreg;
 226        struct squashfs_dir_inode *dir;
 227        struct squashfs_ldir_inode *ldir;
 228        struct squashfs_ipc_inode *ipc;
 229        struct squashfs_lipc_inode *lipc;
 230};
 231
 232struct squashfs_directory_entry {
 233        u16 offset;
 234        s16 inode_offset;
 235        u16 type;
 236        u16 name_size;
 237        char name[0];
 238};
 239
 240struct squashfs_directory_header {
 241        u32 count;
 242        u32 start;
 243        u32 inode_number;
 244};
 245
 246struct squashfs_fragment_block_entry {
 247        u64 start;
 248        u32 size;
 249        u32 _unused;
 250};
 251
 252struct squashfs_dir_stream {
 253        struct fs_dir_stream fs_dirs;
 254        struct fs_dirent dentp;
 255        /*
 256         * 'size' is the uncompressed size of the entire listing, including
 257         * headers. 'entry_count' is the number of entries following a
 258         * specific header. Both variables are decremented in sqfs_readdir() so
 259         * the function knows when the end of the directory is reached.
 260         */
 261        size_t size;
 262        int entry_count;
 263        /* SquashFS structures */
 264        struct squashfs_directory_header *dir_header;
 265        struct squashfs_directory_entry *entry;
 266        /*
 267         * 'table' points to a position into the directory table. Both 'table'
 268         * and 'inode' are defined for the first time in sqfs_opendir().
 269         * 'table's value changes in sqfs_readdir().
 270         */
 271        unsigned char *table;
 272        union squashfs_inode i;
 273        struct squashfs_dir_inode i_dir;
 274        struct squashfs_ldir_inode i_ldir;
 275        /*
 276         * References to the tables' beginnings. They are assigned in
 277         * sqfs_opendir() and freed in sqfs_closedir().
 278         */
 279        unsigned char *inode_table;
 280        unsigned char *dir_table;
 281};
 282
 283struct squashfs_file_info {
 284        /* File size in bytes (uncompressed) */
 285        size_t size;
 286        /* Reference to list of data blocks's sizes */
 287        u32 *blk_sizes;
 288        /* Offset into the fragment block */
 289        u32 offset;
 290        /* Offset in which the data blocks begin */
 291        u64 start;
 292        /* Is file fragmented? */
 293        bool frag;
 294        /* Compressed fragment */
 295        bool comp;
 296};
 297
 298void *sqfs_find_inode(void *inode_table, int inode_number, __le32 inode_count,
 299                      __le32 block_size);
 300
 301int sqfs_dir_offset(void *dir_i, u32 *m_list, int m_count);
 302
 303int sqfs_read_metablock(unsigned char *file_mapping, int offset,
 304                        bool *compressed, u32 *data_size);
 305
 306bool sqfs_is_empty_dir(void *dir_i);
 307
 308bool sqfs_is_dir(u16 type);
 309
 310#endif /* SQFS_FILESYSTEM_H */
 311