Commit | Line | Data |
---|---|---|
29b24f6c GX |
1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* | |
bfb8674d | 3 | * Copyright (C) 2017-2018 HUAWEI, Inc. |
592e7cd0 | 4 | * https://www.huawei.com/ |
c5aa903a | 5 | * Copyright (C) 2021, Alibaba Cloud |
bfb8674d | 6 | */ |
14f362b4 GX |
7 | #ifndef __EROFS_INTERNAL_H |
8 | #define __EROFS_INTERNAL_H | |
bfb8674d GX |
9 | |
10 | #include <linux/fs.h> | |
11 | #include <linux/dcache.h> | |
12 | #include <linux/mm.h> | |
13 | #include <linux/pagemap.h> | |
14 | #include <linux/bio.h> | |
15 | #include <linux/buffer_head.h> | |
47e4937a | 16 | #include <linux/magic.h> |
bfb8674d GX |
17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | |
eadcd6b5 | 19 | #include <linux/iomap.h> |
bfb8674d GX |
20 | #include "erofs_fs.h" |
21 | ||
22 | /* redefine pr_fmt "erofs: " */ | |
23 | #undef pr_fmt | |
24 | #define pr_fmt(fmt) "erofs: " fmt | |
25 | ||
4f761fa2 GX |
26 | __printf(3, 4) void _erofs_err(struct super_block *sb, |
27 | const char *function, const char *fmt, ...); | |
28 | #define erofs_err(sb, fmt, ...) \ | |
29 | _erofs_err(sb, __func__, fmt "\n", ##__VA_ARGS__) | |
30 | __printf(3, 4) void _erofs_info(struct super_block *sb, | |
31 | const char *function, const char *fmt, ...); | |
32 | #define erofs_info(sb, fmt, ...) \ | |
33 | _erofs_info(sb, __func__, fmt "\n", ##__VA_ARGS__) | |
bfb8674d | 34 | #ifdef CONFIG_EROFS_FS_DEBUG |
4f761fa2 | 35 | #define erofs_dbg(x, ...) pr_debug(x "\n", ##__VA_ARGS__) |
bfb8674d GX |
36 | #define DBG_BUGON BUG_ON |
37 | #else | |
4f761fa2 | 38 | #define erofs_dbg(x, ...) ((void)0) |
eef16878 | 39 | #define DBG_BUGON(x) ((void)(x)) |
14f362b4 | 40 | #endif /* !CONFIG_EROFS_FS_DEBUG */ |
bfb8674d GX |
41 | |
42 | /* EROFS_SUPER_MAGIC_V1 to represent the whole file system */ | |
43 | #define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1 | |
44 | ||
45 | typedef u64 erofs_nid_t; | |
14f362b4 GX |
46 | typedef u64 erofs_off_t; |
47 | /* data type for filesystem-wide blocks number */ | |
48 | typedef u32 erofs_blk_t; | |
bfb8674d | 49 | |
dfeab2e9 GX |
50 | struct erofs_device_info { |
51 | char *path; | |
955b478e | 52 | struct erofs_fscache *fscache; |
dfeab2e9 GX |
53 | struct block_device *bdev; |
54 | struct dax_device *dax_dev; | |
cd913c76 | 55 | u64 dax_part_off; |
dfeab2e9 GX |
56 | |
57 | u32 blocks; | |
58 | u32 mapped_blkaddr; | |
59 | }; | |
60 | ||
40452ffc HJ |
61 | enum { |
62 | EROFS_SYNC_DECOMPRESS_AUTO, | |
63 | EROFS_SYNC_DECOMPRESS_FORCE_ON, | |
64 | EROFS_SYNC_DECOMPRESS_FORCE_OFF | |
65 | }; | |
66 | ||
e6242465 | 67 | struct erofs_mount_opts { |
f57a3fe4 CY |
68 | #ifdef CONFIG_EROFS_FS_ZIP |
69 | /* current strategy of how to use managed cache */ | |
70 | unsigned char cache_strategy; | |
40452ffc HJ |
71 | /* strategy of sync decompression (0 - auto, 1 - force on, 2 - force off) */ |
72 | unsigned int sync_decompress; | |
f57a3fe4 CY |
73 | |
74 | /* threshold for decompression synchronously */ | |
75 | unsigned int max_sync_decompress_pages; | |
76 | #endif | |
77 | unsigned int mount_opt; | |
c6be2bd0 | 78 | char *fsid; |
f57a3fe4 CY |
79 | }; |
80 | ||
dfeab2e9 GX |
81 | struct erofs_dev_context { |
82 | struct idr tree; | |
83 | struct rw_semaphore rwsem; | |
84 | ||
85 | unsigned int extra_devices; | |
86 | }; | |
87 | ||
e6242465 GX |
88 | struct erofs_fs_context { |
89 | struct erofs_mount_opts opt; | |
dfeab2e9 | 90 | struct erofs_dev_context *devs; |
e6242465 GX |
91 | }; |
92 | ||
5d50538f HJ |
93 | /* all filesystem-wide lz4 configurations */ |
94 | struct erofs_sb_lz4_info { | |
95 | /* # of pages needed for EROFS lz4 rolling decompression */ | |
96 | u16 max_distance_pages; | |
4fea63f7 GX |
97 | /* maximum possible blocks for pclusters in the filesystem */ |
98 | u16 max_pclusterblks; | |
5d50538f HJ |
99 | }; |
100 | ||
b02c602f JX |
101 | struct erofs_fscache { |
102 | struct fscache_cookie *cookie; | |
3c265d7d | 103 | struct inode *inode; |
b02c602f JX |
104 | }; |
105 | ||
bfb8674d | 106 | struct erofs_sb_info { |
e6242465 | 107 | struct erofs_mount_opts opt; /* options */ |
22fe04a7 | 108 | #ifdef CONFIG_EROFS_FS_ZIP |
2497ee41 GX |
109 | /* list for all registered superblocks, mainly for shrinker */ |
110 | struct list_head list; | |
a1581312 | 111 | struct mutex umount_mutex; |
2497ee41 | 112 | |
64094a04 GX |
113 | /* managed XArray arranged in physical block number */ |
114 | struct xarray managed_pslots; | |
105d4ad8 | 115 | |
22fe04a7 | 116 | unsigned int shrinker_run_no; |
14373711 | 117 | u16 available_compr_algs; |
22fe04a7 | 118 | |
4279f3f9 GX |
119 | /* pseudo inode to manage cached pages */ |
120 | struct inode *managed_cache; | |
5d50538f HJ |
121 | |
122 | struct erofs_sb_lz4_info lz4; | |
22fe04a7 | 123 | #endif /* CONFIG_EROFS_FS_ZIP */ |
dfeab2e9 | 124 | struct erofs_dev_context *devs; |
06252e9c | 125 | struct dax_device *dax_dev; |
cd913c76 | 126 | u64 dax_part_off; |
dfeab2e9 GX |
127 | u64 total_blocks; |
128 | u32 primarydevice_blocks; | |
129 | ||
22fe04a7 GX |
130 | u32 meta_blkaddr; |
131 | #ifdef CONFIG_EROFS_FS_XATTR | |
132 | u32 xattr_blkaddr; | |
02827e17 | 133 | #endif |
dfeab2e9 | 134 | u16 device_id_mask; /* valid bits of device id to be used */ |
bfb8674d | 135 | |
22fe04a7 GX |
136 | /* inode slot unit size in bit shift */ |
137 | unsigned char islotbits; | |
138 | ||
14373711 | 139 | u32 sb_size; /* total superblock size */ |
bfb8674d GX |
140 | u32 build_time_nsec; |
141 | u64 build_time; | |
142 | ||
143 | /* what we really care is nid, rather than ino.. */ | |
144 | erofs_nid_t root_nid; | |
145 | /* used for statfs, f_files - f_favail */ | |
146 | u64 inos; | |
147 | ||
148 | u8 uuid[16]; /* 128-bit uuid for volume */ | |
149 | u8 volume_name[16]; /* volume name */ | |
b858a484 | 150 | u32 feature_compat; |
426a9308 | 151 | u32 feature_incompat; |
168e9a76 HJ |
152 | |
153 | /* sysfs support */ | |
154 | struct kobject s_kobj; /* /sys/fs/erofs/<devname> */ | |
155 | struct completion s_kobj_unregister; | |
c6be2bd0 JX |
156 | |
157 | /* fscache support */ | |
158 | struct fscache_volume *volume; | |
37c90c5f | 159 | struct erofs_fscache *s_fscache; |
bfb8674d GX |
160 | }; |
161 | ||
162 | #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) | |
163 | #define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info) | |
164 | ||
b17500a0 GX |
165 | /* Mount flags set via mount options or defaults */ |
166 | #define EROFS_MOUNT_XATTR_USER 0x00000010 | |
167 | #define EROFS_MOUNT_POSIX_ACL 0x00000020 | |
06252e9c GX |
168 | #define EROFS_MOUNT_DAX_ALWAYS 0x00000040 |
169 | #define EROFS_MOUNT_DAX_NEVER 0x00000080 | |
b17500a0 | 170 | |
e6242465 GX |
171 | #define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option) |
172 | #define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option) | |
173 | #define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option) | |
bfb8674d | 174 | |
93b856bb JX |
175 | static inline bool erofs_is_fscache_mode(struct super_block *sb) |
176 | { | |
177 | return IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && !sb->s_bdev; | |
178 | } | |
179 | ||
4279f3f9 GX |
180 | enum { |
181 | EROFS_ZIP_CACHE_DISABLED, | |
182 | EROFS_ZIP_CACHE_READAHEAD, | |
183 | EROFS_ZIP_CACHE_READAROUND | |
184 | }; | |
185 | ||
f57a3fe4 | 186 | #ifdef CONFIG_EROFS_FS_ZIP |
14f362b4 GX |
187 | #define EROFS_LOCKED_MAGIC (INT_MIN | 0xE0F510CCL) |
188 | ||
e7e9a307 GX |
189 | /* basic unit of the workstation of a super_block */ |
190 | struct erofs_workgroup { | |
191 | /* the workgroup index in the workstation */ | |
192 | pgoff_t index; | |
193 | ||
194 | /* overall workgroup reference count */ | |
195 | atomic_t refcount; | |
196 | }; | |
197 | ||
73f5c66d GX |
198 | #if defined(CONFIG_SMP) |
199 | static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp, | |
200 | int val) | |
e7e9a307 | 201 | { |
e7e9a307 | 202 | preempt_disable(); |
73f5c66d | 203 | if (val != atomic_cmpxchg(&grp->refcount, val, EROFS_LOCKED_MAGIC)) { |
e7e9a307 GX |
204 | preempt_enable(); |
205 | return false; | |
206 | } | |
e7e9a307 GX |
207 | return true; |
208 | } | |
209 | ||
73f5c66d GX |
210 | static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp, |
211 | int orig_val) | |
e7e9a307 | 212 | { |
948bbdb1 GX |
213 | /* |
214 | * other observers should notice all modifications | |
215 | * in the freezing period. | |
216 | */ | |
217 | smp_mb(); | |
73f5c66d | 218 | atomic_set(&grp->refcount, orig_val); |
e7e9a307 GX |
219 | preempt_enable(); |
220 | } | |
221 | ||
df134b8d GX |
222 | static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) |
223 | { | |
224 | return atomic_cond_read_relaxed(&grp->refcount, | |
225 | VAL != EROFS_LOCKED_MAGIC); | |
226 | } | |
227 | #else | |
73f5c66d GX |
228 | static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp, |
229 | int val) | |
230 | { | |
231 | preempt_disable(); | |
232 | /* no need to spin on UP platforms, let's just disable preemption. */ | |
233 | if (val != atomic_read(&grp->refcount)) { | |
234 | preempt_enable(); | |
235 | return false; | |
236 | } | |
237 | return true; | |
238 | } | |
239 | ||
240 | static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp, | |
241 | int orig_val) | |
242 | { | |
243 | preempt_enable(); | |
244 | } | |
245 | ||
df134b8d GX |
246 | static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp) |
247 | { | |
248 | int v = atomic_read(&grp->refcount); | |
249 | ||
250 | /* workgroup is never freezed on uniprocessor systems */ | |
251 | DBG_BUGON(v == EROFS_LOCKED_MAGIC); | |
252 | return v; | |
253 | } | |
14f362b4 | 254 | #endif /* !CONFIG_SMP */ |
14f362b4 | 255 | #endif /* !CONFIG_EROFS_FS_ZIP */ |
e7e9a307 | 256 | |
bfb8674d GX |
257 | /* we strictly follow PAGE_SIZE and no buffer head yet */ |
258 | #define LOG_BLOCK_SIZE PAGE_SHIFT | |
259 | ||
260 | #undef LOG_SECTORS_PER_BLOCK | |
261 | #define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) | |
262 | ||
263 | #undef SECTORS_PER_BLOCK | |
264 | #define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK) | |
265 | ||
266 | #define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE) | |
267 | ||
268 | #if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ) | |
269 | #error erofs cannot be used in this platform | |
270 | #endif | |
271 | ||
fdf80a47 GX |
272 | enum erofs_kmap_type { |
273 | EROFS_NO_KMAP, /* don't map the buffer */ | |
274 | EROFS_KMAP, /* use kmap() to map the buffer */ | |
275 | EROFS_KMAP_ATOMIC, /* use kmap_atomic() to map the buffer */ | |
276 | }; | |
277 | ||
278 | struct erofs_buf { | |
279 | struct page *page; | |
280 | void *base; | |
281 | enum erofs_kmap_type kmap_type; | |
282 | }; | |
283 | #define __EROFS_BUF_INITIALIZER ((struct erofs_buf){ .page = NULL }) | |
284 | ||
bfb8674d GX |
285 | #define ROOT_NID(sb) ((sb)->root_nid) |
286 | ||
bfb8674d GX |
287 | #define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ) |
288 | #define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ) | |
289 | #define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ) | |
290 | ||
291 | static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid) | |
292 | { | |
293 | return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits); | |
294 | } | |
295 | ||
de06a6a3 GX |
296 | #define EROFS_FEATURE_FUNCS(name, compat, feature) \ |
297 | static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \ | |
298 | { \ | |
299 | return sbi->feature_##compat & EROFS_FEATURE_##feature; \ | |
300 | } | |
301 | ||
7e508f2c | 302 | EROFS_FEATURE_FUNCS(zero_padding, incompat, INCOMPAT_ZERO_PADDING) |
14373711 | 303 | EROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS) |
5404c330 | 304 | EROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER) |
168e9a76 | 305 | EROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE) |
dfeab2e9 | 306 | EROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE) |
168e9a76 | 307 | EROFS_FEATURE_FUNCS(compr_head2, incompat, INCOMPAT_COMPR_HEAD2) |
ab92184f | 308 | EROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING) |
de06a6a3 GX |
309 | EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) |
310 | ||
62dc4597 | 311 | /* atomic flag definitions */ |
a5876e24 GX |
312 | #define EROFS_I_EA_INITED_BIT 0 |
313 | #define EROFS_I_Z_INITED_BIT 1 | |
62dc4597 GX |
314 | |
315 | /* bitlock definitions (arranged in reverse order) */ | |
a5876e24 GX |
316 | #define EROFS_I_BL_XATTR_BIT (BITS_PER_LONG - 1) |
317 | #define EROFS_I_BL_Z_BIT (BITS_PER_LONG - 2) | |
bfb8674d | 318 | |
a5876e24 | 319 | struct erofs_inode { |
bfb8674d | 320 | erofs_nid_t nid; |
62dc4597 GX |
321 | |
322 | /* atomic flags (including bitlocks) */ | |
323 | unsigned long flags; | |
bfb8674d | 324 | |
8a765682 | 325 | unsigned char datalayout; |
bfb8674d GX |
326 | unsigned char inode_isize; |
327 | unsigned short xattr_isize; | |
328 | ||
e82a9a17 PS |
329 | unsigned int xattr_shared_count; |
330 | unsigned int *xattr_shared_xattrs; | |
bfb8674d | 331 | |
152a333a GX |
332 | union { |
333 | erofs_blk_t raw_blkaddr; | |
c5aa903a GX |
334 | struct { |
335 | unsigned short chunkformat; | |
336 | unsigned char chunkbits; | |
337 | }; | |
152a333a GX |
338 | #ifdef CONFIG_EROFS_FS_ZIP |
339 | struct { | |
340 | unsigned short z_advise; | |
341 | unsigned char z_algorithmtype[2]; | |
342 | unsigned char z_logical_clusterbits; | |
ab92184f | 343 | unsigned long z_tailextent_headlcn; |
22ba5e99 | 344 | erofs_off_t z_idataoff; |
ab92184f | 345 | unsigned short z_idata_size; |
152a333a | 346 | }; |
14f362b4 | 347 | #endif /* CONFIG_EROFS_FS_ZIP */ |
152a333a | 348 | }; |
bfb8674d GX |
349 | /* the corresponding vfs inode */ |
350 | struct inode vfs_inode; | |
351 | }; | |
352 | ||
a5876e24 GX |
353 | #define EROFS_I(ptr) \ |
354 | container_of(ptr, struct erofs_inode, vfs_inode) | |
bfb8674d | 355 | |
99634bf3 | 356 | static inline unsigned long erofs_inode_datablocks(struct inode *inode) |
bfb8674d GX |
357 | { |
358 | /* since i_size cannot be changed */ | |
359 | return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); | |
360 | } | |
361 | ||
8a765682 GX |
362 | static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit, |
363 | unsigned int bits) | |
364 | { | |
365 | ||
366 | return (value >> bit) & ((1 << bits) - 1); | |
367 | } | |
368 | ||
369 | ||
370 | static inline unsigned int erofs_inode_version(unsigned int value) | |
bfb8674d | 371 | { |
8a765682 GX |
372 | return erofs_bitrange(value, EROFS_I_VERSION_BIT, |
373 | EROFS_I_VERSION_BITS); | |
bfb8674d GX |
374 | } |
375 | ||
8a765682 | 376 | static inline unsigned int erofs_inode_datalayout(unsigned int value) |
bfb8674d | 377 | { |
8a765682 GX |
378 | return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT, |
379 | EROFS_I_DATALAYOUT_BITS); | |
bfb8674d GX |
380 | } |
381 | ||
38629291 GX |
382 | /* |
383 | * Different from grab_cache_page_nowait(), reclaiming is never triggered | |
384 | * when allocating new pages. | |
385 | */ | |
386 | static inline | |
387 | struct page *erofs_grab_cache_page_nowait(struct address_space *mapping, | |
388 | pgoff_t index) | |
389 | { | |
390 | return pagecache_get_page(mapping, index, | |
391 | FGP_LOCK|FGP_CREAT|FGP_NOFS|FGP_NOWAIT, | |
392 | readahead_gfp_mask(mapping) & ~__GFP_RECLAIM); | |
393 | } | |
394 | ||
bfb8674d | 395 | extern const struct super_operations erofs_sops; |
bfb8674d GX |
396 | |
397 | extern const struct address_space_operations erofs_raw_access_aops; | |
0c638f70 | 398 | extern const struct address_space_operations z_erofs_aops; |
bfb8674d | 399 | |
bfb8674d | 400 | enum { |
8f899262 | 401 | BH_Encoded = BH_PrivateStart, |
b6a76183 | 402 | BH_FullMapped, |
bfb8674d GX |
403 | }; |
404 | ||
405 | /* Has a disk mapping */ | |
406 | #define EROFS_MAP_MAPPED (1 << BH_Mapped) | |
407 | /* Located in metadata (could be copied from bd_inode) */ | |
408 | #define EROFS_MAP_META (1 << BH_Meta) | |
8f899262 GX |
409 | /* The extent is encoded */ |
410 | #define EROFS_MAP_ENCODED (1 << BH_Encoded) | |
b6a76183 GX |
411 | /* The length of extent is full */ |
412 | #define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped) | |
bfb8674d GX |
413 | |
414 | struct erofs_map_blocks { | |
09c54379 GX |
415 | struct erofs_buf buf; |
416 | ||
bfb8674d GX |
417 | erofs_off_t m_pa, m_la; |
418 | u64 m_plen, m_llen; | |
419 | ||
dfeab2e9 | 420 | unsigned short m_deviceid; |
8f899262 | 421 | char m_algorithmformat; |
bfb8674d GX |
422 | unsigned int m_flags; |
423 | }; | |
424 | ||
8137824e | 425 | /* Flags used by erofs_map_blocks_flatmode() */ |
bfb8674d | 426 | #define EROFS_GET_BLOCKS_RAW 0x0001 |
d95ae5e2 GX |
427 | /* |
428 | * Used to get the exact decompressed length, e.g. fiemap (consider lookback | |
429 | * approach instead if possible since it's more metadata lightweight.) | |
430 | */ | |
431 | #define EROFS_GET_BLOCKS_FIEMAP 0x0002 | |
622ceadd GX |
432 | /* Used to map the whole extent if non-negligible data is requested for LZMA */ |
433 | #define EROFS_GET_BLOCKS_READMORE 0x0004 | |
ab92184f YH |
434 | /* Used to map tail extent for tailpacking inline pcluster */ |
435 | #define EROFS_GET_BLOCKS_FINDTAIL 0x0008 | |
bfb8674d | 436 | |
8f899262 GX |
437 | enum { |
438 | Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX, | |
439 | Z_EROFS_COMPRESSION_RUNTIME_MAX | |
440 | }; | |
441 | ||
152a333a | 442 | /* zmap.c */ |
eadcd6b5 GX |
443 | extern const struct iomap_ops z_erofs_iomap_report_ops; |
444 | ||
3b423417 | 445 | #ifdef CONFIG_EROFS_FS_ZIP |
152a333a | 446 | int z_erofs_fill_inode(struct inode *inode); |
3b423417 CY |
447 | int z_erofs_map_blocks_iter(struct inode *inode, |
448 | struct erofs_map_blocks *map, | |
449 | int flags); | |
450 | #else | |
ff784a78 | 451 | static inline int z_erofs_fill_inode(struct inode *inode) { return -EOPNOTSUPP; } |
3b423417 CY |
452 | static inline int z_erofs_map_blocks_iter(struct inode *inode, |
453 | struct erofs_map_blocks *map, | |
454 | int flags) | |
455 | { | |
ff784a78 | 456 | return -EOPNOTSUPP; |
3b423417 | 457 | } |
14f362b4 | 458 | #endif /* !CONFIG_EROFS_FS_ZIP */ |
3b423417 | 459 | |
dfeab2e9 | 460 | struct erofs_map_dev { |
955b478e | 461 | struct erofs_fscache *m_fscache; |
dfeab2e9 GX |
462 | struct block_device *m_bdev; |
463 | struct dax_device *m_daxdev; | |
de205114 | 464 | u64 m_dax_part_off; |
dfeab2e9 GX |
465 | |
466 | erofs_off_t m_pa; | |
467 | unsigned int m_deviceid; | |
468 | }; | |
469 | ||
bfb8674d | 470 | /* data.c */ |
a08e67a0 | 471 | extern const struct file_operations erofs_file_fops; |
09c54379 | 472 | void erofs_unmap_metabuf(struct erofs_buf *buf); |
c521e3ad | 473 | void erofs_put_metabuf(struct erofs_buf *buf); |
fe5de585 GX |
474 | void *erofs_bread(struct erofs_buf *buf, struct inode *inode, |
475 | erofs_blk_t blkaddr, enum erofs_kmap_type type); | |
c521e3ad GX |
476 | void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb, |
477 | erofs_blk_t blkaddr, enum erofs_kmap_type type); | |
dfeab2e9 | 478 | int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev); |
eadcd6b5 GX |
479 | int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
480 | u64 start, u64 len); | |
94d78946 JX |
481 | int erofs_map_blocks(struct inode *inode, |
482 | struct erofs_map_blocks *map, int flags); | |
6e78901a | 483 | |
bfb8674d | 484 | /* inode.c */ |
2abd7814 GX |
485 | static inline unsigned long erofs_inode_hash(erofs_nid_t nid) |
486 | { | |
487 | #if BITS_PER_LONG == 32 | |
488 | return (nid >> 32) ^ (nid & 0xffffffff); | |
489 | #else | |
490 | return nid; | |
491 | #endif | |
492 | } | |
493 | ||
60939826 GX |
494 | extern const struct inode_operations erofs_generic_iops; |
495 | extern const struct inode_operations erofs_symlink_iops; | |
496 | extern const struct inode_operations erofs_fast_symlink_iops; | |
b17500a0 | 497 | |
2e1d6637 | 498 | struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir); |
549c7297 CB |
499 | int erofs_getattr(struct user_namespace *mnt_userns, const struct path *path, |
500 | struct kstat *stat, u32 request_mask, | |
501 | unsigned int query_flags); | |
2e1d6637 | 502 | |
60939826 GX |
503 | /* namei.c */ |
504 | extern const struct inode_operations erofs_dir_iops; | |
505 | ||
3e917cc3 | 506 | int erofs_namei(struct inode *dir, const struct qstr *name, |
60939826 GX |
507 | erofs_nid_t *nid, unsigned int *d_type); |
508 | ||
509 | /* dir.c */ | |
510 | extern const struct file_operations erofs_dir_fops; | |
511 | ||
598162d0 GX |
512 | static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count) |
513 | { | |
514 | int retried = 0; | |
515 | ||
516 | while (1) { | |
517 | void *p = vm_map_ram(pages, count, -1); | |
518 | ||
519 | /* retry two more times (totally 3 times) */ | |
520 | if (p || ++retried >= 3) | |
521 | return p; | |
522 | vm_unmap_aliases(); | |
523 | } | |
524 | return NULL; | |
525 | } | |
526 | ||
52488734 GX |
527 | /* pcpubuf.c */ |
528 | void *erofs_get_pcpubuf(unsigned int requiredpages); | |
529 | void erofs_put_pcpubuf(void *ptr); | |
530 | int erofs_pcpubuf_growsize(unsigned int nrpages); | |
531 | void erofs_pcpubuf_init(void); | |
532 | void erofs_pcpubuf_exit(void); | |
533 | ||
168e9a76 HJ |
534 | /* sysfs.c */ |
535 | int erofs_register_sysfs(struct super_block *sb); | |
536 | void erofs_unregister_sysfs(struct super_block *sb); | |
537 | int __init erofs_init_sysfs(void); | |
538 | void erofs_exit_sysfs(void); | |
539 | ||
14f362b4 | 540 | /* utils.c / zdata.c */ |
eaa9172a GX |
541 | struct page *erofs_allocpage(struct page **pagepool, gfp_t gfp); |
542 | static inline void erofs_pagepool_add(struct page **pagepool, | |
543 | struct page *page) | |
544 | { | |
545 | set_page_private(page, (unsigned long)*pagepool); | |
546 | *pagepool = page; | |
547 | } | |
548 | void erofs_release_pages(struct page **pagepool); | |
fa61a33f | 549 | |
22fe04a7 | 550 | #ifdef CONFIG_EROFS_FS_ZIP |
14f362b4 GX |
551 | int erofs_workgroup_put(struct erofs_workgroup *grp); |
552 | struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, | |
997626d8 | 553 | pgoff_t index); |
64094a04 GX |
554 | struct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb, |
555 | struct erofs_workgroup *grp); | |
14f362b4 | 556 | void erofs_workgroup_free_rcu(struct erofs_workgroup *grp); |
22fe04a7 GX |
557 | void erofs_shrinker_register(struct super_block *sb); |
558 | void erofs_shrinker_unregister(struct super_block *sb); | |
559 | int __init erofs_init_shrinker(void); | |
560 | void erofs_exit_shrinker(void); | |
561 | int __init z_erofs_init_zip_subsystem(void); | |
562 | void z_erofs_exit_zip_subsystem(void); | |
14f362b4 GX |
563 | int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, |
564 | struct erofs_workgroup *egrp); | |
d252ff3d | 565 | int erofs_try_to_free_cached_page(struct page *page); |
5d50538f | 566 | int z_erofs_load_lz4_config(struct super_block *sb, |
46249cde GX |
567 | struct erofs_super_block *dsb, |
568 | struct z_erofs_lz4_cfgs *lz4, int len); | |
22fe04a7 GX |
569 | #else |
570 | static inline void erofs_shrinker_register(struct super_block *sb) {} | |
571 | static inline void erofs_shrinker_unregister(struct super_block *sb) {} | |
572 | static inline int erofs_init_shrinker(void) { return 0; } | |
573 | static inline void erofs_exit_shrinker(void) {} | |
574 | static inline int z_erofs_init_zip_subsystem(void) { return 0; } | |
575 | static inline void z_erofs_exit_zip_subsystem(void) {} | |
5d50538f | 576 | static inline int z_erofs_load_lz4_config(struct super_block *sb, |
46249cde GX |
577 | struct erofs_super_block *dsb, |
578 | struct z_erofs_lz4_cfgs *lz4, int len) | |
5d50538f | 579 | { |
14373711 | 580 | if (lz4 || dsb->u1.lz4_max_distance) { |
5d50538f HJ |
581 | erofs_err(sb, "lz4 algorithm isn't enabled"); |
582 | return -EINVAL; | |
583 | } | |
584 | return 0; | |
585 | } | |
22fe04a7 | 586 | #endif /* !CONFIG_EROFS_FS_ZIP */ |
2e1d6637 | 587 | |
622ceadd GX |
588 | #ifdef CONFIG_EROFS_FS_ZIP_LZMA |
589 | int z_erofs_lzma_init(void); | |
590 | void z_erofs_lzma_exit(void); | |
591 | int z_erofs_load_lzma_config(struct super_block *sb, | |
592 | struct erofs_super_block *dsb, | |
593 | struct z_erofs_lzma_cfgs *lzma, int size); | |
594 | #else | |
595 | static inline int z_erofs_lzma_init(void) { return 0; } | |
596 | static inline int z_erofs_lzma_exit(void) { return 0; } | |
597 | static inline int z_erofs_load_lzma_config(struct super_block *sb, | |
598 | struct erofs_super_block *dsb, | |
599 | struct z_erofs_lzma_cfgs *lzma, int size) { | |
600 | if (lzma) { | |
601 | erofs_err(sb, "lzma algorithm isn't enabled"); | |
602 | return -EINVAL; | |
603 | } | |
604 | return 0; | |
605 | } | |
606 | #endif /* !CONFIG_EROFS_FS_ZIP */ | |
607 | ||
c6be2bd0 JX |
608 | /* fscache.c */ |
609 | #ifdef CONFIG_EROFS_FS_ONDEMAND | |
610 | int erofs_fscache_register_fs(struct super_block *sb); | |
611 | void erofs_fscache_unregister_fs(struct super_block *sb); | |
b02c602f JX |
612 | |
613 | int erofs_fscache_register_cookie(struct super_block *sb, | |
3c265d7d JX |
614 | struct erofs_fscache **fscache, |
615 | char *name, bool need_inode); | |
b02c602f | 616 | void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache); |
1442b02b JX |
617 | |
618 | extern const struct address_space_operations erofs_fscache_access_aops; | |
c6be2bd0 JX |
619 | #else |
620 | static inline int erofs_fscache_register_fs(struct super_block *sb) | |
621 | { | |
622 | return 0; | |
623 | } | |
624 | static inline void erofs_fscache_unregister_fs(struct super_block *sb) {} | |
b02c602f JX |
625 | |
626 | static inline int erofs_fscache_register_cookie(struct super_block *sb, | |
627 | struct erofs_fscache **fscache, | |
3c265d7d | 628 | char *name, bool need_inode) |
b02c602f JX |
629 | { |
630 | return -EOPNOTSUPP; | |
631 | } | |
632 | ||
633 | static inline void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache) | |
634 | { | |
635 | } | |
c6be2bd0 JX |
636 | #endif |
637 | ||
a6b9b1d5 GX |
638 | #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ |
639 | ||
14f362b4 | 640 | #endif /* __EROFS_INTERNAL_H */ |