1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
4 * https://www.huawei.com/
5 * Created by Gao Xiang <gaoxiang25@huawei.com>
7 #ifndef __EROFS_INTERNAL_H
8 #define __EROFS_INTERNAL_H
11 #include <linux/dcache.h>
13 #include <linux/pagemap.h>
14 #include <linux/bio.h>
15 #include <linux/buffer_head.h>
16 #include <linux/magic.h>
17 #include <linux/slab.h>
18 #include <linux/vmalloc.h>
21 /* redefine pr_fmt "erofs: " */
23 #define pr_fmt(fmt) "erofs: " fmt
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__)
33 #ifdef CONFIG_EROFS_FS_DEBUG
34 #define erofs_dbg(x, ...) pr_debug(x "\n", ##__VA_ARGS__)
35 #define DBG_BUGON BUG_ON
37 #define erofs_dbg(x, ...) ((void)0)
38 #define DBG_BUGON(x) ((void)(x))
39 #endif /* !CONFIG_EROFS_FS_DEBUG */
41 /* EROFS_SUPER_MAGIC_V1 to represent the whole file system */
42 #define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1
44 typedef u64 erofs_nid_t
;
45 typedef u64 erofs_off_t
;
46 /* data type for filesystem-wide blocks number */
47 typedef u32 erofs_blk_t
;
49 struct erofs_fs_context
{
50 #ifdef CONFIG_EROFS_FS_ZIP
51 /* current strategy of how to use managed cache */
52 unsigned char cache_strategy
;
54 /* threshold for decompression synchronously */
55 unsigned int max_sync_decompress_pages
;
57 unsigned int mount_opt
;
60 struct erofs_sb_info
{
61 #ifdef CONFIG_EROFS_FS_ZIP
62 /* list for all registered superblocks, mainly for shrinker */
63 struct list_head list
;
64 struct mutex umount_mutex
;
66 /* managed XArray arranged in physical block number */
67 struct xarray managed_pslots
;
69 unsigned int shrinker_run_no
;
71 /* pseudo inode to manage cached pages */
72 struct inode
*managed_cache
;
73 #endif /* CONFIG_EROFS_FS_ZIP */
76 #ifdef CONFIG_EROFS_FS_XATTR
80 /* inode slot unit size in bit shift */
81 unsigned char islotbits
;
86 /* what we really care is nid, rather than ino.. */
88 /* used for statfs, f_files - f_favail */
91 u8 uuid
[16]; /* 128-bit uuid for volume */
92 u8 volume_name
[16]; /* volume name */
96 struct erofs_fs_context ctx
; /* options */
99 #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
100 #define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)
102 /* Mount flags set via mount options or defaults */
103 #define EROFS_MOUNT_XATTR_USER 0x00000010
104 #define EROFS_MOUNT_POSIX_ACL 0x00000020
106 #define clear_opt(ctx, option) ((ctx)->mount_opt &= ~EROFS_MOUNT_##option)
107 #define set_opt(ctx, option) ((ctx)->mount_opt |= EROFS_MOUNT_##option)
108 #define test_opt(ctx, option) ((ctx)->mount_opt & EROFS_MOUNT_##option)
111 EROFS_ZIP_CACHE_DISABLED
,
112 EROFS_ZIP_CACHE_READAHEAD
,
113 EROFS_ZIP_CACHE_READAROUND
116 #ifdef CONFIG_EROFS_FS_ZIP
117 #define EROFS_LOCKED_MAGIC (INT_MIN | 0xE0F510CCL)
119 /* basic unit of the workstation of a super_block */
120 struct erofs_workgroup
{
121 /* the workgroup index in the workstation */
124 /* overall workgroup reference count */
128 #if defined(CONFIG_SMP)
129 static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup
*grp
,
133 if (val
!= atomic_cmpxchg(&grp
->refcount
, val
, EROFS_LOCKED_MAGIC
)) {
140 static inline void erofs_workgroup_unfreeze(struct erofs_workgroup
*grp
,
144 * other observers should notice all modifications
145 * in the freezing period.
148 atomic_set(&grp
->refcount
, orig_val
);
152 static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup
*grp
)
154 return atomic_cond_read_relaxed(&grp
->refcount
,
155 VAL
!= EROFS_LOCKED_MAGIC
);
158 static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup
*grp
,
162 /* no need to spin on UP platforms, let's just disable preemption. */
163 if (val
!= atomic_read(&grp
->refcount
)) {
170 static inline void erofs_workgroup_unfreeze(struct erofs_workgroup
*grp
,
176 static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup
*grp
)
178 int v
= atomic_read(&grp
->refcount
);
180 /* workgroup is never freezed on uniprocessor systems */
181 DBG_BUGON(v
== EROFS_LOCKED_MAGIC
);
184 #endif /* !CONFIG_SMP */
186 /* hard limit of pages per compressed cluster */
187 #define Z_EROFS_CLUSTER_MAX_PAGES (CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT)
188 #define EROFS_PCPUBUF_NR_PAGES Z_EROFS_CLUSTER_MAX_PAGES
190 #define EROFS_PCPUBUF_NR_PAGES 0
191 #endif /* !CONFIG_EROFS_FS_ZIP */
193 /* we strictly follow PAGE_SIZE and no buffer head yet */
194 #define LOG_BLOCK_SIZE PAGE_SHIFT
196 #undef LOG_SECTORS_PER_BLOCK
197 #define LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9)
199 #undef SECTORS_PER_BLOCK
200 #define SECTORS_PER_BLOCK (1 << SECTORS_PER_BLOCK)
202 #define EROFS_BLKSIZ (1 << LOG_BLOCK_SIZE)
204 #if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
205 #error erofs cannot be used in this platform
208 #define ROOT_NID(sb) ((sb)->root_nid)
210 #define erofs_blknr(addr) ((addr) / EROFS_BLKSIZ)
211 #define erofs_blkoff(addr) ((addr) % EROFS_BLKSIZ)
212 #define blknr_to_addr(nr) ((erofs_off_t)(nr) * EROFS_BLKSIZ)
214 static inline erofs_off_t
iloc(struct erofs_sb_info
*sbi
, erofs_nid_t nid
)
216 return blknr_to_addr(sbi
->meta_blkaddr
) + (nid
<< sbi
->islotbits
);
219 /* atomic flag definitions */
220 #define EROFS_I_EA_INITED_BIT 0
221 #define EROFS_I_Z_INITED_BIT 1
223 /* bitlock definitions (arranged in reverse order) */
224 #define EROFS_I_BL_XATTR_BIT (BITS_PER_LONG - 1)
225 #define EROFS_I_BL_Z_BIT (BITS_PER_LONG - 2)
230 /* atomic flags (including bitlocks) */
233 unsigned char datalayout
;
234 unsigned char inode_isize
;
235 unsigned short xattr_isize
;
237 unsigned int xattr_shared_count
;
238 unsigned int *xattr_shared_xattrs
;
241 erofs_blk_t raw_blkaddr
;
242 #ifdef CONFIG_EROFS_FS_ZIP
244 unsigned short z_advise
;
245 unsigned char z_algorithmtype
[2];
246 unsigned char z_logical_clusterbits
;
247 unsigned char z_physical_clusterbits
[2];
249 #endif /* CONFIG_EROFS_FS_ZIP */
251 /* the corresponding vfs inode */
252 struct inode vfs_inode
;
255 #define EROFS_I(ptr) \
256 container_of(ptr, struct erofs_inode, vfs_inode)
258 static inline unsigned long erofs_inode_datablocks(struct inode
*inode
)
260 /* since i_size cannot be changed */
261 return DIV_ROUND_UP(inode
->i_size
, EROFS_BLKSIZ
);
264 static inline unsigned int erofs_bitrange(unsigned int value
, unsigned int bit
,
268 return (value
>> bit
) & ((1 << bits
) - 1);
272 static inline unsigned int erofs_inode_version(unsigned int value
)
274 return erofs_bitrange(value
, EROFS_I_VERSION_BIT
,
275 EROFS_I_VERSION_BITS
);
278 static inline unsigned int erofs_inode_datalayout(unsigned int value
)
280 return erofs_bitrange(value
, EROFS_I_DATALAYOUT_BIT
,
281 EROFS_I_DATALAYOUT_BITS
);
284 extern const struct super_operations erofs_sops
;
286 extern const struct address_space_operations erofs_raw_access_aops
;
287 extern const struct address_space_operations z_erofs_aops
;
290 * Logical to physical block mapping, used by erofs_map_blocks()
292 * Different with other file systems, it is used for 2 access modes:
294 * 1) RAW access mode:
296 * Users pass a valid (m_lblk, m_lofs -- usually 0) pair,
297 * and get the valid m_pblk, m_pofs and the longest m_len(in bytes).
299 * Note that m_lblk in the RAW access mode refers to the number of
300 * the compressed ondisk block rather than the uncompressed
301 * in-memory block for the compressed file.
303 * m_pofs equals to m_lofs except for the inline data page.
305 * 2) Normal access mode:
307 * If the inode is not compressed, it has no difference with
308 * the RAW access mode. However, if the inode is compressed,
309 * users should pass a valid (m_lblk, m_lofs) pair, and get
310 * the needed m_pblk, m_pofs, m_len to get the compressed data
311 * and the updated m_lblk, m_lofs which indicates the start
312 * of the corresponding uncompressed data in the file.
315 BH_Zipped
= BH_PrivateStart
,
319 /* Has a disk mapping */
320 #define EROFS_MAP_MAPPED (1 << BH_Mapped)
321 /* Located in metadata (could be copied from bd_inode) */
322 #define EROFS_MAP_META (1 << BH_Meta)
323 /* The extent has been compressed */
324 #define EROFS_MAP_ZIPPED (1 << BH_Zipped)
325 /* The length of extent is full */
326 #define EROFS_MAP_FULL_MAPPED (1 << BH_FullMapped)
328 struct erofs_map_blocks
{
329 erofs_off_t m_pa
, m_la
;
332 unsigned int m_flags
;
337 /* Flags used by erofs_map_blocks() */
338 #define EROFS_GET_BLOCKS_RAW 0x0001
341 #ifdef CONFIG_EROFS_FS_ZIP
342 int z_erofs_fill_inode(struct inode
*inode
);
343 int z_erofs_map_blocks_iter(struct inode
*inode
,
344 struct erofs_map_blocks
*map
,
347 static inline int z_erofs_fill_inode(struct inode
*inode
) { return -EOPNOTSUPP
; }
348 static inline int z_erofs_map_blocks_iter(struct inode
*inode
,
349 struct erofs_map_blocks
*map
,
354 #endif /* !CONFIG_EROFS_FS_ZIP */
357 struct page
*erofs_get_meta_page(struct super_block
*sb
, erofs_blk_t blkaddr
);
359 int erofs_map_blocks(struct inode
*, struct erofs_map_blocks
*, int);
362 static inline unsigned long erofs_inode_hash(erofs_nid_t nid
)
364 #if BITS_PER_LONG == 32
365 return (nid
>> 32) ^ (nid
& 0xffffffff);
371 extern const struct inode_operations erofs_generic_iops
;
372 extern const struct inode_operations erofs_symlink_iops
;
373 extern const struct inode_operations erofs_fast_symlink_iops
;
375 struct inode
*erofs_iget(struct super_block
*sb
, erofs_nid_t nid
, bool dir
);
376 int erofs_getattr(const struct path
*path
, struct kstat
*stat
,
377 u32 request_mask
, unsigned int query_flags
);
380 extern const struct inode_operations erofs_dir_iops
;
382 int erofs_namei(struct inode
*dir
, struct qstr
*name
,
383 erofs_nid_t
*nid
, unsigned int *d_type
);
386 extern const struct file_operations erofs_dir_fops
;
388 /* utils.c / zdata.c */
389 struct page
*erofs_allocpage(struct list_head
*pool
, gfp_t gfp
);
391 #if (EROFS_PCPUBUF_NR_PAGES > 0)
392 void *erofs_get_pcpubuf(unsigned int pagenr
);
393 #define erofs_put_pcpubuf(buf) do { \
398 static inline void *erofs_get_pcpubuf(unsigned int pagenr
)
400 return ERR_PTR(-EOPNOTSUPP
);
403 #define erofs_put_pcpubuf(buf) do {} while (0)
406 #ifdef CONFIG_EROFS_FS_ZIP
407 int erofs_workgroup_put(struct erofs_workgroup
*grp
);
408 struct erofs_workgroup
*erofs_find_workgroup(struct super_block
*sb
,
410 struct erofs_workgroup
*erofs_insert_workgroup(struct super_block
*sb
,
411 struct erofs_workgroup
*grp
);
412 void erofs_workgroup_free_rcu(struct erofs_workgroup
*grp
);
413 void erofs_shrinker_register(struct super_block
*sb
);
414 void erofs_shrinker_unregister(struct super_block
*sb
);
415 int __init
erofs_init_shrinker(void);
416 void erofs_exit_shrinker(void);
417 int __init
z_erofs_init_zip_subsystem(void);
418 void z_erofs_exit_zip_subsystem(void);
419 int erofs_try_to_free_all_cached_pages(struct erofs_sb_info
*sbi
,
420 struct erofs_workgroup
*egrp
);
421 int erofs_try_to_free_cached_page(struct address_space
*mapping
,
424 static inline void erofs_shrinker_register(struct super_block
*sb
) {}
425 static inline void erofs_shrinker_unregister(struct super_block
*sb
) {}
426 static inline int erofs_init_shrinker(void) { return 0; }
427 static inline void erofs_exit_shrinker(void) {}
428 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
429 static inline void z_erofs_exit_zip_subsystem(void) {}
430 #endif /* !CONFIG_EROFS_FS_ZIP */
432 #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
434 #endif /* __EROFS_INTERNAL_H */