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 54 struct 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 76 struct 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 85 struct squashfs_directory_index { 86 u32 index; 87 u32 start; 88 u32 size; 89 char name[0]; 90 }; 91 92 struct 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 101 struct 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 111 struct 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 122 struct 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 133 struct 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 145 struct 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 157 struct 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 171 struct 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 188 struct 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 202 struct 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 219 union 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 232 struct squashfs_directory_entry { 233 u16 offset; 234 u16 inode_offset; 235 u16 type; 236 u16 name_size; 237 char name[0]; 238 }; 239 240 struct squashfs_directory_header { 241 u32 count; 242 u32 start; 243 u32 inode_number; 244 }; 245 246 struct squashfs_fragment_block_entry { 247 u64 start; 248 u32 size; 249 u32 _unused; 250 }; 251 252 struct 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 283 struct 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 298 void *sqfs_find_inode(void *inode_table, int inode_number, __le32 inode_count, 299 __le32 block_size); 300 301 int sqfs_dir_offset(void *dir_i, u32 *m_list, int m_count); 302 303 int sqfs_read_metablock(unsigned char *file_mapping, int offset, 304 bool *compressed, u32 *data_size); 305 306 bool sqfs_is_empty_dir(void *dir_i); 307 308 bool sqfs_is_dir(u16 type); 309 310 #endif /* SQFS_FILESYSTEM_H */ 311