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