root/fs/erofs/internal.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. erofs_workgroup_try_to_freeze
  2. erofs_workgroup_unfreeze
  3. erofs_wait_on_workgroup_freezed
  4. erofs_workgroup_try_to_freeze
  5. erofs_workgroup_unfreeze
  6. erofs_wait_on_workgroup_freezed
  7. iloc
  8. erofs_inode_datablocks
  9. erofs_bitrange
  10. erofs_inode_version
  11. erofs_inode_datalayout
  12. z_erofs_fill_inode
  13. z_erofs_map_blocks_iter
  14. erofs_inode_hash
  15. erofs_get_pcpubuf
  16. erofs_shrinker_register
  17. erofs_shrinker_unregister
  18. erofs_init_shrinker
  19. erofs_exit_shrinker
  20. z_erofs_init_zip_subsystem
  21. z_erofs_exit_zip_subsystem

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Copyright (C) 2017-2018 HUAWEI, Inc.
   4  *             http://www.huawei.com/
   5  * Created by Gao Xiang <gaoxiang25@huawei.com>
   6  */
   7 #ifndef __EROFS_INTERNAL_H
   8 #define __EROFS_INTERNAL_H
   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>
  16 #include <linux/magic.h>
  17 #include <linux/slab.h>
  18 #include <linux/vmalloc.h>
  19 #include "erofs_fs.h"
  20 
  21 /* redefine pr_fmt "erofs: " */
  22 #undef pr_fmt
  23 #define pr_fmt(fmt) "erofs: " fmt
  24 
  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
  36 #else
  37 #define erofs_dbg(x, ...)       ((void)0)
  38 #define DBG_BUGON(x)            ((void)(x))
  39 #endif  /* !CONFIG_EROFS_FS_DEBUG */
  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;
  45 typedef u64 erofs_off_t;
  46 /* data type for filesystem-wide blocks number */
  47 typedef u32 erofs_blk_t;
  48 
  49 struct erofs_sb_info {
  50 #ifdef CONFIG_EROFS_FS_ZIP
  51         /* list for all registered superblocks, mainly for shrinker */
  52         struct list_head list;
  53         struct mutex umount_mutex;
  54 
  55         /* the dedicated workstation for compression */
  56         struct radix_tree_root workstn_tree;
  57 
  58         /* threshold for decompression synchronously */
  59         unsigned int max_sync_decompress_pages;
  60 
  61         unsigned int shrinker_run_no;
  62 
  63         /* current strategy of how to use managed cache */
  64         unsigned char cache_strategy;
  65 
  66         /* pseudo inode to manage cached pages */
  67         struct inode *managed_cache;
  68 #endif  /* CONFIG_EROFS_FS_ZIP */
  69         u32 blocks;
  70         u32 meta_blkaddr;
  71 #ifdef CONFIG_EROFS_FS_XATTR
  72         u32 xattr_blkaddr;
  73 #endif
  74 
  75         /* inode slot unit size in bit shift */
  76         unsigned char islotbits;
  77 
  78         u32 build_time_nsec;
  79         u64 build_time;
  80 
  81         /* what we really care is nid, rather than ino.. */
  82         erofs_nid_t root_nid;
  83         /* used for statfs, f_files - f_favail */
  84         u64 inos;
  85 
  86         u8 uuid[16];                    /* 128-bit uuid for volume */
  87         u8 volume_name[16];             /* volume name */
  88         u32 feature_incompat;
  89 
  90         unsigned int mount_opt;
  91 };
  92 
  93 #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
  94 #define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)
  95 
  96 /* Mount flags set via mount options or defaults */
  97 #define EROFS_MOUNT_XATTR_USER          0x00000010
  98 #define EROFS_MOUNT_POSIX_ACL           0x00000020
  99 
 100 #define clear_opt(sbi, option)  ((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
 101 #define set_opt(sbi, option)    ((sbi)->mount_opt |= EROFS_MOUNT_##option)
 102 #define test_opt(sbi, option)   ((sbi)->mount_opt & EROFS_MOUNT_##option)
 103 
 104 #ifdef CONFIG_EROFS_FS_ZIP
 105 enum {
 106         EROFS_ZIP_CACHE_DISABLED,
 107         EROFS_ZIP_CACHE_READAHEAD,
 108         EROFS_ZIP_CACHE_READAROUND
 109 };
 110 
 111 #define EROFS_LOCKED_MAGIC     (INT_MIN | 0xE0F510CCL)
 112 
 113 /* basic unit of the workstation of a super_block */
 114 struct erofs_workgroup {
 115         /* the workgroup index in the workstation */
 116         pgoff_t index;
 117 
 118         /* overall workgroup reference count */
 119         atomic_t refcount;
 120 };
 121 
 122 #if defined(CONFIG_SMP)
 123 static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp,
 124                                                  int val)
 125 {
 126         preempt_disable();
 127         if (val != atomic_cmpxchg(&grp->refcount, val, EROFS_LOCKED_MAGIC)) {
 128                 preempt_enable();
 129                 return false;
 130         }
 131         return true;
 132 }
 133 
 134 static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp,
 135                                             int orig_val)
 136 {
 137         /*
 138          * other observers should notice all modifications
 139          * in the freezing period.
 140          */
 141         smp_mb();
 142         atomic_set(&grp->refcount, orig_val);
 143         preempt_enable();
 144 }
 145 
 146 static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
 147 {
 148         return atomic_cond_read_relaxed(&grp->refcount,
 149                                         VAL != EROFS_LOCKED_MAGIC);
 150 }
 151 #else
 152 static inline bool erofs_workgroup_try_to_freeze(struct erofs_workgroup *grp,
 153                                                  int val)
 154 {
 155         preempt_disable();
 156         /* no need to spin on UP platforms, let's just disable preemption. */
 157         if (val != atomic_read(&grp->refcount)) {
 158                 preempt_enable();
 159                 return false;
 160         }
 161         return true;
 162 }
 163 
 164 static inline void erofs_workgroup_unfreeze(struct erofs_workgroup *grp,
 165                                             int orig_val)
 166 {
 167         preempt_enable();
 168 }
 169 
 170 static inline int erofs_wait_on_workgroup_freezed(struct erofs_workgroup *grp)
 171 {
 172         int v = atomic_read(&grp->refcount);
 173 
 174         /* workgroup is never freezed on uniprocessor systems */
 175         DBG_BUGON(v == EROFS_LOCKED_MAGIC);
 176         return v;
 177 }
 178 #endif  /* !CONFIG_SMP */
 179 
 180 /* hard limit of pages per compressed cluster */
 181 #define Z_EROFS_CLUSTER_MAX_PAGES       (CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT)
 182 #define EROFS_PCPUBUF_NR_PAGES          Z_EROFS_CLUSTER_MAX_PAGES
 183 #else
 184 #define EROFS_PCPUBUF_NR_PAGES          0
 185 #endif  /* !CONFIG_EROFS_FS_ZIP */
 186 
 187 /* we strictly follow PAGE_SIZE and no buffer head yet */
 188 #define LOG_BLOCK_SIZE          PAGE_SHIFT
 189 
 190 #undef LOG_SECTORS_PER_BLOCK
 191 #define LOG_SECTORS_PER_BLOCK   (PAGE_SHIFT - 9)
 192 
 193 #undef SECTORS_PER_BLOCK
 194 #define SECTORS_PER_BLOCK       (1 << SECTORS_PER_BLOCK)
 195 
 196 #define EROFS_BLKSIZ            (1 << LOG_BLOCK_SIZE)
 197 
 198 #if (EROFS_BLKSIZ % 4096 || !EROFS_BLKSIZ)
 199 #error erofs cannot be used in this platform
 200 #endif
 201 
 202 #define ROOT_NID(sb)            ((sb)->root_nid)
 203 
 204 #define erofs_blknr(addr)       ((addr) / EROFS_BLKSIZ)
 205 #define erofs_blkoff(addr)      ((addr) % EROFS_BLKSIZ)
 206 #define blknr_to_addr(nr)       ((erofs_off_t)(nr) * EROFS_BLKSIZ)
 207 
 208 static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid)
 209 {
 210         return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits);
 211 }
 212 
 213 /* atomic flag definitions */
 214 #define EROFS_I_EA_INITED_BIT   0
 215 #define EROFS_I_Z_INITED_BIT    1
 216 
 217 /* bitlock definitions (arranged in reverse order) */
 218 #define EROFS_I_BL_XATTR_BIT    (BITS_PER_LONG - 1)
 219 #define EROFS_I_BL_Z_BIT        (BITS_PER_LONG - 2)
 220 
 221 struct erofs_inode {
 222         erofs_nid_t nid;
 223 
 224         /* atomic flags (including bitlocks) */
 225         unsigned long flags;
 226 
 227         unsigned char datalayout;
 228         unsigned char inode_isize;
 229         unsigned short xattr_isize;
 230 
 231         unsigned int xattr_shared_count;
 232         unsigned int *xattr_shared_xattrs;
 233 
 234         union {
 235                 erofs_blk_t raw_blkaddr;
 236 #ifdef CONFIG_EROFS_FS_ZIP
 237                 struct {
 238                         unsigned short z_advise;
 239                         unsigned char  z_algorithmtype[2];
 240                         unsigned char  z_logical_clusterbits;
 241                         unsigned char  z_physical_clusterbits[2];
 242                 };
 243 #endif  /* CONFIG_EROFS_FS_ZIP */
 244         };
 245         /* the corresponding vfs inode */
 246         struct inode vfs_inode;
 247 };
 248 
 249 #define EROFS_I(ptr)    \
 250         container_of(ptr, struct erofs_inode, vfs_inode)
 251 
 252 static inline unsigned long erofs_inode_datablocks(struct inode *inode)
 253 {
 254         /* since i_size cannot be changed */
 255         return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
 256 }
 257 
 258 static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
 259                                           unsigned int bits)
 260 {
 261 
 262         return (value >> bit) & ((1 << bits) - 1);
 263 }
 264 
 265 
 266 static inline unsigned int erofs_inode_version(unsigned int value)
 267 {
 268         return erofs_bitrange(value, EROFS_I_VERSION_BIT,
 269                               EROFS_I_VERSION_BITS);
 270 }
 271 
 272 static inline unsigned int erofs_inode_datalayout(unsigned int value)
 273 {
 274         return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
 275                               EROFS_I_DATALAYOUT_BITS);
 276 }
 277 
 278 extern const struct super_operations erofs_sops;
 279 
 280 extern const struct address_space_operations erofs_raw_access_aops;
 281 #ifdef CONFIG_EROFS_FS_ZIP
 282 extern const struct address_space_operations z_erofs_vle_normalaccess_aops;
 283 #endif
 284 
 285 /*
 286  * Logical to physical block mapping, used by erofs_map_blocks()
 287  *
 288  * Different with other file systems, it is used for 2 access modes:
 289  *
 290  * 1) RAW access mode:
 291  *
 292  * Users pass a valid (m_lblk, m_lofs -- usually 0) pair,
 293  * and get the valid m_pblk, m_pofs and the longest m_len(in bytes).
 294  *
 295  * Note that m_lblk in the RAW access mode refers to the number of
 296  * the compressed ondisk block rather than the uncompressed
 297  * in-memory block for the compressed file.
 298  *
 299  * m_pofs equals to m_lofs except for the inline data page.
 300  *
 301  * 2) Normal access mode:
 302  *
 303  * If the inode is not compressed, it has no difference with
 304  * the RAW access mode. However, if the inode is compressed,
 305  * users should pass a valid (m_lblk, m_lofs) pair, and get
 306  * the needed m_pblk, m_pofs, m_len to get the compressed data
 307  * and the updated m_lblk, m_lofs which indicates the start
 308  * of the corresponding uncompressed data in the file.
 309  */
 310 enum {
 311         BH_Zipped = BH_PrivateStart,
 312         BH_FullMapped,
 313 };
 314 
 315 /* Has a disk mapping */
 316 #define EROFS_MAP_MAPPED        (1 << BH_Mapped)
 317 /* Located in metadata (could be copied from bd_inode) */
 318 #define EROFS_MAP_META          (1 << BH_Meta)
 319 /* The extent has been compressed */
 320 #define EROFS_MAP_ZIPPED        (1 << BH_Zipped)
 321 /* The length of extent is full */
 322 #define EROFS_MAP_FULL_MAPPED   (1 << BH_FullMapped)
 323 
 324 struct erofs_map_blocks {
 325         erofs_off_t m_pa, m_la;
 326         u64 m_plen, m_llen;
 327 
 328         unsigned int m_flags;
 329 
 330         struct page *mpage;
 331 };
 332 
 333 /* Flags used by erofs_map_blocks() */
 334 #define EROFS_GET_BLOCKS_RAW    0x0001
 335 
 336 /* zmap.c */
 337 #ifdef CONFIG_EROFS_FS_ZIP
 338 int z_erofs_fill_inode(struct inode *inode);
 339 int z_erofs_map_blocks_iter(struct inode *inode,
 340                             struct erofs_map_blocks *map,
 341                             int flags);
 342 #else
 343 static inline int z_erofs_fill_inode(struct inode *inode) { return -EOPNOTSUPP; }
 344 static inline int z_erofs_map_blocks_iter(struct inode *inode,
 345                                           struct erofs_map_blocks *map,
 346                                           int flags)
 347 {
 348         return -EOPNOTSUPP;
 349 }
 350 #endif  /* !CONFIG_EROFS_FS_ZIP */
 351 
 352 /* data.c */
 353 struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr);
 354 
 355 int erofs_map_blocks(struct inode *, struct erofs_map_blocks *, int);
 356 
 357 /* inode.c */
 358 static inline unsigned long erofs_inode_hash(erofs_nid_t nid)
 359 {
 360 #if BITS_PER_LONG == 32
 361         return (nid >> 32) ^ (nid & 0xffffffff);
 362 #else
 363         return nid;
 364 #endif
 365 }
 366 
 367 extern const struct inode_operations erofs_generic_iops;
 368 extern const struct inode_operations erofs_symlink_iops;
 369 extern const struct inode_operations erofs_fast_symlink_iops;
 370 
 371 struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool dir);
 372 int erofs_getattr(const struct path *path, struct kstat *stat,
 373                   u32 request_mask, unsigned int query_flags);
 374 
 375 /* namei.c */
 376 extern const struct inode_operations erofs_dir_iops;
 377 
 378 int erofs_namei(struct inode *dir, struct qstr *name,
 379                 erofs_nid_t *nid, unsigned int *d_type);
 380 
 381 /* dir.c */
 382 extern const struct file_operations erofs_dir_fops;
 383 
 384 /* utils.c / zdata.c */
 385 struct page *erofs_allocpage(struct list_head *pool, gfp_t gfp, bool nofail);
 386 
 387 #if (EROFS_PCPUBUF_NR_PAGES > 0)
 388 void *erofs_get_pcpubuf(unsigned int pagenr);
 389 #define erofs_put_pcpubuf(buf) do { \
 390         (void)&(buf);   \
 391         preempt_enable();       \
 392 } while (0)
 393 #else
 394 static inline void *erofs_get_pcpubuf(unsigned int pagenr)
 395 {
 396         return ERR_PTR(-EOPNOTSUPP);
 397 }
 398 
 399 #define erofs_put_pcpubuf(buf) do {} while (0)
 400 #endif
 401 
 402 #ifdef CONFIG_EROFS_FS_ZIP
 403 int erofs_workgroup_put(struct erofs_workgroup *grp);
 404 struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb,
 405                                              pgoff_t index, bool *tag);
 406 int erofs_register_workgroup(struct super_block *sb,
 407                              struct erofs_workgroup *grp, bool tag);
 408 void erofs_workgroup_free_rcu(struct erofs_workgroup *grp);
 409 void erofs_shrinker_register(struct super_block *sb);
 410 void erofs_shrinker_unregister(struct super_block *sb);
 411 int __init erofs_init_shrinker(void);
 412 void erofs_exit_shrinker(void);
 413 int __init z_erofs_init_zip_subsystem(void);
 414 void z_erofs_exit_zip_subsystem(void);
 415 int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
 416                                        struct erofs_workgroup *egrp);
 417 int erofs_try_to_free_cached_page(struct address_space *mapping,
 418                                   struct page *page);
 419 #else
 420 static inline void erofs_shrinker_register(struct super_block *sb) {}
 421 static inline void erofs_shrinker_unregister(struct super_block *sb) {}
 422 static inline int erofs_init_shrinker(void) { return 0; }
 423 static inline void erofs_exit_shrinker(void) {}
 424 static inline int z_erofs_init_zip_subsystem(void) { return 0; }
 425 static inline void z_erofs_exit_zip_subsystem(void) {}
 426 #endif  /* !CONFIG_EROFS_FS_ZIP */
 427 
 428 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
 429 
 430 #endif  /* __EROFS_INTERNAL_H */
 431 

/* [<][>][^][v][top][bottom][index][help] */