1 /* SPDX-License-Identifier: GPL-2.0+ */
2 #ifndef __EROFS_INTERNAL_H
3 #define __EROFS_INTERNAL_H
4 
5 #define __packed __attribute__((__packed__))
6 
7 #include <linux/stat.h>
8 #include <linux/bug.h>
9 #include <linux/err.h>
10 #include <linux/printk.h>
11 #include <linux/log2.h>
12 #include <inttypes.h>
13 #include "erofs_fs.h"
14 
15 #define erofs_err(fmt, ...)	\
16 	pr_err(fmt "\n", ##__VA_ARGS__)
17 
18 #define erofs_info(fmt, ...)	\
19 	pr_info(fmt "\n", ##__VA_ARGS__)
20 
21 #define erofs_dbg(fmt, ...)	\
22 	pr_debug(fmt "\n", ##__VA_ARGS__)
23 
24 #define DBG_BUGON(condition)	BUG_ON(condition)
25 
26 /* no obvious reason to support explicit PAGE_SIZE != 4096 for now */
27 #if PAGE_SIZE != 4096
28 #error incompatible PAGE_SIZE is already defined
29 #endif
30 
31 #define PAGE_MASK		(~(PAGE_SIZE - 1))
32 
33 #define LOG_BLOCK_SIZE          (12)
34 #define EROFS_BLKSIZ            (1U << LOG_BLOCK_SIZE)
35 
36 #define EROFS_ISLOTBITS		5
37 #define EROFS_SLOTSIZE		(1U << EROFS_ISLOTBITS)
38 
39 typedef u64 erofs_off_t;
40 typedef u64 erofs_nid_t;
41 /* data type for filesystem-wide blocks number */
42 typedef u32 erofs_blk_t;
43 
44 #define NULL_ADDR	((unsigned int)-1)
45 #define NULL_ADDR_UL	((unsigned long)-1)
46 
47 #define erofs_blknr(addr)       ((addr) / EROFS_BLKSIZ)
48 #define erofs_blkoff(addr)      ((addr) % EROFS_BLKSIZ)
49 #define blknr_to_addr(nr)       ((erofs_off_t)(nr) * EROFS_BLKSIZ)
50 
51 #define BLK_ROUND_UP(addr)	DIV_ROUND_UP(addr, EROFS_BLKSIZ)
52 
53 struct erofs_buffer_head;
54 
55 struct erofs_device_info {
56 	u32 blocks;
57 	u32 mapped_blkaddr;
58 };
59 
60 struct erofs_sb_info {
61 	struct erofs_device_info *devs;
62 
63 	u64 total_blocks;
64 	u64 primarydevice_blocks;
65 
66 	erofs_blk_t meta_blkaddr;
67 	erofs_blk_t xattr_blkaddr;
68 
69 	u32 feature_compat;
70 	u32 feature_incompat;
71 	u64 build_time;
72 	u32 build_time_nsec;
73 
74 	unsigned char islotbits;
75 
76 	/* what we really care is nid, rather than ino.. */
77 	erofs_nid_t root_nid;
78 	/* used for statfs, f_files - f_favail */
79 	u64 inos;
80 
81 	u8 uuid[16];
82 
83 	u16 available_compr_algs;
84 	u16 lz4_max_distance;
85 	u32 checksum;
86 	u16 extra_devices;
87 	union {
88 		u16 devt_slotoff;		/* used for mkfs */
89 		u16 device_id_mask;		/* used for others */
90 	};
91 };
92 
93 /* global sbi */
94 extern struct erofs_sb_info sbi;
95 
iloc(erofs_nid_t nid)96 static inline erofs_off_t iloc(erofs_nid_t nid)
97 {
98 	return blknr_to_addr(sbi.meta_blkaddr) + (nid << sbi.islotbits);
99 }
100 
101 #define EROFS_FEATURE_FUNCS(name, compat, feature) \
102 static inline bool erofs_sb_has_##name(void) \
103 { \
104 	return sbi.feature_##compat & EROFS_FEATURE_##feature; \
105 } \
106 static inline void erofs_sb_set_##name(void) \
107 { \
108 	sbi.feature_##compat |= EROFS_FEATURE_##feature; \
109 } \
110 static inline void erofs_sb_clear_##name(void) \
111 { \
112 	sbi.feature_##compat &= ~EROFS_FEATURE_##feature; \
113 }
114 
115 EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING)
116 EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS)
117 EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER)
118 EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE)
119 EROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE)
120 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
121 
122 #define EROFS_I_EA_INITED	(1 << 0)
123 #define EROFS_I_Z_INITED	(1 << 1)
124 
125 struct erofs_inode {
126 	struct list_head i_hash, i_subdirs, i_xattrs;
127 
128 	union {
129 		/* (erofsfuse) runtime flags */
130 		unsigned int flags;
131 		/* (mkfs.erofs) device ID containing source file */
132 		u32 dev;
133 	};
134 	unsigned int i_count;
135 	struct erofs_inode *i_parent;
136 
137 	umode_t i_mode;
138 	erofs_off_t i_size;
139 
140 	u64 i_ino[2];
141 	u32 i_uid;
142 	u32 i_gid;
143 	u64 i_ctime;
144 	u32 i_ctime_nsec;
145 	u32 i_nlink;
146 
147 	union {
148 		u32 i_blkaddr;
149 		u32 i_blocks;
150 		u32 i_rdev;
151 		struct {
152 			unsigned short	chunkformat;
153 			unsigned char	chunkbits;
154 		};
155 	} u;
156 
157 	unsigned char datalayout;
158 	unsigned char inode_isize;
159 	/* inline tail-end packing size */
160 	unsigned short idata_size;
161 
162 	unsigned int xattr_isize;
163 	unsigned int extent_isize;
164 
165 	erofs_nid_t nid;
166 	struct erofs_buffer_head *bh;
167 	struct erofs_buffer_head *bh_inline, *bh_data;
168 
169 	void *idata;
170 
171 	union {
172 		void *compressmeta;
173 		void *chunkindexes;
174 		struct {
175 			uint16_t z_advise;
176 			uint8_t  z_algorithmtype[2];
177 			uint8_t  z_logical_clusterbits;
178 			uint8_t  z_physical_clusterblks;
179 		};
180 	};
181 };
182 
is_inode_layout_compression(struct erofs_inode * inode)183 static inline bool is_inode_layout_compression(struct erofs_inode *inode)
184 {
185 	return erofs_inode_is_data_compressed(inode->datalayout);
186 }
187 
erofs_bitrange(unsigned int value,unsigned int bit,unsigned int bits)188 static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
189 					  unsigned int bits)
190 {
191 	return (value >> bit) & ((1 << bits) - 1);
192 }
193 
erofs_inode_version(unsigned int value)194 static inline unsigned int erofs_inode_version(unsigned int value)
195 {
196 	return erofs_bitrange(value, EROFS_I_VERSION_BIT,
197 			      EROFS_I_VERSION_BITS);
198 }
199 
erofs_inode_datalayout(unsigned int value)200 static inline unsigned int erofs_inode_datalayout(unsigned int value)
201 {
202 	return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
203 			      EROFS_I_DATALAYOUT_BITS);
204 }
205 
206 #define IS_ROOT(x)	((x) == (x)->i_parent)
207 
208 struct erofs_dentry {
209 	struct list_head d_child;	/* child of parent list */
210 
211 	unsigned int type;
212 	char name[EROFS_NAME_LEN];
213 	union {
214 		struct erofs_inode *inode;
215 		erofs_nid_t nid;
216 	};
217 };
218 
is_dot_dotdot(const char * name)219 static inline bool is_dot_dotdot(const char *name)
220 {
221 	if (name[0] != '.')
222 		return false;
223 
224 	return name[1] == '\0' || (name[1] == '.' && name[2] == '\0');
225 }
226 
227 enum {
228 	BH_Meta,
229 	BH_Mapped,
230 	BH_Encoded,
231 	BH_FullMapped,
232 };
233 
234 /* Has a disk mapping */
235 #define EROFS_MAP_MAPPED	(1 << BH_Mapped)
236 /* Located in metadata (could be copied from bd_inode) */
237 #define EROFS_MAP_META		(1 << BH_Meta)
238 /* The extent is encoded */
239 #define EROFS_MAP_ENCODED	(1 << BH_Encoded)
240 /* The length of extent is full */
241 #define EROFS_MAP_FULL_MAPPED	(1 << BH_FullMapped)
242 
243 struct erofs_map_blocks {
244 	char mpage[EROFS_BLKSIZ];
245 
246 	erofs_off_t m_pa, m_la;
247 	u64 m_plen, m_llen;
248 
249 	unsigned short m_deviceid;
250 	char m_algorithmformat;
251 	unsigned int m_flags;
252 	erofs_blk_t index;
253 };
254 
255 /*
256  * Used to get the exact decompressed length, e.g. fiemap (consider lookback
257  * approach instead if possible since it's more metadata lightweight.)
258  */
259 #define EROFS_GET_BLOCKS_FIEMAP	0x0002
260 
261 enum {
262 	Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
263 	Z_EROFS_COMPRESSION_RUNTIME_MAX
264 };
265 
266 struct erofs_map_dev {
267 	erofs_off_t m_pa;
268 	unsigned int m_deviceid;
269 };
270 
271 /* fs.c */
272 int erofs_blk_read(void *buf, erofs_blk_t start, u32 nblocks);
273 int erofs_dev_read(int device_id, void *buf, u64 offset, size_t len);
274 
275 /* super.c */
276 int erofs_read_superblock(void);
277 
278 /* namei.c */
279 int erofs_read_inode_from_disk(struct erofs_inode *vi);
280 int erofs_ilookup(const char *path, struct erofs_inode *vi);
281 int erofs_read_inode_from_disk(struct erofs_inode *vi);
282 
283 /* data.c */
284 int erofs_pread(struct erofs_inode *inode, char *buf,
285 		erofs_off_t count, erofs_off_t offset);
286 int erofs_map_blocks(struct erofs_inode *inode,
287 		     struct erofs_map_blocks *map, int flags);
288 int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map);
289 /* zmap.c */
290 int z_erofs_fill_inode(struct erofs_inode *vi);
291 int z_erofs_map_blocks_iter(struct erofs_inode *vi,
292 			    struct erofs_map_blocks *map, int flags);
293 
294 #ifdef EUCLEAN
295 #define EFSCORRUPTED	EUCLEAN		/* Filesystem is corrupted */
296 #else
297 #define EFSCORRUPTED	EIO
298 #endif
299 
300 #define CRC32C_POLY_LE	0x82F63B78
erofs_crc32c(u32 crc,const u8 * in,size_t len)301 static inline u32 erofs_crc32c(u32 crc, const u8 *in, size_t len)
302 {
303 	int i;
304 
305 	while (len--) {
306 		crc ^= *in++;
307 		for (i = 0; i < 8; i++)
308 			crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
309 	}
310 	return crc;
311 }
312 
313 #endif
314