1c0677e6dSZheng Liu /* 2c0677e6dSZheng Liu * fs/ext4/extents_status.h 3c0677e6dSZheng Liu * 4c0677e6dSZheng Liu * Written by Yongqiang Yang <xiaoqiangnk@gmail.com> 5c0677e6dSZheng Liu * Modified by 6c0677e6dSZheng Liu * Allison Henderson <achender@linux.vnet.ibm.com> 7c0677e6dSZheng Liu * Zheng Liu <wenqing.lz@taobao.com> 8c0677e6dSZheng Liu * 9c0677e6dSZheng Liu */ 10c0677e6dSZheng Liu 11c0677e6dSZheng Liu #ifndef _EXT4_EXTENTS_STATUS_H 12c0677e6dSZheng Liu #define _EXT4_EXTENTS_STATUS_H 13c0677e6dSZheng Liu 14654598beSZheng Liu /* 15654598beSZheng Liu * Turn on ES_DEBUG__ to get lots of info about extent status operations. 16654598beSZheng Liu */ 17654598beSZheng Liu #ifdef ES_DEBUG__ 18654598beSZheng Liu #define es_debug(fmt, ...) printk(fmt, ##__VA_ARGS__) 19654598beSZheng Liu #else 20654598beSZheng Liu #define es_debug(fmt, ...) no_printk(fmt, ##__VA_ARGS__) 21654598beSZheng Liu #endif 22654598beSZheng Liu 238e919d13STheodore Ts'o /* 24921f266bSDmitry Monakhov * With ES_AGGRESSIVE_TEST defined, the result of es caching will be 25921f266bSDmitry Monakhov * checked with old map_block's result. 26921f266bSDmitry Monakhov */ 27921f266bSDmitry Monakhov #define ES_AGGRESSIVE_TEST__ 28921f266bSDmitry Monakhov 29921f266bSDmitry Monakhov /* 308e919d13STheodore Ts'o * These flags live in the high bits of extent_status.es_pblk 318e919d13STheodore Ts'o */ 323be78c73STheodore Ts'o #define ES_SHIFT 60 333be78c73STheodore Ts'o 343be78c73STheodore Ts'o #define EXTENT_STATUS_WRITTEN (1 << 3) 353be78c73STheodore Ts'o #define EXTENT_STATUS_UNWRITTEN (1 << 2) 363be78c73STheodore Ts'o #define EXTENT_STATUS_DELAYED (1 << 1) 373be78c73STheodore Ts'o #define EXTENT_STATUS_HOLE (1 << 0) 38fdc0212eSZheng Liu 39fdc0212eSZheng Liu #define EXTENT_STATUS_FLAGS (EXTENT_STATUS_WRITTEN | \ 40fdc0212eSZheng Liu EXTENT_STATUS_UNWRITTEN | \ 41fdc0212eSZheng Liu EXTENT_STATUS_DELAYED | \ 42fdc0212eSZheng Liu EXTENT_STATUS_HOLE) 43fdc0212eSZheng Liu 443be78c73STheodore Ts'o #define ES_WRITTEN (1ULL << 63) 453be78c73STheodore Ts'o #define ES_UNWRITTEN (1ULL << 62) 463be78c73STheodore Ts'o #define ES_DELAYED (1ULL << 61) 473be78c73STheodore Ts'o #define ES_HOLE (1ULL << 60) 483be78c73STheodore Ts'o 493be78c73STheodore Ts'o #define ES_MASK (ES_WRITTEN | ES_UNWRITTEN | \ 503be78c73STheodore Ts'o ES_DELAYED | ES_HOLE) 513be78c73STheodore Ts'o 52d3922a77SZheng Liu struct ext4_sb_info; 53adb23551SZheng Liu struct ext4_extent; 54adb23551SZheng Liu 55c0677e6dSZheng Liu struct extent_status { 56c0677e6dSZheng Liu struct rb_node rb_node; 5706b0c886SZheng Liu ext4_lblk_t es_lblk; /* first logical block extent covers */ 5806b0c886SZheng Liu ext4_lblk_t es_len; /* length of extent in block */ 59fdc0212eSZheng Liu ext4_fsblk_t es_pblk; /* first physical block */ 60c0677e6dSZheng Liu }; 61c0677e6dSZheng Liu 62c0677e6dSZheng Liu struct ext4_es_tree { 63c0677e6dSZheng Liu struct rb_root root; 64c0677e6dSZheng Liu struct extent_status *cache_es; /* recently accessed extent */ 65c0677e6dSZheng Liu }; 66c0677e6dSZheng Liu 67eb68d0e2SZheng Liu struct ext4_es_stats { 68eb68d0e2SZheng Liu unsigned long es_stats_last_sorted; 69eb68d0e2SZheng Liu unsigned long es_stats_shrunk; 70eb68d0e2SZheng Liu unsigned long es_stats_cache_hits; 71eb68d0e2SZheng Liu unsigned long es_stats_cache_misses; 72eb68d0e2SZheng Liu u64 es_stats_scan_time; 73eb68d0e2SZheng Liu u64 es_stats_max_scan_time; 74eb68d0e2SZheng Liu struct percpu_counter es_stats_all_cnt; 75eb68d0e2SZheng Liu struct percpu_counter es_stats_lru_cnt; 76eb68d0e2SZheng Liu }; 77eb68d0e2SZheng Liu 78654598beSZheng Liu extern int __init ext4_init_es(void); 79654598beSZheng Liu extern void ext4_exit_es(void); 80654598beSZheng Liu extern void ext4_es_init_tree(struct ext4_es_tree *tree); 81654598beSZheng Liu 8206b0c886SZheng Liu extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, 83fdc0212eSZheng Liu ext4_lblk_t len, ext4_fsblk_t pblk, 843be78c73STheodore Ts'o unsigned int status); 85107a7bd3STheodore Ts'o extern void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk, 86107a7bd3STheodore Ts'o ext4_lblk_t len, ext4_fsblk_t pblk, 87107a7bd3STheodore Ts'o unsigned int status); 8806b0c886SZheng Liu extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, 89654598beSZheng Liu ext4_lblk_t len); 90e30b5dcaSYan, Zheng extern void ext4_es_find_delayed_extent_range(struct inode *inode, 91e30b5dcaSYan, Zheng ext4_lblk_t lblk, ext4_lblk_t end, 92654598beSZheng Liu struct extent_status *es); 93d100eef2SZheng Liu extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, 94d100eef2SZheng Liu struct extent_status *es); 95654598beSZheng Liu 96fdc0212eSZheng Liu static inline int ext4_es_is_written(struct extent_status *es) 97fdc0212eSZheng Liu { 983be78c73STheodore Ts'o return (es->es_pblk & ES_WRITTEN) != 0; 99fdc0212eSZheng Liu } 100fdc0212eSZheng Liu 101fdc0212eSZheng Liu static inline int ext4_es_is_unwritten(struct extent_status *es) 102fdc0212eSZheng Liu { 1033be78c73STheodore Ts'o return (es->es_pblk & ES_UNWRITTEN) != 0; 104fdc0212eSZheng Liu } 105fdc0212eSZheng Liu 106fdc0212eSZheng Liu static inline int ext4_es_is_delayed(struct extent_status *es) 107fdc0212eSZheng Liu { 1083be78c73STheodore Ts'o return (es->es_pblk & ES_DELAYED) != 0; 109fdc0212eSZheng Liu } 110fdc0212eSZheng Liu 111fdc0212eSZheng Liu static inline int ext4_es_is_hole(struct extent_status *es) 112fdc0212eSZheng Liu { 1133be78c73STheodore Ts'o return (es->es_pblk & ES_HOLE) != 0; 114fdc0212eSZheng Liu } 115fdc0212eSZheng Liu 1163be78c73STheodore Ts'o static inline unsigned int ext4_es_status(struct extent_status *es) 117fdc0212eSZheng Liu { 1183be78c73STheodore Ts'o return es->es_pblk >> ES_SHIFT; 119fdc0212eSZheng Liu } 120fdc0212eSZheng Liu 121fdc0212eSZheng Liu static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es) 122fdc0212eSZheng Liu { 1233be78c73STheodore Ts'o return es->es_pblk & ~ES_MASK; 124fdc0212eSZheng Liu } 125fdc0212eSZheng Liu 126fdc0212eSZheng Liu static inline void ext4_es_store_pblock(struct extent_status *es, 127fdc0212eSZheng Liu ext4_fsblk_t pb) 128fdc0212eSZheng Liu { 129fdc0212eSZheng Liu ext4_fsblk_t block; 130fdc0212eSZheng Liu 1313be78c73STheodore Ts'o block = (pb & ~ES_MASK) | (es->es_pblk & ES_MASK); 132fdc0212eSZheng Liu es->es_pblk = block; 133fdc0212eSZheng Liu } 134fdc0212eSZheng Liu 135fdc0212eSZheng Liu static inline void ext4_es_store_status(struct extent_status *es, 1363be78c73STheodore Ts'o unsigned int status) 137fdc0212eSZheng Liu { 1383be78c73STheodore Ts'o es->es_pblk = (((ext4_fsblk_t) 1393be78c73STheodore Ts'o (status & EXTENT_STATUS_FLAGS) << ES_SHIFT) | 1403be78c73STheodore Ts'o (es->es_pblk & ~ES_MASK)); 141fdc0212eSZheng Liu } 142fdc0212eSZheng Liu 1439a6633b1STheodore Ts'o static inline void ext4_es_store_pblock_status(struct extent_status *es, 1449a6633b1STheodore Ts'o ext4_fsblk_t pb, 1459a6633b1STheodore Ts'o unsigned int status) 1469a6633b1STheodore Ts'o { 1479a6633b1STheodore Ts'o es->es_pblk = (((ext4_fsblk_t) 1489a6633b1STheodore Ts'o (status & EXTENT_STATUS_FLAGS) << ES_SHIFT) | 1499a6633b1STheodore Ts'o (pb & ~ES_MASK)); 1509a6633b1STheodore Ts'o } 1519a6633b1STheodore Ts'o 152eb68d0e2SZheng Liu extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi); 153d3922a77SZheng Liu extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi); 15474cd15cdSZheng Liu extern void ext4_es_lru_add(struct inode *inode); 15574cd15cdSZheng Liu extern void ext4_es_lru_del(struct inode *inode); 15674cd15cdSZheng Liu 157c0677e6dSZheng Liu #endif /* _EXT4_EXTENTS_STATUS_H */ 158