0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef _EXT4_EXTENTS_STATUS_H
0013 #define _EXT4_EXTENTS_STATUS_H
0014
0015
0016
0017
0018 #ifdef ES_DEBUG__
0019 #define es_debug(fmt, ...) printk(fmt, ##__VA_ARGS__)
0020 #else
0021 #define es_debug(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
0022 #endif
0023
0024
0025
0026
0027
0028 #define ES_AGGRESSIVE_TEST__
0029
0030
0031
0032
0033 enum {
0034 ES_WRITTEN_B,
0035 ES_UNWRITTEN_B,
0036 ES_DELAYED_B,
0037 ES_HOLE_B,
0038 ES_REFERENCED_B,
0039 ES_FLAGS
0040 };
0041
0042 #define ES_SHIFT (sizeof(ext4_fsblk_t)*8 - ES_FLAGS)
0043 #define ES_MASK (~((ext4_fsblk_t)0) << ES_SHIFT)
0044
0045 #define EXTENT_STATUS_WRITTEN (1 << ES_WRITTEN_B)
0046 #define EXTENT_STATUS_UNWRITTEN (1 << ES_UNWRITTEN_B)
0047 #define EXTENT_STATUS_DELAYED (1 << ES_DELAYED_B)
0048 #define EXTENT_STATUS_HOLE (1 << ES_HOLE_B)
0049 #define EXTENT_STATUS_REFERENCED (1 << ES_REFERENCED_B)
0050
0051 #define ES_TYPE_MASK ((ext4_fsblk_t)(EXTENT_STATUS_WRITTEN | \
0052 EXTENT_STATUS_UNWRITTEN | \
0053 EXTENT_STATUS_DELAYED | \
0054 EXTENT_STATUS_HOLE) << ES_SHIFT)
0055
0056 struct ext4_sb_info;
0057 struct ext4_extent;
0058
0059 struct extent_status {
0060 struct rb_node rb_node;
0061 ext4_lblk_t es_lblk;
0062 ext4_lblk_t es_len;
0063 ext4_fsblk_t es_pblk;
0064 };
0065
0066 struct ext4_es_tree {
0067 struct rb_root root;
0068 struct extent_status *cache_es;
0069 };
0070
0071 struct ext4_es_stats {
0072 unsigned long es_stats_shrunk;
0073 struct percpu_counter es_stats_cache_hits;
0074 struct percpu_counter es_stats_cache_misses;
0075 u64 es_stats_scan_time;
0076 u64 es_stats_max_scan_time;
0077 struct percpu_counter es_stats_all_cnt;
0078 struct percpu_counter es_stats_shk_cnt;
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 struct pending_reservation {
0118 struct rb_node rb_node;
0119 ext4_lblk_t lclu;
0120 };
0121
0122 struct ext4_pending_tree {
0123 struct rb_root root;
0124 };
0125
0126 extern int __init ext4_init_es(void);
0127 extern void ext4_exit_es(void);
0128 extern void ext4_es_init_tree(struct ext4_es_tree *tree);
0129
0130 extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
0131 ext4_lblk_t len, ext4_fsblk_t pblk,
0132 unsigned int status);
0133 extern void ext4_es_cache_extent(struct inode *inode, ext4_lblk_t lblk,
0134 ext4_lblk_t len, ext4_fsblk_t pblk,
0135 unsigned int status);
0136 extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
0137 ext4_lblk_t len);
0138 extern void ext4_es_find_extent_range(struct inode *inode,
0139 int (*match_fn)(struct extent_status *es),
0140 ext4_lblk_t lblk, ext4_lblk_t end,
0141 struct extent_status *es);
0142 extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk,
0143 ext4_lblk_t *next_lblk,
0144 struct extent_status *es);
0145 extern bool ext4_es_scan_range(struct inode *inode,
0146 int (*matching_fn)(struct extent_status *es),
0147 ext4_lblk_t lblk, ext4_lblk_t end);
0148 extern bool ext4_es_scan_clu(struct inode *inode,
0149 int (*matching_fn)(struct extent_status *es),
0150 ext4_lblk_t lblk);
0151
0152 static inline unsigned int ext4_es_status(struct extent_status *es)
0153 {
0154 return es->es_pblk >> ES_SHIFT;
0155 }
0156
0157 static inline unsigned int ext4_es_type(struct extent_status *es)
0158 {
0159 return (es->es_pblk & ES_TYPE_MASK) >> ES_SHIFT;
0160 }
0161
0162 static inline int ext4_es_is_written(struct extent_status *es)
0163 {
0164 return (ext4_es_type(es) & EXTENT_STATUS_WRITTEN) != 0;
0165 }
0166
0167 static inline int ext4_es_is_unwritten(struct extent_status *es)
0168 {
0169 return (ext4_es_type(es) & EXTENT_STATUS_UNWRITTEN) != 0;
0170 }
0171
0172 static inline int ext4_es_is_delayed(struct extent_status *es)
0173 {
0174 return (ext4_es_type(es) & EXTENT_STATUS_DELAYED) != 0;
0175 }
0176
0177 static inline int ext4_es_is_hole(struct extent_status *es)
0178 {
0179 return (ext4_es_type(es) & EXTENT_STATUS_HOLE) != 0;
0180 }
0181
0182 static inline int ext4_es_is_mapped(struct extent_status *es)
0183 {
0184 return (ext4_es_is_written(es) || ext4_es_is_unwritten(es));
0185 }
0186
0187 static inline int ext4_es_is_delonly(struct extent_status *es)
0188 {
0189 return (ext4_es_is_delayed(es) && !ext4_es_is_unwritten(es));
0190 }
0191
0192 static inline void ext4_es_set_referenced(struct extent_status *es)
0193 {
0194 es->es_pblk |= ((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT;
0195 }
0196
0197 static inline void ext4_es_clear_referenced(struct extent_status *es)
0198 {
0199 es->es_pblk &= ~(((ext4_fsblk_t)EXTENT_STATUS_REFERENCED) << ES_SHIFT);
0200 }
0201
0202 static inline int ext4_es_is_referenced(struct extent_status *es)
0203 {
0204 return (ext4_es_status(es) & EXTENT_STATUS_REFERENCED) != 0;
0205 }
0206
0207 static inline ext4_fsblk_t ext4_es_pblock(struct extent_status *es)
0208 {
0209 return es->es_pblk & ~ES_MASK;
0210 }
0211
0212 static inline ext4_fsblk_t ext4_es_show_pblock(struct extent_status *es)
0213 {
0214 ext4_fsblk_t pblock = ext4_es_pblock(es);
0215 return pblock == ~ES_MASK ? 0 : pblock;
0216 }
0217
0218 static inline void ext4_es_store_pblock(struct extent_status *es,
0219 ext4_fsblk_t pb)
0220 {
0221 ext4_fsblk_t block;
0222
0223 block = (pb & ~ES_MASK) | (es->es_pblk & ES_MASK);
0224 es->es_pblk = block;
0225 }
0226
0227 static inline void ext4_es_store_status(struct extent_status *es,
0228 unsigned int status)
0229 {
0230 es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) |
0231 (es->es_pblk & ~ES_MASK);
0232 }
0233
0234 static inline void ext4_es_store_pblock_status(struct extent_status *es,
0235 ext4_fsblk_t pb,
0236 unsigned int status)
0237 {
0238 es->es_pblk = (((ext4_fsblk_t)status << ES_SHIFT) & ES_MASK) |
0239 (pb & ~ES_MASK);
0240 }
0241
0242 extern int ext4_es_register_shrinker(struct ext4_sb_info *sbi);
0243 extern void ext4_es_unregister_shrinker(struct ext4_sb_info *sbi);
0244
0245 extern int ext4_seq_es_shrinker_info_show(struct seq_file *seq, void *v);
0246
0247 extern int __init ext4_init_pending(void);
0248 extern void ext4_exit_pending(void);
0249 extern void ext4_init_pending_tree(struct ext4_pending_tree *tree);
0250 extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk);
0251 extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk);
0252 extern int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
0253 bool allocated);
0254 extern unsigned int ext4_es_delayed_clu(struct inode *inode, ext4_lblk_t lblk,
0255 ext4_lblk_t len);
0256 extern void ext4_clear_inode_es(struct inode *inode);
0257
0258 #endif