1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * erofs-utils/include/erofs/internal.h
4 *
5 * Copyright (C) 2019 HUAWEI, Inc.
6 * http://www.huawei.com/
7 * Created by Gao Xiang <gaoxiang25@huawei.com>
8 */
9 #ifndef __EROFS_INTERNAL_H
10 #define __EROFS_INTERNAL_H
11
12 #include "list.h"
13 #include "err.h"
14
15 typedef unsigned short umode_t;
16
17 #define __packed __attribute__((__packed__))
18
19 #include "erofs_fs.h"
20 #include <fcntl.h>
21
22 #ifndef PATH_MAX
23 #define PATH_MAX 4096 /* # chars in a path name including nul */
24 #endif
25
26 #ifndef PAGE_SHIFT
27 #define PAGE_SHIFT (12)
28 #endif
29
30 #ifndef PAGE_SIZE
31 #define PAGE_SIZE (1U << PAGE_SHIFT)
32 #endif
33
34 /* no obvious reason to support explicit PAGE_SIZE != 4096 for now */
35 #if PAGE_SIZE != 4096
36 #error incompatible PAGE_SIZE is already defined
37 #endif
38
39 #define PAGE_MASK (~(PAGE_SIZE-1))
40
41 #define LOG_BLOCK_SIZE (12)
42 #define EROFS_BLKSIZ (1U << LOG_BLOCK_SIZE)
43
44 #define EROFS_ISLOTBITS 5
45 #define EROFS_SLOTSIZE (1U << EROFS_ISLOTBITS)
46
47 typedef u64 erofs_off_t;
48 typedef u64 erofs_nid_t;
49 /* data type for filesystem-wide blocks number */
50 typedef u32 erofs_blk_t;
51
52 #define NULL_ADDR ((unsigned int)-1)
53 #define NULL_ADDR_UL ((unsigned long)-1)
54
55 #define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ)
56 #define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ)
57 #define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ)
58
59 #define BLK_ROUND_UP(addr) DIV_ROUND_UP(addr, EROFS_BLKSIZ)
60
61 struct erofs_buffer_head;
62
63 struct erofs_sb_info {
64 u64 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
84 /* global sbi */
85 extern struct erofs_sb_info sbi;
86
iloc(erofs_nid_t nid)87 static inline erofs_off_t iloc(erofs_nid_t nid)
88 {
89 return blknr_to_addr(sbi.meta_blkaddr) + (nid << sbi.islotbits);
90 }
91
92 #define EROFS_FEATURE_FUNCS(name, compat, feature) \
93 static inline bool erofs_sb_has_##name(void) \
94 { \
95 return sbi.feature_##compat & EROFS_FEATURE_##feature; \
96 } \
97 static inline void erofs_sb_set_##name(void) \
98 { \
99 sbi.feature_##compat |= EROFS_FEATURE_##feature; \
100 } \
101 static inline void erofs_sb_clear_##name(void) \
102 { \
103 sbi.feature_##compat &= ~EROFS_FEATURE_##feature; \
104 }
105
106 EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING)
107 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
108
109 #define EROFS_I_EA_INITED (1 << 0)
110 #define EROFS_I_Z_INITED (1 << 1)
111
112 struct erofs_inode {
113 struct list_head i_hash, i_subdirs, i_xattrs;
114
115 union {
116 /* (erofsfuse) runtime flags */
117 unsigned int flags;
118 /* (mkfs.erofs) device ID containing source file */
119 u32 dev;
120 };
121 unsigned int i_count;
122 struct erofs_inode *i_parent;
123
124 umode_t i_mode;
125 erofs_off_t i_size;
126
127 u64 i_ino[2];
128 u32 i_uid;
129 u32 i_gid;
130 u64 i_ctime;
131 u32 i_ctime_nsec;
132 u32 i_nlink;
133
134 union {
135 u32 i_blkaddr;
136 u32 i_blocks;
137 u32 i_rdev;
138 } u;
139
140 char i_srcpath[PATH_MAX + 1];
141
142 unsigned char datalayout;
143 unsigned char inode_isize;
144 /* inline tail-end packing size */
145 unsigned short idata_size;
146
147 unsigned int xattr_isize;
148 unsigned int extent_isize;
149
150 erofs_nid_t nid;
151 struct erofs_buffer_head *bh;
152 struct erofs_buffer_head *bh_inline, *bh_data;
153
154 void *idata;
155
156 union {
157 void *compressmeta;
158 struct {
159 uint16_t z_advise;
160 uint8_t z_algorithmtype[2];
161 uint8_t z_logical_clusterbits;
162 uint8_t z_physical_clusterbits[2];
163 };
164 };
165 #ifdef WITH_ANDROID
166 uint64_t capabilities;
167 #endif
168 };
169
is_inode_layout_compression(struct erofs_inode * inode)170 static inline bool is_inode_layout_compression(struct erofs_inode *inode)
171 {
172 return erofs_inode_is_data_compressed(inode->datalayout);
173 }
174
erofs_bitrange(unsigned int value,unsigned int bit,unsigned int bits)175 static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
176 unsigned int bits)
177 {
178 return (value >> bit) & ((1 << bits) - 1);
179 }
180
erofs_inode_version(unsigned int value)181 static inline unsigned int erofs_inode_version(unsigned int value)
182 {
183 return erofs_bitrange(value, EROFS_I_VERSION_BIT,
184 EROFS_I_VERSION_BITS);
185 }
186
erofs_inode_datalayout(unsigned int value)187 static inline unsigned int erofs_inode_datalayout(unsigned int value)
188 {
189 return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
190 EROFS_I_DATALAYOUT_BITS);
191 }
192
193 #define IS_ROOT(x) ((x) == (x)->i_parent)
194
195 struct erofs_dentry {
196 struct list_head d_child; /* child of parent list */
197
198 unsigned int type;
199 char name[EROFS_NAME_LEN];
200 union {
201 struct erofs_inode *inode;
202 erofs_nid_t nid;
203 };
204 };
205
is_dot_dotdot(const char * name)206 static inline bool is_dot_dotdot(const char *name)
207 {
208 if (name[0] != '.')
209 return false;
210
211 return name[1] == '\0' || (name[1] == '.' && name[2] == '\0');
212 }
213
214 #include <stdio.h>
215 #include <string.h>
216
erofs_strerror(int err)217 static inline const char *erofs_strerror(int err)
218 {
219 static char msg[256];
220
221 sprintf(msg, "[Error %d] %s", -err, strerror(-err));
222 return msg;
223 }
224
225 enum {
226 BH_Meta,
227 BH_Mapped,
228 BH_Zipped,
229 BH_FullMapped,
230 };
231
232 /* Has a disk mapping */
233 #define EROFS_MAP_MAPPED (1 << BH_Mapped)
234 /* Located in metadata (could be copied from bd_inode) */
235 #define EROFS_MAP_META (1 << BH_Meta)
236 /* The extent has been compressed */
237 #define EROFS_MAP_ZIPPED (1 << BH_Zipped)
238 /* The length of extent is full */
239 #define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped)
240
241 struct erofs_map_blocks {
242 char mpage[EROFS_BLKSIZ];
243
244 erofs_off_t m_pa, m_la;
245 u64 m_plen, m_llen;
246
247 unsigned int m_flags;
248 erofs_blk_t index;
249 };
250
251 /* super.c */
252 int erofs_read_superblock(void);
253
254 /* namei.c */
255 int erofs_ilookup(const char *path, struct erofs_inode *vi);
256
257 /* data.c */
258 int erofs_pread(struct erofs_inode *inode, char *buf,
259 erofs_off_t count, erofs_off_t offset);
260 /* zmap.c */
261 int z_erofs_fill_inode(struct erofs_inode *vi);
262 int z_erofs_map_blocks_iter(struct erofs_inode *vi,
263 struct erofs_map_blocks *map);
264
265 #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
266
267 #endif
268
269