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 */ 32624d0f1dSJan Kara enum { 33624d0f1dSJan Kara ES_WRITTEN_B, 34624d0f1dSJan Kara ES_UNWRITTEN_B, 35624d0f1dSJan Kara ES_DELAYED_B, 36624d0f1dSJan Kara ES_HOLE_B, 372be12de9SJan Kara ES_REFERENCED_B, 38624d0f1dSJan Kara ES_FLAGS 39624d0f1dSJan Kara }; 403be78c73STheodore Ts'o 41624d0f1dSJan Kara #define ES_SHIFT (sizeof(ext4_fsblk_t)*8 - ES_FLAGS) 42624d0f1dSJan Kara #define ES_MASK (~((ext4_fsblk_t)0) << ES_SHIFT) 43fdc0212eSZheng Liu 44624d0f1dSJan Kara #define EXTENT_STATUS_WRITTEN (1 << ES_WRITTEN_B) 45624d0f1dSJan Kara #define EXTENT_STATUS_UNWRITTEN (1 << ES_UNWRITTEN_B) 46624d0f1dSJan Kara #define EXTENT_STATUS_DELAYED (1 << ES_DELAYED_B) 47624d0f1dSJan Kara #define EXTENT_STATUS_HOLE (1 << ES_HOLE_B) 482be12de9SJan Kara #define EXTENT_STATUS_REFERENCED (1 << ES_REFERENCED_B) 492be12de9SJan Kara 502be12de9SJan Kara #define ES_TYPE_MASK ((ext4_fsblk_t)(EXTENT_STATUS_WRITTEN | \ 512be12de9SJan Kara EXTENT_STATUS_UNWRITTEN | \ 522be12de9SJan Kara EXTENT_STATUS_DELAYED | \ 532be12de9SJan Kara EXTENT_STATUS_HOLE) << ES_SHIFT) 543be78c73STheodore Ts'o 55d3922a77SZheng Liu struct ext4_sb_info; 56adb23551SZheng Liu struct ext4_extent; 57adb23551SZheng Liu 58c0677e6dSZheng Liu struct extent_status { 59c0677e6dSZheng Liu struct rb_node rb_node; 6006b0c886SZheng Liu ext4_lblk_t es_lblk; /* first logical block extent covers */ 6106b0c886SZheng Liu ext4_lblk_t es_len; /* length of extent in block */ 62fdc0212eSZheng Liu ext4_fsblk_t es_pblk; /* first physical block */ 63c0677e6dSZheng Liu }; 64c0677e6dSZheng Liu 65c0677e6dSZheng Liu struct ext4_es_tree { 66c0677e6dSZheng Liu struct rb_root root; 67c0677e6dSZheng Liu struct extent_status *cache_es; /* recently accessed extent */ 68c0677e6dSZheng Liu }; 69c0677e6dSZheng Liu 70eb68d0e2SZheng Liu struct ext4_es_stats { 71eb68d0e2SZheng Liu unsigned long es_stats_shrunk; 72eb68d0e2SZheng Liu unsigned long es_stats_cache_hits; 73eb68d0e2SZheng Liu unsigned long es_stats_cache_misses; 74eb68d0e2SZheng Liu u64 es_stats_scan_time; 75eb68d0e2SZheng Liu u64 es_stats_max_scan_time; 76eb68d0e2SZheng Liu struct percpu_counter es_stats_all_cnt; 77edaa53caSZheng Liu struct percpu_counter es_stats_shk_cnt; 78eb68d0e2SZheng Liu }; 79eb68d0e2SZheng Liu 80654598beSZheng Liu extern int __init ext4_init_es(void); 81654598beSZheng Liu extern void ext4_exit_es(void); 82654598beSZheng Liu extern void ext4_es_init_tree(struct ext4_es_tree *tree); 83654598beSZheng Liu 8406b0c886SZheng Liu extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, 85fdc0212eSZheng Liu ext4_lblk_t len, ext4_fsblk_t pblk, 863be78c73STheodore Ts'o unsigned int status); 87107a7bd3STheodore Ts'o extern void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk, 88107a7bd3STheodore Ts'o ext4_lblk_t len, ext4_fsblk_t pblk, 89107a7bd3STheodore Ts'o unsigned int status); 9006b0c886SZheng Liu extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, 91654598beSZheng Liu ext4_lblk_t len); 92e30b5dcaSYan, Zheng extern void ext4_es_find_delayed_extent_range(struct inode *inode, 93e30b5dcaSYan, Zheng ext4_lblk_t lblk, ext4_lblk_t end, 94654598beSZheng Liu struct extent_status *es); 95d100eef2SZheng Liu extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, 96d100eef2SZheng Liu struct extent_status *es); 97654598beSZheng Liu 98624d0f1dSJan Kara static inline unsigned int ext4_es_status(struct extent_status *es) 99624d0f1dSJan Kara { 100624d0f1dSJan Kara return es->es_pblk >> ES_SHIFT; 101624d0f1dSJan Kara } 102624d0f1dSJan Kara 1032be12de9SJan Kara static inline unsigned int ext4_es_type(struct extent_status *es) 1042be12de9SJan Kara { 1052be12de9SJan Kara return (es->es_pblk & ES_TYPE_MASK) >> ES_SHIFT; 1062be12de9SJan Kara } 1072be12de9SJan Kara 108fdc0212eSZheng Liu static inline int ext4_es_is_written(struct extent_status *es) 109fdc0212eSZheng Liu { 1102be12de9SJan Kara return (ext4_es_type(es) & EXTENT_STATUS_WRITTEN) != 0; 111fdc0212eSZheng Liu } 112fdc0212eSZheng Liu 113fdc0212eSZheng Liu static inline int ext4_es_is_unwritten(struct extent_status *es) 114fdc0212eSZheng Liu { 1152be12de9SJan Kara return (ext4_es_type(es) & EXTENT_STATUS_UNWRITTEN) != 0; 116fdc0212eSZheng Liu } 117fdc0212eSZheng Liu 118fdc0212eSZheng Liu static inline int ext4_es_is_delayed(struct extent_status *es) 119fdc0212eSZheng Liu { 1202be12de9SJan Kara return (ext4_es_type(es) & EXTENT_STATUS_DELAYED) != 0; 121fdc0212eSZheng Liu } 122fdc0212eSZheng Liu 123fdc0212eSZheng Liu static inline int ext4_es_is_hole(struct extent_status *es) 124fdc0212eSZheng Liu { 1252be12de9SJan Kara return (ext4_es_type(es) & EXTENT_STATUS_HOLE) != 0; 1262be12de9SJan Kara } 1272be12de9SJan Kara 1282be12de9SJan Kara static inline void ext4_es_set_referenced(struct extent_status *es) 1292be12de9SJan Kara { 1302be12de9SJan Kara es->es_pblk |= ((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT; 1312be12de9SJan Kara } 1322be12de9SJan Kara 1332be12de9SJan Kara static inline void ext4_es_clear_referenced(struct extent_status *es) 1342be12de9SJan Kara { 1352be12de9SJan Kara es->es_pblk &= ~(((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT); 1362be12de9SJan Kara } 1372be12de9SJan Kara 1382be12de9SJan Kara static inline int ext4_es_is_referenced(struct extent_status *es) 1392be12de9SJan Kara { 1402be12de9SJan Kara return (ext4_es_status(es) & EXTENT_STATUS_REFERENCED) != 0; 141fdc0212eSZheng Liu } 142fdc0212eSZheng Liu 143fdc0212eSZheng Liu static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es) 144fdc0212eSZheng Liu { 1453be78c73STheodore Ts'o return es->es_pblk & ~ES_MASK; 146fdc0212eSZheng Liu } 147fdc0212eSZheng Liu 148fdc0212eSZheng Liu static inline void ext4_es_store_pblock(struct extent_status *es, 149fdc0212eSZheng Liu ext4_fsblk_t pb) 150fdc0212eSZheng Liu { 151fdc0212eSZheng Liu ext4_fsblk_t block; 152fdc0212eSZheng Liu 1533be78c73STheodore Ts'o block = (pb & ~ES_MASK) | (es->es_pblk & ES_MASK); 154fdc0212eSZheng Liu es->es_pblk = block; 155fdc0212eSZheng Liu } 156fdc0212eSZheng Liu 157fdc0212eSZheng Liu static inline void ext4_es_store_status(struct extent_status *es, 1583be78c73STheodore Ts'o unsigned int status) 159fdc0212eSZheng Liu { 160624d0f1dSJan Kara es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) | 161624d0f1dSJan Kara (es->es_pblk & ~ES_MASK); 162fdc0212eSZheng Liu } 163fdc0212eSZheng Liu 1649a6633b1STheodore Ts'o static inline void ext4_es_store_pblock_status(struct extent_status *es, 1659a6633b1STheodore Ts'o ext4_fsblk_t pb, 1669a6633b1STheodore Ts'o unsigned int status) 1679a6633b1STheodore Ts'o { 168624d0f1dSJan Kara es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) | 169624d0f1dSJan Kara (pb & ~ES_MASK); 1709a6633b1STheodore Ts'o } 1719a6633b1STheodore Ts'o 172eb68d0e2SZheng Liu extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi); 173d3922a77SZheng Liu extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi); 17474cd15cdSZheng Liu 175c0677e6dSZheng Liu #endif /* _EXT4_EXTENTS_STATUS_H */ 176