aboutsummaryrefslogtreecommitdiff
path: root/include/sqfs/super.h
blob: d275ec100560e844d8c73d8e8d418af7c9b39bb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
 * super.h - This file is part of libsquashfs
 *
 * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#ifndef SQFS_SUPER_H
#define SQFS_SUPER_H

#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.
	 */
	sqfs_u32 magic;

	/**
	 * @brief Total number of inodes.
	 */
	sqfs_u32 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).
	 */
	sqfs_u32 modification_time;

	/**
	 * @brief The data block size in bytes.
	 *
	 * Must be a power of 2, no less than 4k and not larger than 1M.
	 */
	sqfs_u32 block_size;

	/**
	 * @brief The number of fragment blocks in the data area.
	 */
	sqfs_u32 fragment_entry_count;

	/**
	 * @brief Identifies the compressor that has been used.
	 *
	 * Valid identifiers are in the @ref SQFS_COMPRESSOR enum.
	 */
	sqfs_u16 compression_id;

	/**
	 * @brief The log2 of the block_size field for sanity checking
	 *
	 * Must be no less than 12 and not larger than 20.
	 */
	sqfs_u16 block_log;

	/**
	 * @brief A combination of @ref SQFS_SUPER_FLAGS flags
	 *
	 * Most of the flags that can be set here are informative only.
	 */
	sqfs_u16 flags;

	/**
	 * @brief The total number of unique user or group IDs.
	 */
	sqfs_u16 id_count;

	/**
	 * @brief Must be @ref SQFS_VERSION_MAJOR
	 */
	sqfs_u16 version_major;

	/**
	 * @brief Must be @ref SQFS_VERSION_MINOR
	 */
	sqfs_u16 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.
	 */
	sqfs_u64 root_inode_ref;

	/**
	 * @brief Total size of the file system in bytes, not counting padding
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 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.
	 */
	sqfs_u64 export_table_start;
};

/**
 * @enum 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,
	SQFS_COMP_LZO = 3,
	SQFS_COMP_XZ = 4,
	SQFS_COMP_LZ4 = 5,
	SQFS_COMP_ZSTD = 6,

	SQFS_COMP_MIN = 1,
	SQFS_COMP_MAX = 6,
} SQFS_COMPRESSOR;

/**
 * @enum 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,
} SQFS_SUPER_FLAGS;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @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 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,
			     sqfs_u32 mtime,
			     SQFS_COMPRESSOR compressor);

/**
 * @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 SQFS_ERROR value if one of the
 *         fields does not hold a valid value.
 */
SQFS_API int sqfs_super_write(const sqfs_super_t *super, sqfs_file_t *file);

/**
 * @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 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
}
#endif

#endif /* SQFS_SUPER_H */