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