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 */ 328e919d13STheodore Ts'o #define EXTENT_STATUS_WRITTEN (1ULL << 63) 338e919d13STheodore Ts'o #define EXTENT_STATUS_UNWRITTEN (1ULL << 62) 348e919d13STheodore Ts'o #define EXTENT_STATUS_DELAYED (1ULL << 61) 358e919d13STheodore Ts'o #define EXTENT_STATUS_HOLE (1ULL << 60) 36fdc0212eSZheng Liu 37fdc0212eSZheng Liu #define EXTENT_STATUS_FLAGS (EXTENT_STATUS_WRITTEN | \ 38fdc0212eSZheng Liu EXTENT_STATUS_UNWRITTEN | \ 39fdc0212eSZheng Liu EXTENT_STATUS_DELAYED | \ 40fdc0212eSZheng Liu EXTENT_STATUS_HOLE) 41fdc0212eSZheng Liu 42adb23551SZheng Liu struct ext4_extent; 43adb23551SZheng Liu 44c0677e6dSZheng Liu struct extent_status { 45c0677e6dSZheng Liu struct rb_node rb_node; 4606b0c886SZheng Liu ext4_lblk_t es_lblk; /* first logical block extent covers */ 4706b0c886SZheng Liu ext4_lblk_t es_len; /* length of extent in block */ 48fdc0212eSZheng Liu ext4_fsblk_t es_pblk; /* first physical block */ 49c0677e6dSZheng Liu }; 50c0677e6dSZheng Liu 51c0677e6dSZheng Liu struct ext4_es_tree { 52c0677e6dSZheng Liu struct rb_root root; 53c0677e6dSZheng Liu struct extent_status *cache_es; /* recently accessed extent */ 54c0677e6dSZheng Liu }; 55c0677e6dSZheng Liu 56654598beSZheng Liu extern int __init ext4_init_es(void); 57654598beSZheng Liu extern void ext4_exit_es(void); 58654598beSZheng Liu extern void ext4_es_init_tree(struct ext4_es_tree *tree); 59654598beSZheng Liu 6006b0c886SZheng Liu extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, 61fdc0212eSZheng Liu ext4_lblk_t len, ext4_fsblk_t pblk, 62fdc0212eSZheng Liu unsigned long long status); 6306b0c886SZheng Liu extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, 64654598beSZheng Liu ext4_lblk_t len); 65e30b5dcaSYan, Zheng extern void ext4_es_find_delayed_extent_range(struct inode *inode, 66e30b5dcaSYan, Zheng ext4_lblk_t lblk, ext4_lblk_t end, 67654598beSZheng Liu struct extent_status *es); 68d100eef2SZheng Liu extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, 69d100eef2SZheng Liu struct extent_status *es); 70adb23551SZheng Liu extern int ext4_es_zeroout(struct inode *inode, struct ext4_extent *ex); 71654598beSZheng Liu 72fdc0212eSZheng Liu static inline int ext4_es_is_written(struct extent_status *es) 73fdc0212eSZheng Liu { 748e919d13STheodore Ts'o return (es->es_pblk & EXTENT_STATUS_WRITTEN) != 0; 75fdc0212eSZheng Liu } 76fdc0212eSZheng Liu 77fdc0212eSZheng Liu static inline int ext4_es_is_unwritten(struct extent_status *es) 78fdc0212eSZheng Liu { 798e919d13STheodore Ts'o return (es->es_pblk & EXTENT_STATUS_UNWRITTEN) != 0; 80fdc0212eSZheng Liu } 81fdc0212eSZheng Liu 82fdc0212eSZheng Liu static inline int ext4_es_is_delayed(struct extent_status *es) 83fdc0212eSZheng Liu { 848e919d13STheodore Ts'o return (es->es_pblk & EXTENT_STATUS_DELAYED) != 0; 85fdc0212eSZheng Liu } 86fdc0212eSZheng Liu 87fdc0212eSZheng Liu static inline int ext4_es_is_hole(struct extent_status *es) 88fdc0212eSZheng Liu { 898e919d13STheodore Ts'o return (es->es_pblk & EXTENT_STATUS_HOLE) != 0; 90fdc0212eSZheng Liu } 91fdc0212eSZheng Liu 92fdc0212eSZheng Liu static inline ext4_fsblk_t ext4_es_status(struct extent_status *es) 93fdc0212eSZheng Liu { 94fdc0212eSZheng Liu return (es->es_pblk & EXTENT_STATUS_FLAGS); 95fdc0212eSZheng Liu } 96fdc0212eSZheng Liu 97fdc0212eSZheng Liu static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es) 98fdc0212eSZheng Liu { 99fdc0212eSZheng Liu return (es->es_pblk & ~EXTENT_STATUS_FLAGS); 100fdc0212eSZheng Liu } 101fdc0212eSZheng Liu 102fdc0212eSZheng Liu static inline void ext4_es_store_pblock(struct extent_status *es, 103fdc0212eSZheng Liu ext4_fsblk_t pb) 104fdc0212eSZheng Liu { 105fdc0212eSZheng Liu ext4_fsblk_t block; 106fdc0212eSZheng Liu 107fdc0212eSZheng Liu block = (pb & ~EXTENT_STATUS_FLAGS) | 108fdc0212eSZheng Liu (es->es_pblk & EXTENT_STATUS_FLAGS); 109fdc0212eSZheng Liu es->es_pblk = block; 110fdc0212eSZheng Liu } 111fdc0212eSZheng Liu 112fdc0212eSZheng Liu static inline void ext4_es_store_status(struct extent_status *es, 113fdc0212eSZheng Liu unsigned long long status) 114fdc0212eSZheng Liu { 115fdc0212eSZheng Liu ext4_fsblk_t block; 116fdc0212eSZheng Liu 117fdc0212eSZheng Liu block = (status & EXTENT_STATUS_FLAGS) | 118fdc0212eSZheng Liu (es->es_pblk & ~EXTENT_STATUS_FLAGS); 119fdc0212eSZheng Liu es->es_pblk = block; 120fdc0212eSZheng Liu } 121fdc0212eSZheng Liu 12274cd15cdSZheng Liu extern void ext4_es_register_shrinker(struct super_block *sb); 12374cd15cdSZheng Liu extern void ext4_es_unregister_shrinker(struct super_block *sb); 12474cd15cdSZheng Liu extern void ext4_es_lru_add(struct inode *inode); 12574cd15cdSZheng Liu extern void ext4_es_lru_del(struct inode *inode); 12674cd15cdSZheng Liu 127c0677e6dSZheng Liu #endif /* _EXT4_EXTENTS_STATUS_H */ 128