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