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