]> git.ipfire.org Git - thirdparty/u-boot.git/blame - fs/erofs/internal.h
fs/erofs: Quieten test for filesystem presence
[thirdparty/u-boot.git] / fs / erofs / internal.h
CommitLineData
830613f8
HJ
1/* SPDX-License-Identifier: GPL-2.0+ */
2#ifndef __EROFS_INTERNAL_H
3#define __EROFS_INTERNAL_H
4
3a21e92f 5#include "linux/compat.h"
830613f8
HJ
6#define __packed __attribute__((__packed__))
7
8#include <linux/stat.h>
9#include <linux/bug.h>
10#include <linux/err.h>
11#include <linux/printk.h>
12#include <linux/log2.h>
13#include <inttypes.h>
14#include "erofs_fs.h"
15
16#define erofs_err(fmt, ...) \
17 pr_err(fmt "\n", ##__VA_ARGS__)
18
19#define erofs_info(fmt, ...) \
20 pr_info(fmt "\n", ##__VA_ARGS__)
21
22#define erofs_dbg(fmt, ...) \
23 pr_debug(fmt "\n", ##__VA_ARGS__)
24
25#define DBG_BUGON(condition) BUG_ON(condition)
26
27/* no obvious reason to support explicit PAGE_SIZE != 4096 for now */
28#if PAGE_SIZE != 4096
29#error incompatible PAGE_SIZE is already defined
30#endif
31
32#define PAGE_MASK (~(PAGE_SIZE - 1))
33
3a21e92f
YZ
34#ifndef EROFS_MAX_BLOCK_SIZE
35#define EROFS_MAX_BLOCK_SIZE PAGE_SIZE
36#endif
830613f8
HJ
37
38#define EROFS_ISLOTBITS 5
39#define EROFS_SLOTSIZE (1U << EROFS_ISLOTBITS)
40
41typedef u64 erofs_off_t;
42typedef u64 erofs_nid_t;
43/* data type for filesystem-wide blocks number */
44typedef u32 erofs_blk_t;
45
46#define NULL_ADDR ((unsigned int)-1)
47#define NULL_ADDR_UL ((unsigned long)-1)
48
3a21e92f
YZ
49/* global sbi */
50extern struct erofs_sb_info sbi;
51
52#define erofs_blksiz() (1u << sbi.blkszbits)
53#define erofs_blknr(addr) ((addr) >> sbi.blkszbits)
54#define erofs_blkoff(addr) ((addr) & (erofs_blksiz() - 1))
55#define erofs_pos(nr) ((erofs_off_t)(nr) << sbi.blkszbits)
830613f8 56
3a21e92f 57#define BLK_ROUND_UP(addr) DIV_ROUND_UP(addr, 1u << sbi.blkszbits)
830613f8
HJ
58
59struct erofs_buffer_head;
60
61struct erofs_device_info {
62 u32 blocks;
63 u32 mapped_blkaddr;
64};
65
3a21e92f
YZ
66#define EROFS_PACKED_NID_UNALLOCATED -1
67
830613f8
HJ
68struct erofs_sb_info {
69 struct erofs_device_info *devs;
70
71 u64 total_blocks;
72 u64 primarydevice_blocks;
73
74 erofs_blk_t meta_blkaddr;
75 erofs_blk_t xattr_blkaddr;
76
77 u32 feature_compat;
78 u32 feature_incompat;
79 u64 build_time;
80 u32 build_time_nsec;
81
82 unsigned char islotbits;
3a21e92f 83 unsigned char blkszbits;
830613f8
HJ
84
85 /* what we really care is nid, rather than ino.. */
86 erofs_nid_t root_nid;
87 /* used for statfs, f_files - f_favail */
88 u64 inos;
89
90 u8 uuid[16];
3a21e92f 91 char volume_name[16];
830613f8
HJ
92
93 u16 available_compr_algs;
94 u16 lz4_max_distance;
3a21e92f 95
830613f8
HJ
96 u32 checksum;
97 u16 extra_devices;
98 union {
99 u16 devt_slotoff; /* used for mkfs */
100 u16 device_id_mask; /* used for others */
101 };
3a21e92f
YZ
102 erofs_nid_t packed_nid;
103
104 u32 xattr_prefix_start;
105 u8 xattr_prefix_count;
830613f8
HJ
106};
107
830613f8
HJ
108static inline erofs_off_t iloc(erofs_nid_t nid)
109{
3a21e92f 110 return erofs_pos(sbi.meta_blkaddr) + (nid << sbi.islotbits);
830613f8
HJ
111}
112
113#define EROFS_FEATURE_FUNCS(name, compat, feature) \
114static inline bool erofs_sb_has_##name(void) \
115{ \
116 return sbi.feature_##compat & EROFS_FEATURE_##feature; \
117} \
118static inline void erofs_sb_set_##name(void) \
119{ \
120 sbi.feature_##compat |= EROFS_FEATURE_##feature; \
121} \
122static inline void erofs_sb_clear_##name(void) \
123{ \
124 sbi.feature_##compat &= ~EROFS_FEATURE_##feature; \
125}
126
3a21e92f 127EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_ZERO_PADDING)
830613f8
HJ
128EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS)
129EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER)
130EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE)
131EROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE)
3a21e92f
YZ
132EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING)
133EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
134EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
135EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
830613f8
HJ
136EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
137
138#define EROFS_I_EA_INITED (1 << 0)
139#define EROFS_I_Z_INITED (1 << 1)
140
141struct erofs_inode {
142 struct list_head i_hash, i_subdirs, i_xattrs;
143
144 union {
145 /* (erofsfuse) runtime flags */
146 unsigned int flags;
147 /* (mkfs.erofs) device ID containing source file */
148 u32 dev;
3a21e92f
YZ
149 /* (mkfs.erofs) queued sub-directories blocking dump */
150 u32 subdirs_queued;
830613f8
HJ
151 };
152 unsigned int i_count;
153 struct erofs_inode *i_parent;
154
155 umode_t i_mode;
156 erofs_off_t i_size;
157
158 u64 i_ino[2];
159 u32 i_uid;
160 u32 i_gid;
3a21e92f
YZ
161 u64 i_mtime;
162 u32 i_mtime_nsec;
830613f8
HJ
163 u32 i_nlink;
164
165 union {
166 u32 i_blkaddr;
167 u32 i_blocks;
168 u32 i_rdev;
169 struct {
170 unsigned short chunkformat;
171 unsigned char chunkbits;
172 };
173 } u;
174
3a21e92f
YZ
175 char *i_srcpath;
176
830613f8
HJ
177 unsigned char datalayout;
178 unsigned char inode_isize;
179 /* inline tail-end packing size */
180 unsigned short idata_size;
3a21e92f
YZ
181 bool compressed_idata;
182 bool lazy_tailblock;
830613f8
HJ
183
184 unsigned int xattr_isize;
185 unsigned int extent_isize;
186
3a21e92f
YZ
187 unsigned int xattr_shared_count;
188 unsigned int *xattr_shared_xattrs;
189
830613f8
HJ
190 erofs_nid_t nid;
191 struct erofs_buffer_head *bh;
192 struct erofs_buffer_head *bh_inline, *bh_data;
193
194 void *idata;
195
3a21e92f
YZ
196 /* (ztailpacking) in order to recover uncompressed EOF data */
197 void *eof_tailraw;
198 unsigned int eof_tailrawsize;
199
830613f8
HJ
200 union {
201 void *compressmeta;
202 void *chunkindexes;
203 struct {
204 uint16_t z_advise;
205 uint8_t z_algorithmtype[2];
206 uint8_t z_logical_clusterbits;
207 uint8_t z_physical_clusterblks;
3a21e92f
YZ
208 uint64_t z_tailextent_headlcn;
209 unsigned int z_idataoff;
210#define z_idata_size idata_size
830613f8
HJ
211 };
212 };
3a21e92f
YZ
213 uint64_t capabilities;
214 erofs_off_t fragmentoff;
215 unsigned int fragment_size;
830613f8
HJ
216};
217
218static inline bool is_inode_layout_compression(struct erofs_inode *inode)
219{
220 return erofs_inode_is_data_compressed(inode->datalayout);
221}
222
223static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
224 unsigned int bits)
225{
226 return (value >> bit) & ((1 << bits) - 1);
227}
228
229static inline unsigned int erofs_inode_version(unsigned int value)
230{
231 return erofs_bitrange(value, EROFS_I_VERSION_BIT,
232 EROFS_I_VERSION_BITS);
233}
234
235static inline unsigned int erofs_inode_datalayout(unsigned int value)
236{
237 return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
238 EROFS_I_DATALAYOUT_BITS);
239}
240
241#define IS_ROOT(x) ((x) == (x)->i_parent)
242
243struct erofs_dentry {
244 struct list_head d_child; /* child of parent list */
245
246 unsigned int type;
247 char name[EROFS_NAME_LEN];
248 union {
249 struct erofs_inode *inode;
250 erofs_nid_t nid;
251 };
252};
253
3a21e92f
YZ
254static inline bool is_dot_dotdot_len(const char *name, unsigned int len)
255{
256 if (len >= 1 && name[0] != '.')
257 return false;
258
259 return len == 1 || (len == 2 && name[1] == '.');
260}
261
830613f8
HJ
262static inline bool is_dot_dotdot(const char *name)
263{
264 if (name[0] != '.')
265 return false;
266
267 return name[1] == '\0' || (name[1] == '.' && name[2] == '\0');
268}
269
270enum {
271 BH_Meta,
272 BH_Mapped,
273 BH_Encoded,
274 BH_FullMapped,
3a21e92f
YZ
275 BH_Fragment,
276 BH_Partialref,
830613f8
HJ
277};
278
279/* Has a disk mapping */
280#define EROFS_MAP_MAPPED (1 << BH_Mapped)
281/* Located in metadata (could be copied from bd_inode) */
282#define EROFS_MAP_META (1 << BH_Meta)
283/* The extent is encoded */
284#define EROFS_MAP_ENCODED (1 << BH_Encoded)
285/* The length of extent is full */
286#define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped)
3a21e92f
YZ
287/* Located in the special packed inode */
288#define EROFS_MAP_FRAGMENT (1 << BH_Fragment)
289/* The extent refers to partial decompressed data */
290#define EROFS_MAP_PARTIAL_REF (1 << BH_Partialref)
830613f8
HJ
291
292struct erofs_map_blocks {
3a21e92f 293 char mpage[EROFS_MAX_BLOCK_SIZE];
830613f8
HJ
294
295 erofs_off_t m_pa, m_la;
296 u64 m_plen, m_llen;
297
298 unsigned short m_deviceid;
299 char m_algorithmformat;
300 unsigned int m_flags;
301 erofs_blk_t index;
302};
303
304/*
305 * Used to get the exact decompressed length, e.g. fiemap (consider lookback
306 * approach instead if possible since it's more metadata lightweight.)
307 */
308#define EROFS_GET_BLOCKS_FIEMAP 0x0002
3a21e92f
YZ
309/* Used to map tail extent for tailpacking inline or fragment pcluster */
310#define EROFS_GET_BLOCKS_FINDTAIL 0x0008
830613f8
HJ
311
312enum {
313 Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
3a21e92f 314 Z_EROFS_COMPRESSION_INTERLACED,
830613f8
HJ
315 Z_EROFS_COMPRESSION_RUNTIME_MAX
316};
317
318struct erofs_map_dev {
319 erofs_off_t m_pa;
320 unsigned int m_deviceid;
321};
322
323/* fs.c */
324int erofs_blk_read(void *buf, erofs_blk_t start, u32 nblocks);
325int erofs_dev_read(int device_id, void *buf, u64 offset, size_t len);
326
327/* super.c */
328int erofs_read_superblock(void);
3a21e92f 329void erofs_put_super(void);
830613f8
HJ
330
331/* namei.c */
332int erofs_read_inode_from_disk(struct erofs_inode *vi);
333int erofs_ilookup(const char *path, struct erofs_inode *vi);
334int erofs_read_inode_from_disk(struct erofs_inode *vi);
335
336/* data.c */
337int erofs_pread(struct erofs_inode *inode, char *buf,
338 erofs_off_t count, erofs_off_t offset);
3a21e92f
YZ
339int erofs_map_blocks(struct erofs_inode *inode, struct erofs_map_blocks *map,
340 int flags);
341int erofs_map_dev(struct erofs_map_dev *map);
342int erofs_read_one_data(struct erofs_map_blocks *map, char *buffer, u64 offset,
343 size_t len);
344int z_erofs_read_one_data(struct erofs_inode *inode,
345 struct erofs_map_blocks *map, char *raw, char *buffer,
346 erofs_off_t skip, erofs_off_t length, bool trimmed);
347
348static inline int erofs_get_occupied_size(const struct erofs_inode *inode,
349 erofs_off_t *size)
350{
351 *size = 0;
352 switch (inode->datalayout) {
353 case EROFS_INODE_FLAT_INLINE:
354 case EROFS_INODE_FLAT_PLAIN:
355 case EROFS_INODE_CHUNK_BASED:
356 *size = inode->i_size;
357 break;
358 case EROFS_INODE_COMPRESSED_FULL:
359 case EROFS_INODE_COMPRESSED_COMPACT:
360 *size = inode->u.i_blocks * erofs_blksiz();
361 break;
362 default:
363 return -EOPNOTSUPP;
364 }
365 return 0;
366}
367
368/* data.c */
369int erofs_getxattr(struct erofs_inode *vi, const char *name, char *buffer,
370 size_t buffer_size);
371int erofs_listxattr(struct erofs_inode *vi, char *buffer, size_t buffer_size);
372
830613f8
HJ
373/* zmap.c */
374int z_erofs_fill_inode(struct erofs_inode *vi);
375int z_erofs_map_blocks_iter(struct erofs_inode *vi,
376 struct erofs_map_blocks *map, int flags);
377
378#ifdef EUCLEAN
379#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
380#else
381#define EFSCORRUPTED EIO
382#endif
383
384#define CRC32C_POLY_LE 0x82F63B78
385static inline u32 erofs_crc32c(u32 crc, const u8 *in, size_t len)
386{
387 int i;
388
389 while (len--) {
390 crc ^= *in++;
391 for (i = 0; i < 8; i++)
392 crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
393 }
394 return crc;
395}
396
397#endif