1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29888c340SDavid Sterba
39888c340SDavid Sterba #ifndef BTRFS_EXTENT_MAP_H
49888c340SDavid Sterba #define BTRFS_EXTENT_MAP_H
5a52d9a80SChris Mason
6a52d9a80SChris Mason #include <linux/rbtree.h>
7490b54d6SElena Reshetova #include <linux/refcount.h>
8a52d9a80SChris Mason
9e248e04eSDulshani Gunawardhana #define EXTENT_MAP_LAST_BYTE ((u64)-4)
10e248e04eSDulshani Gunawardhana #define EXTENT_MAP_HOLE ((u64)-3)
11e248e04eSDulshani Gunawardhana #define EXTENT_MAP_INLINE ((u64)-2)
12951e05a9SNikolay Borisov /* used only during fiemap calls */
13e248e04eSDulshani Gunawardhana #define EXTENT_MAP_DELALLOC ((u64)-1)
14a52d9a80SChris Mason
1550b5b602SDavid Sterba /* bits for the extent_map::flags field */
1650b5b602SDavid Sterba enum {
1750b5b602SDavid Sterba /* this entry not yet on disk, don't free it */
1850b5b602SDavid Sterba EXTENT_FLAG_PINNED,
1950b5b602SDavid Sterba EXTENT_FLAG_COMPRESSED,
2050b5b602SDavid Sterba /* pre-allocated extent */
2150b5b602SDavid Sterba EXTENT_FLAG_PREALLOC,
2250b5b602SDavid Sterba /* Logging this extent */
2350b5b602SDavid Sterba EXTENT_FLAG_LOGGING,
2450b5b602SDavid Sterba /* Filling in a preallocated extent */
2550b5b602SDavid Sterba EXTENT_FLAG_FILLING,
2650b5b602SDavid Sterba /* filesystem extent mapping type */
2750b5b602SDavid Sterba EXTENT_FLAG_FS_MAPPING,
28199257a7SQu Wenruo /* This em is merged from two or more physically adjacent ems */
29199257a7SQu Wenruo EXTENT_FLAG_MERGED,
3050b5b602SDavid Sterba };
317f3c74fbSChris Mason
32d1310b2eSChris Mason struct extent_map {
33d1310b2eSChris Mason struct rb_node rb_node;
345f39d397SChris Mason
35d1310b2eSChris Mason /* all of these are in bytes */
36d1310b2eSChris Mason u64 start;
37d1310b2eSChris Mason u64 len;
384e2f84e6SLiu Bo u64 mod_start;
394e2f84e6SLiu Bo u64 mod_len;
40ff5b7ee3SYan Zheng u64 orig_start;
41b4939680SJosef Bacik u64 orig_block_len;
42cc95bef6SJosef Bacik u64 ram_bytes;
43d1310b2eSChris Mason u64 block_start;
44c8b97818SChris Mason u64 block_len;
45199257a7SQu Wenruo
46199257a7SQu Wenruo /*
47199257a7SQu Wenruo * Generation of the extent map, for merged em it's the highest
48199257a7SQu Wenruo * generation of all merged ems.
49199257a7SQu Wenruo * For non-merged extents, it's from btrfs_file_extent_item::generation.
50199257a7SQu Wenruo */
515dc562c5SJosef Bacik u64 generation;
52d1310b2eSChris Mason unsigned long flags;
53a019e9e1SDavid Sterba /* Used for chunk mappings, flag EXTENT_FLAG_FS_MAPPING must be set */
5495617d69SJeff Mahoney struct map_lookup *map_lookup;
55490b54d6SElena Reshetova refcount_t refs;
56c08782daSDavid Sterba unsigned int compress_type;
575dc562c5SJosef Bacik struct list_head list;
5807157aacSChris Mason };
5907157aacSChris Mason
60a52d9a80SChris Mason struct extent_map_tree {
6107e1ce09SLiu Bo struct rb_root_cached map;
625dc562c5SJosef Bacik struct list_head modified_extents;
63890871beSChris Mason rwlock_t lock;
64a52d9a80SChris Mason };
65a52d9a80SChris Mason
664c0c8cfcSFilipe Manana struct btrfs_inode;
674c0c8cfcSFilipe Manana
extent_map_in_tree(const struct extent_map * em)68cbc0e928SFilipe Manana static inline int extent_map_in_tree(const struct extent_map *em)
69cbc0e928SFilipe Manana {
70cbc0e928SFilipe Manana return !RB_EMPTY_NODE(&em->rb_node);
71cbc0e928SFilipe Manana }
72cbc0e928SFilipe Manana
extent_map_end(struct extent_map * em)73d1310b2eSChris Mason static inline u64 extent_map_end(struct extent_map *em)
74d1310b2eSChris Mason {
75d1310b2eSChris Mason if (em->start + em->len < em->start)
76d1310b2eSChris Mason return (u64)-1;
77d1310b2eSChris Mason return em->start + em->len;
78d1310b2eSChris Mason }
79a52d9a80SChris Mason
extent_map_block_end(struct extent_map * em)80d1310b2eSChris Mason static inline u64 extent_map_block_end(struct extent_map *em)
81d1310b2eSChris Mason {
82c8b97818SChris Mason if (em->block_start + em->block_len < em->block_start)
83d1310b2eSChris Mason return (u64)-1;
84c8b97818SChris Mason return em->block_start + em->block_len;
85d1310b2eSChris Mason }
8607157aacSChris Mason
87a8067e02SDavid Sterba void extent_map_tree_init(struct extent_map_tree *tree);
88a52d9a80SChris Mason struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
89d1310b2eSChris Mason u64 start, u64 len);
90a52d9a80SChris Mason int add_extent_mapping(struct extent_map_tree *tree,
9109a2a8f9SJosef Bacik struct extent_map *em, int modified);
92c1766dd7Szhong jiang void remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em);
93*f000bc6fSChristoph Hellwig int split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
94*f000bc6fSChristoph Hellwig u64 new_logical);
95d1310b2eSChris Mason
96172ddd60SDavid Sterba struct extent_map *alloc_extent_map(void);
97a52d9a80SChris Mason void free_extent_map(struct extent_map *em);
982f4cbe64SWyatt Banks int __init extent_map_init(void);
99e67c718bSDavid Sterba void __cold extent_map_exit(void);
1005dc562c5SJosef Bacik int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen);
101201a9038SJosef Bacik void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
102b917b7c3SChris Mason struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
103b917b7c3SChris Mason u64 start, u64 len);
104f46b24c9SDavid Sterba int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info,
105f46b24c9SDavid Sterba struct extent_map_tree *em_tree,
106c04e61b5SLiu Bo struct extent_map **em_in, u64 start, u64 len);
1074c0c8cfcSFilipe Manana void btrfs_drop_extent_map_range(struct btrfs_inode *inode,
1084c0c8cfcSFilipe Manana u64 start, u64 end,
1094c0c8cfcSFilipe Manana bool skip_pinned);
110a1ba4c08SFilipe Manana int btrfs_replace_extent_map_range(struct btrfs_inode *inode,
111a1ba4c08SFilipe Manana struct extent_map *new_em,
112a1ba4c08SFilipe Manana bool modified);
1139888c340SDavid Sterba
114a52d9a80SChris Mason #endif
115