• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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