1 /* SPDX-License-Identifier: GPL-2.0+ */
2 #ifndef __EROFS_INTERNAL_H
3 #define __EROFS_INTERNAL_H
4 
5 #include "linux/compat.h"
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 
34 #ifndef EROFS_MAX_BLOCK_SIZE
35 #define EROFS_MAX_BLOCK_SIZE	PAGE_SIZE
36 #endif
37 
38 #define EROFS_ISLOTBITS		5
39 #define EROFS_SLOTSIZE		(1U << EROFS_ISLOTBITS)
40 
41 typedef u64 erofs_off_t;
42 typedef u64 erofs_nid_t;
43 /* data type for filesystem-wide blocks number */
44 typedef u32 erofs_blk_t;
45 
46 #define NULL_ADDR	((unsigned int)-1)
47 #define NULL_ADDR_UL	((unsigned long)-1)
48 
49 /* global sbi */
50 extern 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)
56 
57 #define BLK_ROUND_UP(addr)	DIV_ROUND_UP(addr, 1u << sbi.blkszbits)
58 
59 struct erofs_buffer_head;
60 
61 struct erofs_device_info {
62 	u32 blocks;
63 	u32 mapped_blkaddr;
64 };
65 
66 #define EROFS_PACKED_NID_UNALLOCATED	-1
67 
68 struct 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;
83 	unsigned char blkszbits;
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];
91 	char volume_name[16];
92 
93 	u16 available_compr_algs;
94 	u16 lz4_max_distance;
95 
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 	};
102 	erofs_nid_t packed_nid;
103 
104 	u32 xattr_prefix_start;
105 	u8 xattr_prefix_count;
106 };
107 
iloc(erofs_nid_t nid)108 static inline erofs_off_t iloc(erofs_nid_t nid)
109 {
110 	return erofs_pos(sbi.meta_blkaddr) + (nid << sbi.islotbits);
111 }
112 
113 #define EROFS_FEATURE_FUNCS(name, compat, feature) \
114 static inline bool erofs_sb_has_##name(void) \
115 { \
116 	return sbi.feature_##compat & EROFS_FEATURE_##feature; \
117 } \
118 static inline void erofs_sb_set_##name(void) \
119 { \
120 	sbi.feature_##compat |= EROFS_FEATURE_##feature; \
121 } \
122 static inline void erofs_sb_clear_##name(void) \
123 { \
124 	sbi.feature_##compat &= ~EROFS_FEATURE_##feature; \
125 }
126 
127 EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_ZERO_PADDING)
128 EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS)
129 EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER)
130 EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE)
131 EROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE)
132 EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING)
133 EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
134 EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
135 EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
136 EROFS_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 
141 struct 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;
149 		/* (mkfs.erofs) queued sub-directories blocking dump */
150 		u32 subdirs_queued;
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;
161 	u64 i_mtime;
162 	u32 i_mtime_nsec;
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 
175 	char *i_srcpath;
176 
177 	unsigned char datalayout;
178 	unsigned char inode_isize;
179 	/* inline tail-end packing size */
180 	unsigned short idata_size;
181 	bool compressed_idata;
182 	bool lazy_tailblock;
183 
184 	unsigned int xattr_isize;
185 	unsigned int extent_isize;
186 
187 	unsigned int xattr_shared_count;
188 	unsigned int *xattr_shared_xattrs;
189 
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 
196 	/* (ztailpacking) in order to recover uncompressed EOF data */
197 	void *eof_tailraw;
198 	unsigned int eof_tailrawsize;
199 
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;
208 			uint64_t z_tailextent_headlcn;
209 			unsigned int    z_idataoff;
210 #define z_idata_size	idata_size
211 		};
212 	};
213 	uint64_t capabilities;
214 	erofs_off_t fragmentoff;
215 	unsigned int fragment_size;
216 };
217 
is_inode_layout_compression(struct erofs_inode * inode)218 static inline bool is_inode_layout_compression(struct erofs_inode *inode)
219 {
220 	return erofs_inode_is_data_compressed(inode->datalayout);
221 }
222 
erofs_bitrange(unsigned int value,unsigned int bit,unsigned int bits)223 static 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 
erofs_inode_version(unsigned int value)229 static 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 
erofs_inode_datalayout(unsigned int value)235 static 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 
243 struct 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 
is_dot_dotdot_len(const char * name,unsigned int len)254 static 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 
is_dot_dotdot(const char * name)262 static 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 
270 enum {
271 	BH_Meta,
272 	BH_Mapped,
273 	BH_Encoded,
274 	BH_FullMapped,
275 	BH_Fragment,
276 	BH_Partialref,
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)
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)
291 
292 struct erofs_map_blocks {
293 	char mpage[EROFS_MAX_BLOCK_SIZE];
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
309 /* Used to map tail extent for tailpacking inline or fragment pcluster */
310 #define EROFS_GET_BLOCKS_FINDTAIL	0x0008
311 
312 enum {
313 	Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
314 	Z_EROFS_COMPRESSION_INTERLACED,
315 	Z_EROFS_COMPRESSION_RUNTIME_MAX
316 };
317 
318 struct erofs_map_dev {
319 	erofs_off_t m_pa;
320 	unsigned int m_deviceid;
321 };
322 
323 /* fs.c */
324 int erofs_blk_read(void *buf, erofs_blk_t start, u32 nblocks);
325 int erofs_dev_read(int device_id, void *buf, u64 offset, size_t len);
326 
327 /* super.c */
328 int erofs_read_superblock(void);
329 void erofs_put_super(void);
330 
331 /* namei.c */
332 int erofs_read_inode_from_disk(struct erofs_inode *vi);
333 int erofs_ilookup(const char *path, struct erofs_inode *vi);
334 int erofs_read_inode_from_disk(struct erofs_inode *vi);
335 
336 /* data.c */
337 int erofs_pread(struct erofs_inode *inode, char *buf,
338 		erofs_off_t count, erofs_off_t offset);
339 int erofs_map_blocks(struct erofs_inode *inode, struct erofs_map_blocks *map,
340 		     int flags);
341 int erofs_map_dev(struct erofs_map_dev *map);
342 int erofs_read_one_data(struct erofs_map_blocks *map, char *buffer, u64 offset,
343 			size_t len);
344 int 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 
erofs_get_occupied_size(const struct erofs_inode * inode,erofs_off_t * size)348 static 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 */
369 int erofs_getxattr(struct erofs_inode *vi, const char *name, char *buffer,
370 		   size_t buffer_size);
371 int erofs_listxattr(struct erofs_inode *vi, char *buffer, size_t buffer_size);
372 
373 /* zmap.c */
374 int z_erofs_fill_inode(struct erofs_inode *vi);
375 int 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
erofs_crc32c(u32 crc,const u8 * in,size_t len)385 static 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
398