1*33b1fccfSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
2*33b1fccfSAndroid Build Coastguard Worker /*
3*33b1fccfSAndroid Build Coastguard Worker * Copyright (C) 2019 HUAWEI, Inc.
4*33b1fccfSAndroid Build Coastguard Worker * http://www.huawei.com/
5*33b1fccfSAndroid Build Coastguard Worker * Created by Gao Xiang <[email protected]>
6*33b1fccfSAndroid Build Coastguard Worker */
7*33b1fccfSAndroid Build Coastguard Worker #ifndef __EROFS_INTERNAL_H
8*33b1fccfSAndroid Build Coastguard Worker #define __EROFS_INTERNAL_H
9*33b1fccfSAndroid Build Coastguard Worker
10*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
11*33b1fccfSAndroid Build Coastguard Worker extern "C"
12*33b1fccfSAndroid Build Coastguard Worker {
13*33b1fccfSAndroid Build Coastguard Worker #endif
14*33b1fccfSAndroid Build Coastguard Worker
15*33b1fccfSAndroid Build Coastguard Worker #include "list.h"
16*33b1fccfSAndroid Build Coastguard Worker #include "err.h"
17*33b1fccfSAndroid Build Coastguard Worker
18*33b1fccfSAndroid Build Coastguard Worker typedef unsigned short umode_t;
19*33b1fccfSAndroid Build Coastguard Worker
20*33b1fccfSAndroid Build Coastguard Worker #include "erofs_fs.h"
21*33b1fccfSAndroid Build Coastguard Worker #include <fcntl.h>
22*33b1fccfSAndroid Build Coastguard Worker #include <sys/types.h> /* for off_t definition */
23*33b1fccfSAndroid Build Coastguard Worker #include <sys/stat.h> /* for S_ISCHR definition */
24*33b1fccfSAndroid Build Coastguard Worker #include <stdio.h>
25*33b1fccfSAndroid Build Coastguard Worker #ifdef HAVE_PTHREAD_H
26*33b1fccfSAndroid Build Coastguard Worker #include <pthread.h>
27*33b1fccfSAndroid Build Coastguard Worker #endif
28*33b1fccfSAndroid Build Coastguard Worker #include "atomic.h"
29*33b1fccfSAndroid Build Coastguard Worker #include "io.h"
30*33b1fccfSAndroid Build Coastguard Worker
31*33b1fccfSAndroid Build Coastguard Worker #ifndef PATH_MAX
32*33b1fccfSAndroid Build Coastguard Worker #define PATH_MAX 4096 /* # chars in a path name including nul */
33*33b1fccfSAndroid Build Coastguard Worker #endif
34*33b1fccfSAndroid Build Coastguard Worker
35*33b1fccfSAndroid Build Coastguard Worker #ifndef EROFS_MAX_BLOCK_SIZE
36*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAX_BLOCK_SIZE 4096
37*33b1fccfSAndroid Build Coastguard Worker #endif
38*33b1fccfSAndroid Build Coastguard Worker
39*33b1fccfSAndroid Build Coastguard Worker #define EROFS_ISLOTBITS 5
40*33b1fccfSAndroid Build Coastguard Worker #define EROFS_SLOTSIZE (1U << EROFS_ISLOTBITS)
41*33b1fccfSAndroid Build Coastguard Worker
42*33b1fccfSAndroid Build Coastguard Worker typedef u64 erofs_off_t;
43*33b1fccfSAndroid Build Coastguard Worker typedef u64 erofs_nid_t;
44*33b1fccfSAndroid Build Coastguard Worker /* data type for filesystem-wide blocks number */
45*33b1fccfSAndroid Build Coastguard Worker typedef u32 erofs_blk_t;
46*33b1fccfSAndroid Build Coastguard Worker
47*33b1fccfSAndroid Build Coastguard Worker #define NULL_ADDR ((unsigned int)-1)
48*33b1fccfSAndroid Build Coastguard Worker #define NULL_ADDR_UL ((unsigned long)-1)
49*33b1fccfSAndroid Build Coastguard Worker
50*33b1fccfSAndroid Build Coastguard Worker /* global sbi */
51*33b1fccfSAndroid Build Coastguard Worker extern struct erofs_sb_info g_sbi;
52*33b1fccfSAndroid Build Coastguard Worker
53*33b1fccfSAndroid Build Coastguard Worker #define erofs_blksiz(sbi) (1u << (sbi)->blkszbits)
54*33b1fccfSAndroid Build Coastguard Worker #define erofs_blknr(sbi, addr) ((addr) >> (sbi)->blkszbits)
55*33b1fccfSAndroid Build Coastguard Worker #define erofs_blkoff(sbi, addr) ((addr) & (erofs_blksiz(sbi) - 1))
56*33b1fccfSAndroid Build Coastguard Worker #define erofs_pos(sbi, nr) ((erofs_off_t)(nr) << (sbi)->blkszbits)
57*33b1fccfSAndroid Build Coastguard Worker #define BLK_ROUND_UP(sbi, addr) \
58*33b1fccfSAndroid Build Coastguard Worker (roundup(addr, erofs_blksiz(sbi)) >> (sbi)->blkszbits)
59*33b1fccfSAndroid Build Coastguard Worker
60*33b1fccfSAndroid Build Coastguard Worker struct erofs_buffer_head;
61*33b1fccfSAndroid Build Coastguard Worker struct erofs_bufmgr;
62*33b1fccfSAndroid Build Coastguard Worker
63*33b1fccfSAndroid Build Coastguard Worker struct erofs_device_info {
64*33b1fccfSAndroid Build Coastguard Worker u8 tag[64];
65*33b1fccfSAndroid Build Coastguard Worker u32 blocks;
66*33b1fccfSAndroid Build Coastguard Worker u32 mapped_blkaddr;
67*33b1fccfSAndroid Build Coastguard Worker };
68*33b1fccfSAndroid Build Coastguard Worker
69*33b1fccfSAndroid Build Coastguard Worker /* all filesystem-wide lz4 configurations */
70*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_lz4_info {
71*33b1fccfSAndroid Build Coastguard Worker u16 max_distance;
72*33b1fccfSAndroid Build Coastguard Worker /* maximum possible blocks for pclusters in the filesystem */
73*33b1fccfSAndroid Build Coastguard Worker u16 max_pclusterblks;
74*33b1fccfSAndroid Build Coastguard Worker };
75*33b1fccfSAndroid Build Coastguard Worker
76*33b1fccfSAndroid Build Coastguard Worker struct erofs_xattr_prefix_item {
77*33b1fccfSAndroid Build Coastguard Worker struct erofs_xattr_long_prefix *prefix;
78*33b1fccfSAndroid Build Coastguard Worker u8 infix_len;
79*33b1fccfSAndroid Build Coastguard Worker };
80*33b1fccfSAndroid Build Coastguard Worker
81*33b1fccfSAndroid Build Coastguard Worker #define EROFS_PACKED_NID_UNALLOCATED -1
82*33b1fccfSAndroid Build Coastguard Worker
83*33b1fccfSAndroid Build Coastguard Worker struct erofs_mkfs_dfops;
84*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_info {
85*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_lz4_info lz4;
86*33b1fccfSAndroid Build Coastguard Worker struct erofs_device_info *devs;
87*33b1fccfSAndroid Build Coastguard Worker char *devname;
88*33b1fccfSAndroid Build Coastguard Worker
89*33b1fccfSAndroid Build Coastguard Worker u64 total_blocks;
90*33b1fccfSAndroid Build Coastguard Worker u64 primarydevice_blocks;
91*33b1fccfSAndroid Build Coastguard Worker
92*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t meta_blkaddr;
93*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t xattr_blkaddr;
94*33b1fccfSAndroid Build Coastguard Worker
95*33b1fccfSAndroid Build Coastguard Worker u32 feature_compat;
96*33b1fccfSAndroid Build Coastguard Worker u32 feature_incompat;
97*33b1fccfSAndroid Build Coastguard Worker
98*33b1fccfSAndroid Build Coastguard Worker unsigned char islotbits;
99*33b1fccfSAndroid Build Coastguard Worker unsigned char blkszbits;
100*33b1fccfSAndroid Build Coastguard Worker
101*33b1fccfSAndroid Build Coastguard Worker u32 sb_size; /* total superblock size */
102*33b1fccfSAndroid Build Coastguard Worker u32 build_time_nsec;
103*33b1fccfSAndroid Build Coastguard Worker u64 build_time;
104*33b1fccfSAndroid Build Coastguard Worker
105*33b1fccfSAndroid Build Coastguard Worker /* what we really care is nid, rather than ino.. */
106*33b1fccfSAndroid Build Coastguard Worker erofs_nid_t root_nid;
107*33b1fccfSAndroid Build Coastguard Worker /* used for statfs, f_files - f_favail */
108*33b1fccfSAndroid Build Coastguard Worker u64 inos;
109*33b1fccfSAndroid Build Coastguard Worker
110*33b1fccfSAndroid Build Coastguard Worker u8 uuid[16];
111*33b1fccfSAndroid Build Coastguard Worker char volume_name[16];
112*33b1fccfSAndroid Build Coastguard Worker
113*33b1fccfSAndroid Build Coastguard Worker u32 checksum;
114*33b1fccfSAndroid Build Coastguard Worker u16 available_compr_algs;
115*33b1fccfSAndroid Build Coastguard Worker u16 extra_devices;
116*33b1fccfSAndroid Build Coastguard Worker union {
117*33b1fccfSAndroid Build Coastguard Worker u16 devt_slotoff; /* used for mkfs */
118*33b1fccfSAndroid Build Coastguard Worker u16 device_id_mask; /* used for others */
119*33b1fccfSAndroid Build Coastguard Worker };
120*33b1fccfSAndroid Build Coastguard Worker erofs_nid_t packed_nid;
121*33b1fccfSAndroid Build Coastguard Worker
122*33b1fccfSAndroid Build Coastguard Worker u32 xattr_prefix_start;
123*33b1fccfSAndroid Build Coastguard Worker u8 xattr_prefix_count;
124*33b1fccfSAndroid Build Coastguard Worker struct erofs_xattr_prefix_item *xattr_prefixes;
125*33b1fccfSAndroid Build Coastguard Worker
126*33b1fccfSAndroid Build Coastguard Worker struct erofs_vfile bdev;
127*33b1fccfSAndroid Build Coastguard Worker int devblksz;
128*33b1fccfSAndroid Build Coastguard Worker u64 devsz;
129*33b1fccfSAndroid Build Coastguard Worker dev_t dev;
130*33b1fccfSAndroid Build Coastguard Worker unsigned int nblobs;
131*33b1fccfSAndroid Build Coastguard Worker unsigned int blobfd[256];
132*33b1fccfSAndroid Build Coastguard Worker
133*33b1fccfSAndroid Build Coastguard Worker struct list_head list;
134*33b1fccfSAndroid Build Coastguard Worker
135*33b1fccfSAndroid Build Coastguard Worker u64 saved_by_deduplication;
136*33b1fccfSAndroid Build Coastguard Worker
137*33b1fccfSAndroid Build Coastguard Worker #ifdef EROFS_MT_ENABLED
138*33b1fccfSAndroid Build Coastguard Worker pthread_t dfops_worker;
139*33b1fccfSAndroid Build Coastguard Worker struct erofs_mkfs_dfops *mkfs_dfops;
140*33b1fccfSAndroid Build Coastguard Worker #endif
141*33b1fccfSAndroid Build Coastguard Worker struct erofs_bufmgr *bmgr;
142*33b1fccfSAndroid Build Coastguard Worker bool useqpl;
143*33b1fccfSAndroid Build Coastguard Worker };
144*33b1fccfSAndroid Build Coastguard Worker
145*33b1fccfSAndroid Build Coastguard Worker #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
146*33b1fccfSAndroid Build Coastguard Worker
147*33b1fccfSAndroid Build Coastguard Worker /* make sure that any user of the erofs headers has atleast 64bit off_t type */
148*33b1fccfSAndroid Build Coastguard Worker extern int erofs_assert_largefile[sizeof(off_t)-8];
149*33b1fccfSAndroid Build Coastguard Worker
150*33b1fccfSAndroid Build Coastguard Worker #define EROFS_FEATURE_FUNCS(name, compat, feature) \
151*33b1fccfSAndroid Build Coastguard Worker static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \
152*33b1fccfSAndroid Build Coastguard Worker { \
153*33b1fccfSAndroid Build Coastguard Worker return sbi->feature_##compat & EROFS_FEATURE_##feature; \
154*33b1fccfSAndroid Build Coastguard Worker } \
155*33b1fccfSAndroid Build Coastguard Worker static inline void erofs_sb_set_##name(struct erofs_sb_info *sbi) \
156*33b1fccfSAndroid Build Coastguard Worker { \
157*33b1fccfSAndroid Build Coastguard Worker sbi->feature_##compat |= EROFS_FEATURE_##feature; \
158*33b1fccfSAndroid Build Coastguard Worker } \
159*33b1fccfSAndroid Build Coastguard Worker static inline void erofs_sb_clear_##name(struct erofs_sb_info *sbi) \
160*33b1fccfSAndroid Build Coastguard Worker { \
161*33b1fccfSAndroid Build Coastguard Worker sbi->feature_##compat &= ~EROFS_FEATURE_##feature; \
162*33b1fccfSAndroid Build Coastguard Worker }
163*33b1fccfSAndroid Build Coastguard Worker
164*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_ZERO_PADDING)
165*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS)
166*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER)
167*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE)
168*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE)
169*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING)
170*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
171*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
172*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
173*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
174*33b1fccfSAndroid Build Coastguard Worker EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER)
175*33b1fccfSAndroid Build Coastguard Worker
176*33b1fccfSAndroid Build Coastguard Worker #define EROFS_I_EA_INITED (1 << 0)
177*33b1fccfSAndroid Build Coastguard Worker #define EROFS_I_Z_INITED (1 << 1)
178*33b1fccfSAndroid Build Coastguard Worker
179*33b1fccfSAndroid Build Coastguard Worker struct erofs_diskbuf;
180*33b1fccfSAndroid Build Coastguard Worker
181*33b1fccfSAndroid Build Coastguard Worker #define EROFS_INODE_DATA_SOURCE_NONE 0
182*33b1fccfSAndroid Build Coastguard Worker #define EROFS_INODE_DATA_SOURCE_LOCALPATH 1
183*33b1fccfSAndroid Build Coastguard Worker #define EROFS_INODE_DATA_SOURCE_DISKBUF 2
184*33b1fccfSAndroid Build Coastguard Worker #define EROFS_INODE_DATA_SOURCE_RESVSP 3
185*33b1fccfSAndroid Build Coastguard Worker
186*33b1fccfSAndroid Build Coastguard Worker struct erofs_inode {
187*33b1fccfSAndroid Build Coastguard Worker struct list_head i_hash, i_subdirs, i_xattrs;
188*33b1fccfSAndroid Build Coastguard Worker
189*33b1fccfSAndroid Build Coastguard Worker union {
190*33b1fccfSAndroid Build Coastguard Worker /* (erofsfuse) runtime flags */
191*33b1fccfSAndroid Build Coastguard Worker unsigned int flags;
192*33b1fccfSAndroid Build Coastguard Worker
193*33b1fccfSAndroid Build Coastguard Worker /* (mkfs.erofs) next pointer for directory dumping */
194*33b1fccfSAndroid Build Coastguard Worker struct erofs_inode *next_dirwrite;
195*33b1fccfSAndroid Build Coastguard Worker };
196*33b1fccfSAndroid Build Coastguard Worker erofs_atomic_t i_count;
197*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_info *sbi;
198*33b1fccfSAndroid Build Coastguard Worker struct erofs_inode *i_parent;
199*33b1fccfSAndroid Build Coastguard Worker
200*33b1fccfSAndroid Build Coastguard Worker /* (mkfs.erofs) device ID containing source file */
201*33b1fccfSAndroid Build Coastguard Worker u32 dev;
202*33b1fccfSAndroid Build Coastguard Worker
203*33b1fccfSAndroid Build Coastguard Worker umode_t i_mode;
204*33b1fccfSAndroid Build Coastguard Worker erofs_off_t i_size;
205*33b1fccfSAndroid Build Coastguard Worker
206*33b1fccfSAndroid Build Coastguard Worker u64 i_ino[2];
207*33b1fccfSAndroid Build Coastguard Worker u32 i_uid;
208*33b1fccfSAndroid Build Coastguard Worker u32 i_gid;
209*33b1fccfSAndroid Build Coastguard Worker u64 i_mtime;
210*33b1fccfSAndroid Build Coastguard Worker u32 i_mtime_nsec;
211*33b1fccfSAndroid Build Coastguard Worker u32 i_nlink;
212*33b1fccfSAndroid Build Coastguard Worker
213*33b1fccfSAndroid Build Coastguard Worker union {
214*33b1fccfSAndroid Build Coastguard Worker u32 i_blkaddr;
215*33b1fccfSAndroid Build Coastguard Worker u32 i_blocks;
216*33b1fccfSAndroid Build Coastguard Worker u32 i_rdev;
217*33b1fccfSAndroid Build Coastguard Worker struct {
218*33b1fccfSAndroid Build Coastguard Worker unsigned short chunkformat;
219*33b1fccfSAndroid Build Coastguard Worker unsigned char chunkbits;
220*33b1fccfSAndroid Build Coastguard Worker };
221*33b1fccfSAndroid Build Coastguard Worker } u;
222*33b1fccfSAndroid Build Coastguard Worker
223*33b1fccfSAndroid Build Coastguard Worker char *i_srcpath;
224*33b1fccfSAndroid Build Coastguard Worker union {
225*33b1fccfSAndroid Build Coastguard Worker char *i_link;
226*33b1fccfSAndroid Build Coastguard Worker struct erofs_diskbuf *i_diskbuf;
227*33b1fccfSAndroid Build Coastguard Worker };
228*33b1fccfSAndroid Build Coastguard Worker unsigned char datalayout;
229*33b1fccfSAndroid Build Coastguard Worker unsigned char inode_isize;
230*33b1fccfSAndroid Build Coastguard Worker /* inline tail-end packing size */
231*33b1fccfSAndroid Build Coastguard Worker unsigned short idata_size;
232*33b1fccfSAndroid Build Coastguard Worker char datasource;
233*33b1fccfSAndroid Build Coastguard Worker bool compressed_idata;
234*33b1fccfSAndroid Build Coastguard Worker bool lazy_tailblock;
235*33b1fccfSAndroid Build Coastguard Worker bool opaque;
236*33b1fccfSAndroid Build Coastguard Worker /* OVL: non-merge dir that may contain whiteout entries */
237*33b1fccfSAndroid Build Coastguard Worker bool whiteouts;
238*33b1fccfSAndroid Build Coastguard Worker
239*33b1fccfSAndroid Build Coastguard Worker unsigned int xattr_isize;
240*33b1fccfSAndroid Build Coastguard Worker unsigned int extent_isize;
241*33b1fccfSAndroid Build Coastguard Worker
242*33b1fccfSAndroid Build Coastguard Worker unsigned int xattr_shared_count;
243*33b1fccfSAndroid Build Coastguard Worker unsigned int *xattr_shared_xattrs;
244*33b1fccfSAndroid Build Coastguard Worker
245*33b1fccfSAndroid Build Coastguard Worker erofs_nid_t nid;
246*33b1fccfSAndroid Build Coastguard Worker struct erofs_buffer_head *bh;
247*33b1fccfSAndroid Build Coastguard Worker struct erofs_buffer_head *bh_inline, *bh_data;
248*33b1fccfSAndroid Build Coastguard Worker
249*33b1fccfSAndroid Build Coastguard Worker void *idata;
250*33b1fccfSAndroid Build Coastguard Worker
251*33b1fccfSAndroid Build Coastguard Worker /* (ztailpacking) in order to recover uncompressed EOF data */
252*33b1fccfSAndroid Build Coastguard Worker void *eof_tailraw;
253*33b1fccfSAndroid Build Coastguard Worker unsigned int eof_tailrawsize;
254*33b1fccfSAndroid Build Coastguard Worker
255*33b1fccfSAndroid Build Coastguard Worker union {
256*33b1fccfSAndroid Build Coastguard Worker void *compressmeta;
257*33b1fccfSAndroid Build Coastguard Worker void *chunkindexes;
258*33b1fccfSAndroid Build Coastguard Worker struct {
259*33b1fccfSAndroid Build Coastguard Worker uint16_t z_advise;
260*33b1fccfSAndroid Build Coastguard Worker uint8_t z_algorithmtype[2];
261*33b1fccfSAndroid Build Coastguard Worker uint8_t z_logical_clusterbits;
262*33b1fccfSAndroid Build Coastguard Worker uint8_t z_physical_clusterblks;
263*33b1fccfSAndroid Build Coastguard Worker union {
264*33b1fccfSAndroid Build Coastguard Worker uint64_t z_tailextent_headlcn;
265*33b1fccfSAndroid Build Coastguard Worker erofs_off_t fragment_size;
266*33b1fccfSAndroid Build Coastguard Worker };
267*33b1fccfSAndroid Build Coastguard Worker union {
268*33b1fccfSAndroid Build Coastguard Worker unsigned int z_idataoff;
269*33b1fccfSAndroid Build Coastguard Worker erofs_off_t fragmentoff;
270*33b1fccfSAndroid Build Coastguard Worker };
271*33b1fccfSAndroid Build Coastguard Worker #define z_idata_size idata_size
272*33b1fccfSAndroid Build Coastguard Worker };
273*33b1fccfSAndroid Build Coastguard Worker };
274*33b1fccfSAndroid Build Coastguard Worker #ifdef WITH_ANDROID
275*33b1fccfSAndroid Build Coastguard Worker uint64_t capabilities;
276*33b1fccfSAndroid Build Coastguard Worker #endif
277*33b1fccfSAndroid Build Coastguard Worker };
278*33b1fccfSAndroid Build Coastguard Worker
erofs_iloc(struct erofs_inode * inode)279*33b1fccfSAndroid Build Coastguard Worker static inline erofs_off_t erofs_iloc(struct erofs_inode *inode)
280*33b1fccfSAndroid Build Coastguard Worker {
281*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_info *sbi = inode->sbi;
282*33b1fccfSAndroid Build Coastguard Worker
283*33b1fccfSAndroid Build Coastguard Worker return erofs_pos(sbi, sbi->meta_blkaddr) +
284*33b1fccfSAndroid Build Coastguard Worker (inode->nid << sbi->islotbits);
285*33b1fccfSAndroid Build Coastguard Worker }
286*33b1fccfSAndroid Build Coastguard Worker
is_inode_layout_compression(struct erofs_inode * inode)287*33b1fccfSAndroid Build Coastguard Worker static inline bool is_inode_layout_compression(struct erofs_inode *inode)
288*33b1fccfSAndroid Build Coastguard Worker {
289*33b1fccfSAndroid Build Coastguard Worker return erofs_inode_is_data_compressed(inode->datalayout);
290*33b1fccfSAndroid Build Coastguard Worker }
291*33b1fccfSAndroid Build Coastguard Worker
erofs_bitrange(unsigned int value,unsigned int bit,unsigned int bits)292*33b1fccfSAndroid Build Coastguard Worker static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
293*33b1fccfSAndroid Build Coastguard Worker unsigned int bits)
294*33b1fccfSAndroid Build Coastguard Worker {
295*33b1fccfSAndroid Build Coastguard Worker return (value >> bit) & ((1 << bits) - 1);
296*33b1fccfSAndroid Build Coastguard Worker }
297*33b1fccfSAndroid Build Coastguard Worker
erofs_inode_version(unsigned int value)298*33b1fccfSAndroid Build Coastguard Worker static inline unsigned int erofs_inode_version(unsigned int value)
299*33b1fccfSAndroid Build Coastguard Worker {
300*33b1fccfSAndroid Build Coastguard Worker return erofs_bitrange(value, EROFS_I_VERSION_BIT,
301*33b1fccfSAndroid Build Coastguard Worker EROFS_I_VERSION_BITS);
302*33b1fccfSAndroid Build Coastguard Worker }
303*33b1fccfSAndroid Build Coastguard Worker
erofs_inode_datalayout(unsigned int value)304*33b1fccfSAndroid Build Coastguard Worker static inline unsigned int erofs_inode_datalayout(unsigned int value)
305*33b1fccfSAndroid Build Coastguard Worker {
306*33b1fccfSAndroid Build Coastguard Worker return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
307*33b1fccfSAndroid Build Coastguard Worker EROFS_I_DATALAYOUT_BITS);
308*33b1fccfSAndroid Build Coastguard Worker }
309*33b1fccfSAndroid Build Coastguard Worker
erofs_parent_inode(struct erofs_inode * inode)310*33b1fccfSAndroid Build Coastguard Worker static inline struct erofs_inode *erofs_parent_inode(struct erofs_inode *inode)
311*33b1fccfSAndroid Build Coastguard Worker {
312*33b1fccfSAndroid Build Coastguard Worker return (struct erofs_inode *)((unsigned long)inode->i_parent & ~1UL);
313*33b1fccfSAndroid Build Coastguard Worker }
314*33b1fccfSAndroid Build Coastguard Worker
315*33b1fccfSAndroid Build Coastguard Worker #define IS_ROOT(x) ((x) == erofs_parent_inode(x))
316*33b1fccfSAndroid Build Coastguard Worker
317*33b1fccfSAndroid Build Coastguard Worker struct erofs_dentry {
318*33b1fccfSAndroid Build Coastguard Worker struct list_head d_child; /* child of parent list */
319*33b1fccfSAndroid Build Coastguard Worker union {
320*33b1fccfSAndroid Build Coastguard Worker struct erofs_inode *inode;
321*33b1fccfSAndroid Build Coastguard Worker erofs_nid_t nid;
322*33b1fccfSAndroid Build Coastguard Worker };
323*33b1fccfSAndroid Build Coastguard Worker char name[EROFS_NAME_LEN];
324*33b1fccfSAndroid Build Coastguard Worker u8 type;
325*33b1fccfSAndroid Build Coastguard Worker bool validnid;
326*33b1fccfSAndroid Build Coastguard Worker };
327*33b1fccfSAndroid Build Coastguard Worker
is_dot_dotdot_len(const char * name,unsigned int len)328*33b1fccfSAndroid Build Coastguard Worker static inline bool is_dot_dotdot_len(const char *name, unsigned int len)
329*33b1fccfSAndroid Build Coastguard Worker {
330*33b1fccfSAndroid Build Coastguard Worker if (len >= 1 && name[0] != '.')
331*33b1fccfSAndroid Build Coastguard Worker return false;
332*33b1fccfSAndroid Build Coastguard Worker
333*33b1fccfSAndroid Build Coastguard Worker return len == 1 || (len == 2 && name[1] == '.');
334*33b1fccfSAndroid Build Coastguard Worker }
335*33b1fccfSAndroid Build Coastguard Worker
is_dot_dotdot(const char * name)336*33b1fccfSAndroid Build Coastguard Worker static inline bool is_dot_dotdot(const char *name)
337*33b1fccfSAndroid Build Coastguard Worker {
338*33b1fccfSAndroid Build Coastguard Worker if (name[0] != '.')
339*33b1fccfSAndroid Build Coastguard Worker return false;
340*33b1fccfSAndroid Build Coastguard Worker
341*33b1fccfSAndroid Build Coastguard Worker return name[1] == '\0' || (name[1] == '.' && name[2] == '\0');
342*33b1fccfSAndroid Build Coastguard Worker }
343*33b1fccfSAndroid Build Coastguard Worker
344*33b1fccfSAndroid Build Coastguard Worker #include <stdio.h>
345*33b1fccfSAndroid Build Coastguard Worker #include <string.h>
346*33b1fccfSAndroid Build Coastguard Worker
erofs_strerror(int err)347*33b1fccfSAndroid Build Coastguard Worker static inline const char *erofs_strerror(int err)
348*33b1fccfSAndroid Build Coastguard Worker {
349*33b1fccfSAndroid Build Coastguard Worker static char msg[256];
350*33b1fccfSAndroid Build Coastguard Worker
351*33b1fccfSAndroid Build Coastguard Worker sprintf(msg, "[Error %d] %s", -err, strerror(-err));
352*33b1fccfSAndroid Build Coastguard Worker return msg;
353*33b1fccfSAndroid Build Coastguard Worker }
354*33b1fccfSAndroid Build Coastguard Worker
355*33b1fccfSAndroid Build Coastguard Worker enum {
356*33b1fccfSAndroid Build Coastguard Worker BH_Meta,
357*33b1fccfSAndroid Build Coastguard Worker BH_Mapped,
358*33b1fccfSAndroid Build Coastguard Worker BH_Encoded,
359*33b1fccfSAndroid Build Coastguard Worker BH_FullMapped,
360*33b1fccfSAndroid Build Coastguard Worker BH_Fragment,
361*33b1fccfSAndroid Build Coastguard Worker BH_Partialref,
362*33b1fccfSAndroid Build Coastguard Worker };
363*33b1fccfSAndroid Build Coastguard Worker
364*33b1fccfSAndroid Build Coastguard Worker /* Has a disk mapping */
365*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_MAPPED (1 << BH_Mapped)
366*33b1fccfSAndroid Build Coastguard Worker /* Located in metadata (could be copied from bd_inode) */
367*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_META (1 << BH_Meta)
368*33b1fccfSAndroid Build Coastguard Worker /* The extent is encoded */
369*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_ENCODED (1 << BH_Encoded)
370*33b1fccfSAndroid Build Coastguard Worker /* The length of extent is full */
371*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped)
372*33b1fccfSAndroid Build Coastguard Worker /* Located in the special packed inode */
373*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_FRAGMENT (1 << BH_Fragment)
374*33b1fccfSAndroid Build Coastguard Worker /* The extent refers to partial decompressed data */
375*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MAP_PARTIAL_REF (1 << BH_Partialref)
376*33b1fccfSAndroid Build Coastguard Worker
377*33b1fccfSAndroid Build Coastguard Worker struct erofs_map_blocks {
378*33b1fccfSAndroid Build Coastguard Worker char mpage[EROFS_MAX_BLOCK_SIZE];
379*33b1fccfSAndroid Build Coastguard Worker
380*33b1fccfSAndroid Build Coastguard Worker erofs_off_t m_pa, m_la;
381*33b1fccfSAndroid Build Coastguard Worker u64 m_plen, m_llen;
382*33b1fccfSAndroid Build Coastguard Worker
383*33b1fccfSAndroid Build Coastguard Worker unsigned short m_deviceid;
384*33b1fccfSAndroid Build Coastguard Worker char m_algorithmformat;
385*33b1fccfSAndroid Build Coastguard Worker unsigned int m_flags;
386*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t index;
387*33b1fccfSAndroid Build Coastguard Worker };
388*33b1fccfSAndroid Build Coastguard Worker
389*33b1fccfSAndroid Build Coastguard Worker /*
390*33b1fccfSAndroid Build Coastguard Worker * Used to get the exact decompressed length, e.g. fiemap (consider lookback
391*33b1fccfSAndroid Build Coastguard Worker * approach instead if possible since it's more metadata lightweight.)
392*33b1fccfSAndroid Build Coastguard Worker */
393*33b1fccfSAndroid Build Coastguard Worker #define EROFS_GET_BLOCKS_FIEMAP 0x0002
394*33b1fccfSAndroid Build Coastguard Worker /* Used to map tail extent for tailpacking inline or fragment pcluster */
395*33b1fccfSAndroid Build Coastguard Worker #define EROFS_GET_BLOCKS_FINDTAIL 0x0008
396*33b1fccfSAndroid Build Coastguard Worker
397*33b1fccfSAndroid Build Coastguard Worker enum {
398*33b1fccfSAndroid Build Coastguard Worker Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
399*33b1fccfSAndroid Build Coastguard Worker Z_EROFS_COMPRESSION_INTERLACED,
400*33b1fccfSAndroid Build Coastguard Worker Z_EROFS_COMPRESSION_RUNTIME_MAX
401*33b1fccfSAndroid Build Coastguard Worker };
402*33b1fccfSAndroid Build Coastguard Worker
403*33b1fccfSAndroid Build Coastguard Worker struct erofs_map_dev {
404*33b1fccfSAndroid Build Coastguard Worker erofs_off_t m_pa;
405*33b1fccfSAndroid Build Coastguard Worker unsigned int m_deviceid;
406*33b1fccfSAndroid Build Coastguard Worker };
407*33b1fccfSAndroid Build Coastguard Worker
408*33b1fccfSAndroid Build Coastguard Worker /* super.c */
409*33b1fccfSAndroid Build Coastguard Worker int erofs_read_superblock(struct erofs_sb_info *sbi);
410*33b1fccfSAndroid Build Coastguard Worker void erofs_put_super(struct erofs_sb_info *sbi);
411*33b1fccfSAndroid Build Coastguard Worker int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh,
412*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t *blocks);
413*33b1fccfSAndroid Build Coastguard Worker struct erofs_buffer_head *erofs_reserve_sb(struct erofs_bufmgr *bmgr);
414*33b1fccfSAndroid Build Coastguard Worker int erofs_enable_sb_chksum(struct erofs_sb_info *sbi, u32 *crc);
415*33b1fccfSAndroid Build Coastguard Worker
416*33b1fccfSAndroid Build Coastguard Worker /* namei.c */
417*33b1fccfSAndroid Build Coastguard Worker int erofs_read_inode_from_disk(struct erofs_inode *vi);
418*33b1fccfSAndroid Build Coastguard Worker int erofs_ilookup(const char *path, struct erofs_inode *vi);
419*33b1fccfSAndroid Build Coastguard Worker
420*33b1fccfSAndroid Build Coastguard Worker /* data.c */
421*33b1fccfSAndroid Build Coastguard Worker int erofs_pread(struct erofs_inode *inode, char *buf,
422*33b1fccfSAndroid Build Coastguard Worker erofs_off_t count, erofs_off_t offset);
423*33b1fccfSAndroid Build Coastguard Worker int erofs_map_blocks(struct erofs_inode *inode,
424*33b1fccfSAndroid Build Coastguard Worker struct erofs_map_blocks *map, int flags);
425*33b1fccfSAndroid Build Coastguard Worker int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map);
426*33b1fccfSAndroid Build Coastguard Worker int erofs_read_one_data(struct erofs_inode *inode, struct erofs_map_blocks *map,
427*33b1fccfSAndroid Build Coastguard Worker char *buffer, u64 offset, size_t len);
428*33b1fccfSAndroid Build Coastguard Worker int z_erofs_read_one_data(struct erofs_inode *inode,
429*33b1fccfSAndroid Build Coastguard Worker struct erofs_map_blocks *map, char *raw, char *buffer,
430*33b1fccfSAndroid Build Coastguard Worker erofs_off_t skip, erofs_off_t length, bool trimmed);
431*33b1fccfSAndroid Build Coastguard Worker void *erofs_read_metadata(struct erofs_sb_info *sbi, erofs_nid_t nid,
432*33b1fccfSAndroid Build Coastguard Worker erofs_off_t *offset, int *lengthp);
433*33b1fccfSAndroid Build Coastguard Worker int z_erofs_parse_cfgs(struct erofs_sb_info *sbi, struct erofs_super_block *dsb);
434*33b1fccfSAndroid Build Coastguard Worker
erofs_get_occupied_size(const struct erofs_inode * inode,erofs_off_t * size)435*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_get_occupied_size(const struct erofs_inode *inode,
436*33b1fccfSAndroid Build Coastguard Worker erofs_off_t *size)
437*33b1fccfSAndroid Build Coastguard Worker {
438*33b1fccfSAndroid Build Coastguard Worker *size = 0;
439*33b1fccfSAndroid Build Coastguard Worker switch (inode->datalayout) {
440*33b1fccfSAndroid Build Coastguard Worker case EROFS_INODE_FLAT_INLINE:
441*33b1fccfSAndroid Build Coastguard Worker case EROFS_INODE_FLAT_PLAIN:
442*33b1fccfSAndroid Build Coastguard Worker case EROFS_INODE_CHUNK_BASED:
443*33b1fccfSAndroid Build Coastguard Worker *size = inode->i_size;
444*33b1fccfSAndroid Build Coastguard Worker break;
445*33b1fccfSAndroid Build Coastguard Worker case EROFS_INODE_COMPRESSED_FULL:
446*33b1fccfSAndroid Build Coastguard Worker case EROFS_INODE_COMPRESSED_COMPACT:
447*33b1fccfSAndroid Build Coastguard Worker *size = inode->u.i_blocks * erofs_blksiz(inode->sbi);
448*33b1fccfSAndroid Build Coastguard Worker break;
449*33b1fccfSAndroid Build Coastguard Worker default:
450*33b1fccfSAndroid Build Coastguard Worker return -EOPNOTSUPP;
451*33b1fccfSAndroid Build Coastguard Worker }
452*33b1fccfSAndroid Build Coastguard Worker return 0;
453*33b1fccfSAndroid Build Coastguard Worker }
454*33b1fccfSAndroid Build Coastguard Worker
455*33b1fccfSAndroid Build Coastguard Worker /* data.c */
456*33b1fccfSAndroid Build Coastguard Worker int erofs_getxattr(struct erofs_inode *vi, const char *name, char *buffer,
457*33b1fccfSAndroid Build Coastguard Worker size_t buffer_size);
458*33b1fccfSAndroid Build Coastguard Worker int erofs_listxattr(struct erofs_inode *vi, char *buffer, size_t buffer_size);
459*33b1fccfSAndroid Build Coastguard Worker
460*33b1fccfSAndroid Build Coastguard Worker /* zmap.c */
461*33b1fccfSAndroid Build Coastguard Worker int z_erofs_fill_inode(struct erofs_inode *vi);
462*33b1fccfSAndroid Build Coastguard Worker int z_erofs_map_blocks_iter(struct erofs_inode *vi,
463*33b1fccfSAndroid Build Coastguard Worker struct erofs_map_blocks *map, int flags);
464*33b1fccfSAndroid Build Coastguard Worker
465*33b1fccfSAndroid Build Coastguard Worker /* io.c */
466*33b1fccfSAndroid Build Coastguard Worker int erofs_dev_open(struct erofs_sb_info *sbi, const char *dev, int flags);
467*33b1fccfSAndroid Build Coastguard Worker void erofs_dev_close(struct erofs_sb_info *sbi);
468*33b1fccfSAndroid Build Coastguard Worker void erofs_blob_closeall(struct erofs_sb_info *sbi);
469*33b1fccfSAndroid Build Coastguard Worker int erofs_blob_open_ro(struct erofs_sb_info *sbi, const char *dev);
470*33b1fccfSAndroid Build Coastguard Worker
471*33b1fccfSAndroid Build Coastguard Worker ssize_t erofs_dev_read(struct erofs_sb_info *sbi, int device_id,
472*33b1fccfSAndroid Build Coastguard Worker void *buf, u64 offset, size_t len);
473*33b1fccfSAndroid Build Coastguard Worker
erofs_dev_write(struct erofs_sb_info * sbi,const void * buf,u64 offset,size_t len)474*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_dev_write(struct erofs_sb_info *sbi, const void *buf,
475*33b1fccfSAndroid Build Coastguard Worker u64 offset, size_t len)
476*33b1fccfSAndroid Build Coastguard Worker {
477*33b1fccfSAndroid Build Coastguard Worker if (erofs_io_pwrite(&sbi->bdev, buf, offset, len) != (ssize_t)len)
478*33b1fccfSAndroid Build Coastguard Worker return -EIO;
479*33b1fccfSAndroid Build Coastguard Worker return 0;
480*33b1fccfSAndroid Build Coastguard Worker }
481*33b1fccfSAndroid Build Coastguard Worker
erofs_dev_fillzero(struct erofs_sb_info * sbi,u64 offset,size_t len,bool pad)482*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_dev_fillzero(struct erofs_sb_info *sbi, u64 offset,
483*33b1fccfSAndroid Build Coastguard Worker size_t len, bool pad)
484*33b1fccfSAndroid Build Coastguard Worker {
485*33b1fccfSAndroid Build Coastguard Worker return erofs_io_fallocate(&sbi->bdev, offset, len, pad);
486*33b1fccfSAndroid Build Coastguard Worker }
487*33b1fccfSAndroid Build Coastguard Worker
erofs_dev_resize(struct erofs_sb_info * sbi,erofs_blk_t blocks)488*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_dev_resize(struct erofs_sb_info *sbi,
489*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t blocks)
490*33b1fccfSAndroid Build Coastguard Worker {
491*33b1fccfSAndroid Build Coastguard Worker return erofs_io_ftruncate(&sbi->bdev, (u64)blocks * erofs_blksiz(sbi));
492*33b1fccfSAndroid Build Coastguard Worker }
493*33b1fccfSAndroid Build Coastguard Worker
erofs_blk_write(struct erofs_sb_info * sbi,const void * buf,erofs_blk_t blkaddr,u32 nblocks)494*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_blk_write(struct erofs_sb_info *sbi, const void *buf,
495*33b1fccfSAndroid Build Coastguard Worker erofs_blk_t blkaddr, u32 nblocks)
496*33b1fccfSAndroid Build Coastguard Worker {
497*33b1fccfSAndroid Build Coastguard Worker return erofs_dev_write(sbi, buf, erofs_pos(sbi, blkaddr),
498*33b1fccfSAndroid Build Coastguard Worker erofs_pos(sbi, nblocks));
499*33b1fccfSAndroid Build Coastguard Worker }
500*33b1fccfSAndroid Build Coastguard Worker
erofs_blk_read(struct erofs_sb_info * sbi,int device_id,void * buf,erofs_blk_t start,u32 nblocks)501*33b1fccfSAndroid Build Coastguard Worker static inline int erofs_blk_read(struct erofs_sb_info *sbi, int device_id,
502*33b1fccfSAndroid Build Coastguard Worker void *buf, erofs_blk_t start, u32 nblocks)
503*33b1fccfSAndroid Build Coastguard Worker {
504*33b1fccfSAndroid Build Coastguard Worker return erofs_dev_read(sbi, device_id, buf, erofs_pos(sbi, start),
505*33b1fccfSAndroid Build Coastguard Worker erofs_pos(sbi, nblocks));
506*33b1fccfSAndroid Build Coastguard Worker }
507*33b1fccfSAndroid Build Coastguard Worker
508*33b1fccfSAndroid Build Coastguard Worker #ifdef EUCLEAN
509*33b1fccfSAndroid Build Coastguard Worker #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
510*33b1fccfSAndroid Build Coastguard Worker #else
511*33b1fccfSAndroid Build Coastguard Worker #define EFSCORRUPTED EIO
512*33b1fccfSAndroid Build Coastguard Worker #endif
513*33b1fccfSAndroid Build Coastguard Worker
514*33b1fccfSAndroid Build Coastguard Worker #define CRC32C_POLY_LE 0x82F63B78
erofs_crc32c(u32 crc,const u8 * in,size_t len)515*33b1fccfSAndroid Build Coastguard Worker static inline u32 erofs_crc32c(u32 crc, const u8 *in, size_t len)
516*33b1fccfSAndroid Build Coastguard Worker {
517*33b1fccfSAndroid Build Coastguard Worker int i;
518*33b1fccfSAndroid Build Coastguard Worker
519*33b1fccfSAndroid Build Coastguard Worker while (len--) {
520*33b1fccfSAndroid Build Coastguard Worker crc ^= *in++;
521*33b1fccfSAndroid Build Coastguard Worker for (i = 0; i < 8; i++)
522*33b1fccfSAndroid Build Coastguard Worker crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
523*33b1fccfSAndroid Build Coastguard Worker }
524*33b1fccfSAndroid Build Coastguard Worker return crc;
525*33b1fccfSAndroid Build Coastguard Worker }
526*33b1fccfSAndroid Build Coastguard Worker
527*33b1fccfSAndroid Build Coastguard Worker #define EROFS_WHITEOUT_DEV 0
erofs_inode_is_whiteout(struct erofs_inode * inode)528*33b1fccfSAndroid Build Coastguard Worker static inline bool erofs_inode_is_whiteout(struct erofs_inode *inode)
529*33b1fccfSAndroid Build Coastguard Worker {
530*33b1fccfSAndroid Build Coastguard Worker return S_ISCHR(inode->i_mode) && inode->u.i_rdev == EROFS_WHITEOUT_DEV;
531*33b1fccfSAndroid Build Coastguard Worker }
532*33b1fccfSAndroid Build Coastguard Worker
533*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
534*33b1fccfSAndroid Build Coastguard Worker }
535*33b1fccfSAndroid Build Coastguard Worker #endif
536*33b1fccfSAndroid Build Coastguard Worker
537*33b1fccfSAndroid Build Coastguard Worker #endif
538