162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2017-2018 HUAWEI, Inc. 462306a36Sopenharmony_ci * https://www.huawei.com/ 562306a36Sopenharmony_ci * Copyright (C) 2021, Alibaba Cloud 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#ifndef __EROFS_INTERNAL_H 862306a36Sopenharmony_ci#define __EROFS_INTERNAL_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/fs.h> 1162306a36Sopenharmony_ci#include <linux/dcache.h> 1262306a36Sopenharmony_ci#include <linux/mm.h> 1362306a36Sopenharmony_ci#include <linux/pagemap.h> 1462306a36Sopenharmony_ci#include <linux/bio.h> 1562306a36Sopenharmony_ci#include <linux/magic.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/vmalloc.h> 1862306a36Sopenharmony_ci#include <linux/iomap.h> 1962306a36Sopenharmony_ci#include "erofs_fs.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* redefine pr_fmt "erofs: " */ 2262306a36Sopenharmony_ci#undef pr_fmt 2362306a36Sopenharmony_ci#define pr_fmt(fmt) "erofs: " fmt 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci__printf(3, 4) void _erofs_err(struct super_block *sb, 2662306a36Sopenharmony_ci const char *function, const char *fmt, ...); 2762306a36Sopenharmony_ci#define erofs_err(sb, fmt, ...) \ 2862306a36Sopenharmony_ci _erofs_err(sb, __func__, fmt "\n", ##__VA_ARGS__) 2962306a36Sopenharmony_ci__printf(3, 4) void _erofs_info(struct super_block *sb, 3062306a36Sopenharmony_ci const char *function, const char *fmt, ...); 3162306a36Sopenharmony_ci#define erofs_info(sb, fmt, ...) \ 3262306a36Sopenharmony_ci _erofs_info(sb, __func__, fmt "\n", ##__VA_ARGS__) 3362306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_DEBUG 3462306a36Sopenharmony_ci#define DBG_BUGON BUG_ON 3562306a36Sopenharmony_ci#else 3662306a36Sopenharmony_ci#define DBG_BUGON(x) ((void)(x)) 3762306a36Sopenharmony_ci#endif /* !CONFIG_EROFS_FS_DEBUG */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* EROFS_SUPER_MAGIC_V1 to represent the whole file system */ 4062306a36Sopenharmony_ci#define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_citypedef u64 erofs_nid_t; 4362306a36Sopenharmony_citypedef u64 erofs_off_t; 4462306a36Sopenharmony_ci/* data type for filesystem-wide blocks number */ 4562306a36Sopenharmony_citypedef u32 erofs_blk_t; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistruct erofs_device_info { 4862306a36Sopenharmony_ci char *path; 4962306a36Sopenharmony_ci struct erofs_fscache *fscache; 5062306a36Sopenharmony_ci struct bdev_handle *bdev_handle; 5162306a36Sopenharmony_ci struct dax_device *dax_dev; 5262306a36Sopenharmony_ci u64 dax_part_off; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci u32 blocks; 5562306a36Sopenharmony_ci u32 mapped_blkaddr; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cienum { 5962306a36Sopenharmony_ci EROFS_SYNC_DECOMPRESS_AUTO, 6062306a36Sopenharmony_ci EROFS_SYNC_DECOMPRESS_FORCE_ON, 6162306a36Sopenharmony_ci EROFS_SYNC_DECOMPRESS_FORCE_OFF 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistruct erofs_mount_opts { 6562306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP 6662306a36Sopenharmony_ci /* current strategy of how to use managed cache */ 6762306a36Sopenharmony_ci unsigned char cache_strategy; 6862306a36Sopenharmony_ci /* strategy of sync decompression (0 - auto, 1 - force on, 2 - force off) */ 6962306a36Sopenharmony_ci unsigned int sync_decompress; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* threshold for decompression synchronously */ 7262306a36Sopenharmony_ci unsigned int max_sync_decompress_pages; 7362306a36Sopenharmony_ci#endif 7462306a36Sopenharmony_ci unsigned int mount_opt; 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistruct erofs_dev_context { 7862306a36Sopenharmony_ci struct idr tree; 7962306a36Sopenharmony_ci struct rw_semaphore rwsem; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci unsigned int extra_devices; 8262306a36Sopenharmony_ci bool flatdev; 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistruct erofs_fs_context { 8662306a36Sopenharmony_ci struct erofs_mount_opts opt; 8762306a36Sopenharmony_ci struct erofs_dev_context *devs; 8862306a36Sopenharmony_ci char *fsid; 8962306a36Sopenharmony_ci char *domain_id; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* all filesystem-wide lz4 configurations */ 9362306a36Sopenharmony_cistruct erofs_sb_lz4_info { 9462306a36Sopenharmony_ci /* # of pages needed for EROFS lz4 rolling decompression */ 9562306a36Sopenharmony_ci u16 max_distance_pages; 9662306a36Sopenharmony_ci /* maximum possible blocks for pclusters in the filesystem */ 9762306a36Sopenharmony_ci u16 max_pclusterblks; 9862306a36Sopenharmony_ci}; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistruct erofs_domain { 10162306a36Sopenharmony_ci refcount_t ref; 10262306a36Sopenharmony_ci struct list_head list; 10362306a36Sopenharmony_ci struct fscache_volume *volume; 10462306a36Sopenharmony_ci char *domain_id; 10562306a36Sopenharmony_ci}; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistruct erofs_fscache { 10862306a36Sopenharmony_ci struct fscache_cookie *cookie; 10962306a36Sopenharmony_ci struct inode *inode; /* anonymous inode for the blob */ 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci /* used for share domain mode */ 11262306a36Sopenharmony_ci struct erofs_domain *domain; 11362306a36Sopenharmony_ci struct list_head node; 11462306a36Sopenharmony_ci refcount_t ref; 11562306a36Sopenharmony_ci char *name; 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistruct erofs_xattr_prefix_item { 11962306a36Sopenharmony_ci struct erofs_xattr_long_prefix *prefix; 12062306a36Sopenharmony_ci u8 infix_len; 12162306a36Sopenharmony_ci}; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistruct erofs_sb_info { 12462306a36Sopenharmony_ci struct erofs_mount_opts opt; /* options */ 12562306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP 12662306a36Sopenharmony_ci /* list for all registered superblocks, mainly for shrinker */ 12762306a36Sopenharmony_ci struct list_head list; 12862306a36Sopenharmony_ci struct mutex umount_mutex; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* managed XArray arranged in physical block number */ 13162306a36Sopenharmony_ci struct xarray managed_pslots; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci unsigned int shrinker_run_no; 13462306a36Sopenharmony_ci u16 available_compr_algs; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /* pseudo inode to manage cached pages */ 13762306a36Sopenharmony_ci struct inode *managed_cache; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci struct erofs_sb_lz4_info lz4; 14062306a36Sopenharmony_ci#endif /* CONFIG_EROFS_FS_ZIP */ 14162306a36Sopenharmony_ci struct inode *packed_inode; 14262306a36Sopenharmony_ci struct erofs_dev_context *devs; 14362306a36Sopenharmony_ci struct dax_device *dax_dev; 14462306a36Sopenharmony_ci u64 dax_part_off; 14562306a36Sopenharmony_ci u64 total_blocks; 14662306a36Sopenharmony_ci u32 primarydevice_blocks; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci u32 meta_blkaddr; 14962306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_XATTR 15062306a36Sopenharmony_ci u32 xattr_blkaddr; 15162306a36Sopenharmony_ci u32 xattr_prefix_start; 15262306a36Sopenharmony_ci u8 xattr_prefix_count; 15362306a36Sopenharmony_ci struct erofs_xattr_prefix_item *xattr_prefixes; 15462306a36Sopenharmony_ci unsigned int xattr_filter_reserved; 15562306a36Sopenharmony_ci#endif 15662306a36Sopenharmony_ci u16 device_id_mask; /* valid bits of device id to be used */ 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci unsigned char islotbits; /* inode slot unit size in bit shift */ 15962306a36Sopenharmony_ci unsigned char blkszbits; /* filesystem block size in bit shift */ 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci u32 sb_size; /* total superblock size */ 16262306a36Sopenharmony_ci u32 build_time_nsec; 16362306a36Sopenharmony_ci u64 build_time; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci /* what we really care is nid, rather than ino.. */ 16662306a36Sopenharmony_ci erofs_nid_t root_nid; 16762306a36Sopenharmony_ci erofs_nid_t packed_nid; 16862306a36Sopenharmony_ci /* used for statfs, f_files - f_favail */ 16962306a36Sopenharmony_ci u64 inos; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci u8 uuid[16]; /* 128-bit uuid for volume */ 17262306a36Sopenharmony_ci u8 volume_name[16]; /* volume name */ 17362306a36Sopenharmony_ci u32 feature_compat; 17462306a36Sopenharmony_ci u32 feature_incompat; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* sysfs support */ 17762306a36Sopenharmony_ci struct kobject s_kobj; /* /sys/fs/erofs/<devname> */ 17862306a36Sopenharmony_ci struct completion s_kobj_unregister; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* fscache support */ 18162306a36Sopenharmony_ci struct fscache_volume *volume; 18262306a36Sopenharmony_ci struct erofs_fscache *s_fscache; 18362306a36Sopenharmony_ci struct erofs_domain *domain; 18462306a36Sopenharmony_ci char *fsid; 18562306a36Sopenharmony_ci char *domain_id; 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) 18962306a36Sopenharmony_ci#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info) 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* Mount flags set via mount options or defaults */ 19262306a36Sopenharmony_ci#define EROFS_MOUNT_XATTR_USER 0x00000010 19362306a36Sopenharmony_ci#define EROFS_MOUNT_POSIX_ACL 0x00000020 19462306a36Sopenharmony_ci#define EROFS_MOUNT_DAX_ALWAYS 0x00000040 19562306a36Sopenharmony_ci#define EROFS_MOUNT_DAX_NEVER 0x00000080 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option) 19862306a36Sopenharmony_ci#define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option) 19962306a36Sopenharmony_ci#define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic inline bool erofs_is_fscache_mode(struct super_block *sb) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci return IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && !sb->s_bdev; 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cienum { 20762306a36Sopenharmony_ci EROFS_ZIP_CACHE_DISABLED, 20862306a36Sopenharmony_ci EROFS_ZIP_CACHE_READAHEAD, 20962306a36Sopenharmony_ci EROFS_ZIP_CACHE_READAROUND 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* basic unit of the workstation of a super_block */ 21362306a36Sopenharmony_cistruct erofs_workgroup { 21462306a36Sopenharmony_ci pgoff_t index; 21562306a36Sopenharmony_ci struct lockref lockref; 21662306a36Sopenharmony_ci}; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cienum erofs_kmap_type { 21962306a36Sopenharmony_ci EROFS_NO_KMAP, /* don't map the buffer */ 22062306a36Sopenharmony_ci EROFS_KMAP, /* use kmap_local_page() to map the buffer */ 22162306a36Sopenharmony_ci}; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cistruct erofs_buf { 22462306a36Sopenharmony_ci struct inode *inode; 22562306a36Sopenharmony_ci struct page *page; 22662306a36Sopenharmony_ci void *base; 22762306a36Sopenharmony_ci enum erofs_kmap_type kmap_type; 22862306a36Sopenharmony_ci}; 22962306a36Sopenharmony_ci#define __EROFS_BUF_INITIALIZER ((struct erofs_buf){ .page = NULL }) 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci#define ROOT_NID(sb) ((sb)->root_nid) 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci#define erofs_blknr(sb, addr) ((addr) >> (sb)->s_blocksize_bits) 23462306a36Sopenharmony_ci#define erofs_blkoff(sb, addr) ((addr) & ((sb)->s_blocksize - 1)) 23562306a36Sopenharmony_ci#define erofs_pos(sb, blk) ((erofs_off_t)(blk) << (sb)->s_blocksize_bits) 23662306a36Sopenharmony_ci#define erofs_iblks(i) (round_up((i)->i_size, i_blocksize(i)) >> (i)->i_blkbits) 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#define EROFS_FEATURE_FUNCS(name, compat, feature) \ 23962306a36Sopenharmony_cistatic inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \ 24062306a36Sopenharmony_ci{ \ 24162306a36Sopenharmony_ci return sbi->feature_##compat & EROFS_FEATURE_##feature; \ 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(zero_padding, incompat, INCOMPAT_ZERO_PADDING) 24562306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(compr_cfgs, incompat, INCOMPAT_COMPR_CFGS) 24662306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(big_pcluster, incompat, INCOMPAT_BIG_PCLUSTER) 24762306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(chunked_file, incompat, INCOMPAT_CHUNKED_FILE) 24862306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(device_table, incompat, INCOMPAT_DEVICE_TABLE) 24962306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(compr_head2, incompat, INCOMPAT_COMPR_HEAD2) 25062306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(ztailpacking, incompat, INCOMPAT_ZTAILPACKING) 25162306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS) 25262306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE) 25362306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES) 25462306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) 25562306a36Sopenharmony_ciEROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER) 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci/* atomic flag definitions */ 25862306a36Sopenharmony_ci#define EROFS_I_EA_INITED_BIT 0 25962306a36Sopenharmony_ci#define EROFS_I_Z_INITED_BIT 1 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/* bitlock definitions (arranged in reverse order) */ 26262306a36Sopenharmony_ci#define EROFS_I_BL_XATTR_BIT (BITS_PER_LONG - 1) 26362306a36Sopenharmony_ci#define EROFS_I_BL_Z_BIT (BITS_PER_LONG - 2) 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistruct erofs_inode { 26662306a36Sopenharmony_ci erofs_nid_t nid; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* atomic flags (including bitlocks) */ 26962306a36Sopenharmony_ci unsigned long flags; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci unsigned char datalayout; 27262306a36Sopenharmony_ci unsigned char inode_isize; 27362306a36Sopenharmony_ci unsigned int xattr_isize; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci unsigned int xattr_name_filter; 27662306a36Sopenharmony_ci unsigned int xattr_shared_count; 27762306a36Sopenharmony_ci unsigned int *xattr_shared_xattrs; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci union { 28062306a36Sopenharmony_ci erofs_blk_t raw_blkaddr; 28162306a36Sopenharmony_ci struct { 28262306a36Sopenharmony_ci unsigned short chunkformat; 28362306a36Sopenharmony_ci unsigned char chunkbits; 28462306a36Sopenharmony_ci }; 28562306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP 28662306a36Sopenharmony_ci struct { 28762306a36Sopenharmony_ci unsigned short z_advise; 28862306a36Sopenharmony_ci unsigned char z_algorithmtype[2]; 28962306a36Sopenharmony_ci unsigned char z_logical_clusterbits; 29062306a36Sopenharmony_ci unsigned long z_tailextent_headlcn; 29162306a36Sopenharmony_ci union { 29262306a36Sopenharmony_ci struct { 29362306a36Sopenharmony_ci erofs_off_t z_idataoff; 29462306a36Sopenharmony_ci unsigned short z_idata_size; 29562306a36Sopenharmony_ci }; 29662306a36Sopenharmony_ci erofs_off_t z_fragmentoff; 29762306a36Sopenharmony_ci }; 29862306a36Sopenharmony_ci }; 29962306a36Sopenharmony_ci#endif /* CONFIG_EROFS_FS_ZIP */ 30062306a36Sopenharmony_ci }; 30162306a36Sopenharmony_ci /* the corresponding vfs inode */ 30262306a36Sopenharmony_ci struct inode vfs_inode; 30362306a36Sopenharmony_ci}; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci#define EROFS_I(ptr) container_of(ptr, struct erofs_inode, vfs_inode) 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic inline erofs_off_t erofs_iloc(struct inode *inode) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct erofs_sb_info *sbi = EROFS_I_SB(inode); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci return erofs_pos(inode->i_sb, sbi->meta_blkaddr) + 31262306a36Sopenharmony_ci (EROFS_I(inode)->nid << sbi->islotbits); 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic inline unsigned int erofs_inode_version(unsigned int ifmt) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci return (ifmt >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASK; 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic inline unsigned int erofs_inode_datalayout(unsigned int ifmt) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci return (ifmt >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASK; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/* 32662306a36Sopenharmony_ci * Different from grab_cache_page_nowait(), reclaiming is never triggered 32762306a36Sopenharmony_ci * when allocating new pages. 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_cistatic inline 33062306a36Sopenharmony_cistruct page *erofs_grab_cache_page_nowait(struct address_space *mapping, 33162306a36Sopenharmony_ci pgoff_t index) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci return pagecache_get_page(mapping, index, 33462306a36Sopenharmony_ci FGP_LOCK|FGP_CREAT|FGP_NOFS|FGP_NOWAIT, 33562306a36Sopenharmony_ci readahead_gfp_mask(mapping) & ~__GFP_RECLAIM); 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci/* Has a disk mapping */ 33962306a36Sopenharmony_ci#define EROFS_MAP_MAPPED 0x0001 34062306a36Sopenharmony_ci/* Located in metadata (could be copied from bd_inode) */ 34162306a36Sopenharmony_ci#define EROFS_MAP_META 0x0002 34262306a36Sopenharmony_ci/* The extent is encoded */ 34362306a36Sopenharmony_ci#define EROFS_MAP_ENCODED 0x0004 34462306a36Sopenharmony_ci/* The length of extent is full */ 34562306a36Sopenharmony_ci#define EROFS_MAP_FULL_MAPPED 0x0008 34662306a36Sopenharmony_ci/* Located in the special packed inode */ 34762306a36Sopenharmony_ci#define EROFS_MAP_FRAGMENT 0x0010 34862306a36Sopenharmony_ci/* The extent refers to partial decompressed data */ 34962306a36Sopenharmony_ci#define EROFS_MAP_PARTIAL_REF 0x0020 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistruct erofs_map_blocks { 35262306a36Sopenharmony_ci struct erofs_buf buf; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci erofs_off_t m_pa, m_la; 35562306a36Sopenharmony_ci u64 m_plen, m_llen; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci unsigned short m_deviceid; 35862306a36Sopenharmony_ci char m_algorithmformat; 35962306a36Sopenharmony_ci unsigned int m_flags; 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/* 36362306a36Sopenharmony_ci * Used to get the exact decompressed length, e.g. fiemap (consider lookback 36462306a36Sopenharmony_ci * approach instead if possible since it's more metadata lightweight.) 36562306a36Sopenharmony_ci */ 36662306a36Sopenharmony_ci#define EROFS_GET_BLOCKS_FIEMAP 0x0001 36762306a36Sopenharmony_ci/* Used to map the whole extent if non-negligible data is requested for LZMA */ 36862306a36Sopenharmony_ci#define EROFS_GET_BLOCKS_READMORE 0x0002 36962306a36Sopenharmony_ci/* Used to map tail extent for tailpacking inline or fragment pcluster */ 37062306a36Sopenharmony_ci#define EROFS_GET_BLOCKS_FINDTAIL 0x0004 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cienum { 37362306a36Sopenharmony_ci Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX, 37462306a36Sopenharmony_ci Z_EROFS_COMPRESSION_INTERLACED, 37562306a36Sopenharmony_ci Z_EROFS_COMPRESSION_RUNTIME_MAX 37662306a36Sopenharmony_ci}; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistruct erofs_map_dev { 37962306a36Sopenharmony_ci struct erofs_fscache *m_fscache; 38062306a36Sopenharmony_ci struct block_device *m_bdev; 38162306a36Sopenharmony_ci struct dax_device *m_daxdev; 38262306a36Sopenharmony_ci u64 m_dax_part_off; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci erofs_off_t m_pa; 38562306a36Sopenharmony_ci unsigned int m_deviceid; 38662306a36Sopenharmony_ci}; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ciextern const struct super_operations erofs_sops; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ciextern const struct address_space_operations erofs_raw_access_aops; 39162306a36Sopenharmony_ciextern const struct address_space_operations z_erofs_aops; 39262306a36Sopenharmony_ciextern const struct address_space_operations erofs_fscache_access_aops; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciextern const struct inode_operations erofs_generic_iops; 39562306a36Sopenharmony_ciextern const struct inode_operations erofs_symlink_iops; 39662306a36Sopenharmony_ciextern const struct inode_operations erofs_fast_symlink_iops; 39762306a36Sopenharmony_ciextern const struct inode_operations erofs_dir_iops; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ciextern const struct file_operations erofs_file_fops; 40062306a36Sopenharmony_ciextern const struct file_operations erofs_dir_fops; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ciextern const struct iomap_ops z_erofs_iomap_report_ops; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci/* flags for erofs_fscache_register_cookie() */ 40562306a36Sopenharmony_ci#define EROFS_REG_COOKIE_SHARE 0x0001 40662306a36Sopenharmony_ci#define EROFS_REG_COOKIE_NEED_NOEXIST 0x0002 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_civoid *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf, 40962306a36Sopenharmony_ci erofs_off_t *offset, int *lengthp); 41062306a36Sopenharmony_civoid erofs_unmap_metabuf(struct erofs_buf *buf); 41162306a36Sopenharmony_civoid erofs_put_metabuf(struct erofs_buf *buf); 41262306a36Sopenharmony_civoid *erofs_bread(struct erofs_buf *buf, erofs_blk_t blkaddr, 41362306a36Sopenharmony_ci enum erofs_kmap_type type); 41462306a36Sopenharmony_civoid erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb); 41562306a36Sopenharmony_civoid *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb, 41662306a36Sopenharmony_ci erofs_blk_t blkaddr, enum erofs_kmap_type type); 41762306a36Sopenharmony_ciint erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev); 41862306a36Sopenharmony_ciint erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 41962306a36Sopenharmony_ci u64 start, u64 len); 42062306a36Sopenharmony_ciint erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map); 42162306a36Sopenharmony_cistruct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid); 42262306a36Sopenharmony_ciint erofs_getattr(struct mnt_idmap *idmap, const struct path *path, 42362306a36Sopenharmony_ci struct kstat *stat, u32 request_mask, 42462306a36Sopenharmony_ci unsigned int query_flags); 42562306a36Sopenharmony_ciint erofs_namei(struct inode *dir, const struct qstr *name, 42662306a36Sopenharmony_ci erofs_nid_t *nid, unsigned int *d_type); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic inline void *erofs_vm_map_ram(struct page **pages, unsigned int count) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci int retried = 0; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci while (1) { 43362306a36Sopenharmony_ci void *p = vm_map_ram(pages, count, -1); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci /* retry two more times (totally 3 times) */ 43662306a36Sopenharmony_ci if (p || ++retried >= 3) 43762306a36Sopenharmony_ci return p; 43862306a36Sopenharmony_ci vm_unmap_aliases(); 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci return NULL; 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ciint erofs_register_sysfs(struct super_block *sb); 44462306a36Sopenharmony_civoid erofs_unregister_sysfs(struct super_block *sb); 44562306a36Sopenharmony_ciint __init erofs_init_sysfs(void); 44662306a36Sopenharmony_civoid erofs_exit_sysfs(void); 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_cistruct page *erofs_allocpage(struct page **pagepool, gfp_t gfp); 44962306a36Sopenharmony_cistatic inline void erofs_pagepool_add(struct page **pagepool, struct page *page) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci set_page_private(page, (unsigned long)*pagepool); 45262306a36Sopenharmony_ci *pagepool = page; 45362306a36Sopenharmony_ci} 45462306a36Sopenharmony_civoid erofs_release_pages(struct page **pagepool); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP 45762306a36Sopenharmony_civoid erofs_workgroup_put(struct erofs_workgroup *grp); 45862306a36Sopenharmony_cistruct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, 45962306a36Sopenharmony_ci pgoff_t index); 46062306a36Sopenharmony_cistruct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb, 46162306a36Sopenharmony_ci struct erofs_workgroup *grp); 46262306a36Sopenharmony_civoid erofs_workgroup_free_rcu(struct erofs_workgroup *grp); 46362306a36Sopenharmony_civoid erofs_shrinker_register(struct super_block *sb); 46462306a36Sopenharmony_civoid erofs_shrinker_unregister(struct super_block *sb); 46562306a36Sopenharmony_ciint __init erofs_init_shrinker(void); 46662306a36Sopenharmony_civoid erofs_exit_shrinker(void); 46762306a36Sopenharmony_ciint __init z_erofs_init_zip_subsystem(void); 46862306a36Sopenharmony_civoid z_erofs_exit_zip_subsystem(void); 46962306a36Sopenharmony_ciint erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, 47062306a36Sopenharmony_ci struct erofs_workgroup *egrp); 47162306a36Sopenharmony_ciint z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, 47262306a36Sopenharmony_ci int flags); 47362306a36Sopenharmony_civoid *erofs_get_pcpubuf(unsigned int requiredpages); 47462306a36Sopenharmony_civoid erofs_put_pcpubuf(void *ptr); 47562306a36Sopenharmony_ciint erofs_pcpubuf_growsize(unsigned int nrpages); 47662306a36Sopenharmony_civoid __init erofs_pcpubuf_init(void); 47762306a36Sopenharmony_civoid erofs_pcpubuf_exit(void); 47862306a36Sopenharmony_ciint erofs_init_managed_cache(struct super_block *sb); 47962306a36Sopenharmony_ciint z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb); 48062306a36Sopenharmony_ci#else 48162306a36Sopenharmony_cistatic inline void erofs_shrinker_register(struct super_block *sb) {} 48262306a36Sopenharmony_cistatic inline void erofs_shrinker_unregister(struct super_block *sb) {} 48362306a36Sopenharmony_cistatic inline int erofs_init_shrinker(void) { return 0; } 48462306a36Sopenharmony_cistatic inline void erofs_exit_shrinker(void) {} 48562306a36Sopenharmony_cistatic inline int z_erofs_init_zip_subsystem(void) { return 0; } 48662306a36Sopenharmony_cistatic inline void z_erofs_exit_zip_subsystem(void) {} 48762306a36Sopenharmony_cistatic inline void erofs_pcpubuf_init(void) {} 48862306a36Sopenharmony_cistatic inline void erofs_pcpubuf_exit(void) {} 48962306a36Sopenharmony_cistatic inline int erofs_init_managed_cache(struct super_block *sb) { return 0; } 49062306a36Sopenharmony_ci#endif /* !CONFIG_EROFS_FS_ZIP */ 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP_LZMA 49362306a36Sopenharmony_ciint __init z_erofs_lzma_init(void); 49462306a36Sopenharmony_civoid z_erofs_lzma_exit(void); 49562306a36Sopenharmony_ci#else 49662306a36Sopenharmony_cistatic inline int z_erofs_lzma_init(void) { return 0; } 49762306a36Sopenharmony_cistatic inline int z_erofs_lzma_exit(void) { return 0; } 49862306a36Sopenharmony_ci#endif /* !CONFIG_EROFS_FS_ZIP_LZMA */ 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ZIP_DEFLATE 50162306a36Sopenharmony_ciint __init z_erofs_deflate_init(void); 50262306a36Sopenharmony_civoid z_erofs_deflate_exit(void); 50362306a36Sopenharmony_ci#else 50462306a36Sopenharmony_cistatic inline int z_erofs_deflate_init(void) { return 0; } 50562306a36Sopenharmony_cistatic inline int z_erofs_deflate_exit(void) { return 0; } 50662306a36Sopenharmony_ci#endif /* !CONFIG_EROFS_FS_ZIP_DEFLATE */ 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci#ifdef CONFIG_EROFS_FS_ONDEMAND 50962306a36Sopenharmony_ciint erofs_fscache_register_fs(struct super_block *sb); 51062306a36Sopenharmony_civoid erofs_fscache_unregister_fs(struct super_block *sb); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_cistruct erofs_fscache *erofs_fscache_register_cookie(struct super_block *sb, 51362306a36Sopenharmony_ci char *name, unsigned int flags); 51462306a36Sopenharmony_civoid erofs_fscache_unregister_cookie(struct erofs_fscache *fscache); 51562306a36Sopenharmony_ci#else 51662306a36Sopenharmony_cistatic inline int erofs_fscache_register_fs(struct super_block *sb) 51762306a36Sopenharmony_ci{ 51862306a36Sopenharmony_ci return -EOPNOTSUPP; 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_cistatic inline void erofs_fscache_unregister_fs(struct super_block *sb) {} 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic inline 52362306a36Sopenharmony_cistruct erofs_fscache *erofs_fscache_register_cookie(struct super_block *sb, 52462306a36Sopenharmony_ci char *name, unsigned int flags) 52562306a36Sopenharmony_ci{ 52662306a36Sopenharmony_ci return ERR_PTR(-EOPNOTSUPP); 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic inline void erofs_fscache_unregister_cookie(struct erofs_fscache *fscache) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci} 53262306a36Sopenharmony_ci#endif 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci#endif /* __EROFS_INTERNAL_H */ 537