Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : 3 : #ifndef BTRFS_EXTENT_MAP_H 4 : #define BTRFS_EXTENT_MAP_H 5 : 6 : #include <linux/rbtree.h> 7 : #include <linux/refcount.h> 8 : 9 : #define EXTENT_MAP_LAST_BYTE ((u64)-4) 10 : #define EXTENT_MAP_HOLE ((u64)-3) 11 : #define EXTENT_MAP_INLINE ((u64)-2) 12 : /* used only during fiemap calls */ 13 : #define EXTENT_MAP_DELALLOC ((u64)-1) 14 : 15 : /* bits for the extent_map::flags field */ 16 : enum { 17 : /* this entry not yet on disk, don't free it */ 18 : EXTENT_FLAG_PINNED, 19 : EXTENT_FLAG_COMPRESSED, 20 : /* pre-allocated extent */ 21 : EXTENT_FLAG_PREALLOC, 22 : /* Logging this extent */ 23 : EXTENT_FLAG_LOGGING, 24 : /* Filling in a preallocated extent */ 25 : EXTENT_FLAG_FILLING, 26 : /* filesystem extent mapping type */ 27 : EXTENT_FLAG_FS_MAPPING, 28 : /* This em is merged from two or more physically adjacent ems */ 29 : EXTENT_FLAG_MERGED, 30 : }; 31 : 32 : struct extent_map { 33 : struct rb_node rb_node; 34 : 35 : /* all of these are in bytes */ 36 : u64 start; 37 : u64 len; 38 : u64 mod_start; 39 : u64 mod_len; 40 : u64 orig_start; 41 : u64 orig_block_len; 42 : u64 ram_bytes; 43 : u64 block_start; 44 : u64 block_len; 45 : 46 : /* 47 : * Generation of the extent map, for merged em it's the highest 48 : * generation of all merged ems. 49 : * For non-merged extents, it's from btrfs_file_extent_item::generation. 50 : */ 51 : u64 generation; 52 : unsigned long flags; 53 : /* Used for chunk mappings, flag EXTENT_FLAG_FS_MAPPING must be set */ 54 : struct map_lookup *map_lookup; 55 : refcount_t refs; 56 : unsigned int compress_type; 57 : struct list_head list; 58 : }; 59 : 60 : struct extent_map_tree { 61 : struct rb_root_cached map; 62 : struct list_head modified_extents; 63 : rwlock_t lock; 64 : }; 65 : 66 : struct btrfs_inode; 67 : 68 : static inline int extent_map_in_tree(const struct extent_map *em) 69 : { 70 0 : return !RB_EMPTY_NODE(&em->rb_node); 71 : } 72 : 73 : static inline u64 extent_map_end(struct extent_map *em) 74 : { 75 0 : if (em->start + em->len < em->start) 76 0 : return (u64)-1; 77 : return em->start + em->len; 78 : } 79 : 80 : static inline u64 extent_map_block_end(struct extent_map *em) 81 : { 82 0 : if (em->block_start + em->block_len < em->block_start) 83 0 : return (u64)-1; 84 : return em->block_start + em->block_len; 85 : } 86 : 87 : void extent_map_tree_init(struct extent_map_tree *tree); 88 : struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, 89 : u64 start, u64 len); 90 : int add_extent_mapping(struct extent_map_tree *tree, 91 : struct extent_map *em, int modified); 92 : void remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em); 93 : int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre, 94 : u64 new_logical); 95 : 96 : struct extent_map *alloc_extent_map(void); 97 : void free_extent_map(struct extent_map *em); 98 : int __init extent_map_init(void); 99 : void __cold extent_map_exit(void); 100 : int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen); 101 : void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em); 102 : struct extent_map *search_extent_mapping(struct extent_map_tree *tree, 103 : u64 start, u64 len); 104 : int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info, 105 : struct extent_map_tree *em_tree, 106 : struct extent_map **em_in, u64 start, u64 len); 107 : void btrfs_drop_extent_map_range(struct btrfs_inode *inode, 108 : u64 start, u64 end, 109 : bool skip_pinned); 110 : int btrfs_replace_extent_map_range(struct btrfs_inode *inode, 111 : struct extent_map *new_em, 112 : bool modified); 113 : 114 : #endif