Commit | Line | Data |
---|---|---|
8719aaae JB |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | ||
3 | #ifndef BTRFS_SPACE_INFO_H | |
4 | #define BTRFS_SPACE_INFO_H | |
5 | ||
6 | struct btrfs_space_info { | |
7 | spinlock_t lock; | |
8 | ||
9 | u64 total_bytes; /* total bytes in the space, | |
10 | this doesn't take mirrors into account */ | |
11 | u64 bytes_used; /* total bytes used, | |
12 | this doesn't take mirrors into account */ | |
13 | u64 bytes_pinned; /* total bytes pinned, will be freed when the | |
14 | transaction finishes */ | |
15 | u64 bytes_reserved; /* total bytes the allocator has reserved for | |
16 | current allocations */ | |
17 | u64 bytes_may_use; /* number of bytes that may be used for | |
18 | delalloc/allocations */ | |
19 | u64 bytes_readonly; /* total bytes that are read only */ | |
20 | ||
21 | u64 max_extent_size; /* This will hold the maximum extent size of | |
22 | the space info if we had an ENOSPC in the | |
23 | allocator. */ | |
24 | ||
25 | unsigned int full:1; /* indicates that we cannot allocate any more | |
26 | chunks for this space */ | |
27 | unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ | |
28 | ||
29 | unsigned int flush:1; /* set if we are trying to make space */ | |
30 | ||
31 | unsigned int force_alloc; /* set if we need to force a chunk | |
32 | alloc for this space */ | |
33 | ||
34 | u64 disk_used; /* total bytes used on disk */ | |
35 | u64 disk_total; /* total bytes on disk, takes mirrors into | |
36 | account */ | |
37 | ||
38 | u64 flags; | |
39 | ||
40 | /* | |
41 | * bytes_pinned is kept in line with what is actually pinned, as in | |
42 | * we've called update_block_group and dropped the bytes_used counter | |
43 | * and increased the bytes_pinned counter. However this means that | |
44 | * bytes_pinned does not reflect the bytes that will be pinned once the | |
45 | * delayed refs are flushed, so this counter is inc'ed every time we | |
46 | * call btrfs_free_extent so it is a realtime count of what will be | |
47 | * freed once the transaction is committed. It will be zeroed every | |
48 | * time the transaction commits. | |
49 | */ | |
50 | struct percpu_counter total_bytes_pinned; | |
51 | ||
52 | struct list_head list; | |
53 | /* Protected by the spinlock 'lock'. */ | |
54 | struct list_head ro_bgs; | |
55 | struct list_head priority_tickets; | |
56 | struct list_head tickets; | |
db161806 NB |
57 | |
58 | /* | |
59 | * Size of space that needs to be reclaimed in order to satisfy pending | |
60 | * tickets | |
61 | */ | |
62 | u64 reclaim_size; | |
63 | ||
8719aaae JB |
64 | /* |
65 | * tickets_id just indicates the next ticket will be handled, so note | |
66 | * it's not stored per ticket. | |
67 | */ | |
68 | u64 tickets_id; | |
69 | ||
70 | struct rw_semaphore groups_sem; | |
71 | /* for block groups in our same type */ | |
72 | struct list_head block_groups[BTRFS_NR_RAID_TYPES]; | |
8719aaae JB |
73 | |
74 | struct kobject kobj; | |
75 | struct kobject *block_group_kobjs[BTRFS_NR_RAID_TYPES]; | |
76 | }; | |
77 | ||
b338b013 | 78 | struct reserve_ticket { |
b338b013 JB |
79 | u64 bytes; |
80 | int error; | |
7f9fe614 | 81 | bool steal; |
b338b013 JB |
82 | struct list_head list; |
83 | wait_queue_head_t wait; | |
84 | }; | |
85 | ||
8719aaae JB |
86 | static inline bool btrfs_mixed_space_info(struct btrfs_space_info *space_info) |
87 | { | |
88 | return ((space_info->flags & BTRFS_BLOCK_GROUP_METADATA) && | |
89 | (space_info->flags & BTRFS_BLOCK_GROUP_DATA)); | |
90 | } | |
91 | ||
bb96c4e5 JB |
92 | /* |
93 | * | |
94 | * Declare a helper function to detect underflow of various space info members | |
95 | */ | |
f3e75e38 | 96 | #define DECLARE_SPACE_INFO_UPDATE(name, trace_name) \ |
bb96c4e5 JB |
97 | static inline void \ |
98 | btrfs_space_info_update_##name(struct btrfs_fs_info *fs_info, \ | |
99 | struct btrfs_space_info *sinfo, \ | |
100 | s64 bytes) \ | |
101 | { \ | |
f3e75e38 | 102 | const u64 abs_bytes = (bytes < 0) ? -bytes : bytes; \ |
bb96c4e5 JB |
103 | lockdep_assert_held(&sinfo->lock); \ |
104 | trace_update_##name(fs_info, sinfo, sinfo->name, bytes); \ | |
f3e75e38 JB |
105 | trace_btrfs_space_reservation(fs_info, trace_name, \ |
106 | sinfo->flags, abs_bytes, \ | |
107 | bytes > 0); \ | |
bb96c4e5 JB |
108 | if (bytes < 0 && sinfo->name < -bytes) { \ |
109 | WARN_ON(1); \ | |
110 | sinfo->name = 0; \ | |
111 | return; \ | |
112 | } \ | |
113 | sinfo->name += bytes; \ | |
114 | } | |
115 | ||
f3e75e38 JB |
116 | DECLARE_SPACE_INFO_UPDATE(bytes_may_use, "space_info"); |
117 | DECLARE_SPACE_INFO_UPDATE(bytes_pinned, "pinned"); | |
bb96c4e5 | 118 | |
280c2908 JB |
119 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info); |
120 | void btrfs_update_space_info(struct btrfs_fs_info *info, u64 flags, | |
121 | u64 total_bytes, u64 bytes_used, | |
122 | u64 bytes_readonly, | |
123 | struct btrfs_space_info **space_info); | |
124 | struct btrfs_space_info *btrfs_find_space_info(struct btrfs_fs_info *info, | |
125 | u64 flags); | |
e1f60a65 | 126 | u64 __pure btrfs_space_info_used(struct btrfs_space_info *s_info, |
280c2908 JB |
127 | bool may_use_included); |
128 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); | |
5da6afeb JB |
129 | void btrfs_dump_space_info(struct btrfs_fs_info *fs_info, |
130 | struct btrfs_space_info *info, u64 bytes, | |
131 | int dump_block_groups); | |
0d9764f6 JB |
132 | int btrfs_reserve_metadata_bytes(struct btrfs_root *root, |
133 | struct btrfs_block_rsv *block_rsv, | |
134 | u64 orig_bytes, | |
135 | enum btrfs_reserve_flush_enum flush); | |
18fa2284 JB |
136 | void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info, |
137 | struct btrfs_space_info *space_info); | |
a30a3d20 JB |
138 | int btrfs_can_overcommit(struct btrfs_fs_info *fs_info, |
139 | struct btrfs_space_info *space_info, u64 bytes, | |
140 | enum btrfs_reserve_flush_enum flush); | |
18fa2284 | 141 | |
d05e4649 | 142 | static inline void btrfs_space_info_free_bytes_may_use( |
18fa2284 JB |
143 | struct btrfs_fs_info *fs_info, |
144 | struct btrfs_space_info *space_info, | |
145 | u64 num_bytes) | |
146 | { | |
147 | spin_lock(&space_info->lock); | |
148 | btrfs_space_info_update_bytes_may_use(fs_info, space_info, -num_bytes); | |
149 | btrfs_try_granting_tickets(fs_info, space_info); | |
150 | spin_unlock(&space_info->lock); | |
151 | } | |
d44b72aa | 152 | |
8719aaae | 153 | #endif /* BTRFS_SPACE_INFO_H */ |