| 1 | |
| 2 |
|
| 3 | #include <linux/err.h>
|
| 4 | #include <linux/slab.h>
|
| 5 | #include <linux/spinlock.h>
|
| 6 | #include "messages.h"
|
| 7 | #include "ctree.h"
|
| 8 | #include "extent_map.h"
|
| 9 | #include "compression.h"
|
| 10 | #include "btrfs_inode.h"
|
| 11 | #include "disk-io.h"
|
| 12 |
|
| 13 |
|
| 14 | static struct kmem_cache *extent_map_cache;
|
| 15 |
|
| 16 | int __init btrfs_extent_map_init(void)
|
| 17 | {
|
| 18 | extent_map_cache = kmem_cache_create("btrfs_extent_map",
|
| 19 | sizeof(struct extent_map), 0, 0, NULL);
|
| 20 | if (!extent_map_cache)
|
| 21 | return -ENOMEM;
|
| 22 | return 0;
|
| 23 | }
|
| 24 |
|
| 25 | void __cold btrfs_extent_map_exit(void)
|
| 26 | {
|
| 27 | kmem_cache_destroy(extent_map_cache);
|
| 28 | }
|
| 29 |
|
| 30 | |
| 31 | * Initialize the extent tree @tree. Should be called for each new inode or
|
| 32 | * other user of the extent_map interface.
|
| 33 |
|
| 34 | void btrfs_extent_map_tree_init(struct extent_map_tree *tree)
|
| 35 | {
|
| 36 | tree->root = RB_ROOT;
|
| 37 | INIT_LIST_HEAD(&tree->modified_extents);
|
| 38 | rwlock_init(&tree->lock);
|
| 39 | }
|
| 40 |
|
| 41 | |
| 42 | * Allocate a new extent_map structure. The new structure is returned with a
|
| 43 | * reference count of one and needs to be freed using free_extent_map()
|
| 44 |
|
| 45 | struct extent_map *btrfs_alloc_extent_map(void)
|
| 46 | {
|
| 47 | struct extent_map *em;
|
| 48 | em = kmem_cache_zalloc(extent_map_cache, GFP_NOFS);
|
| 49 | if (!em)
|
| 50 | return NULL;
|
| 51 | RB_CLEAR_NODE(&em->rb_node);
|
| 52 | refcount_set(&em->refs, 1);
|
| 53 | INIT_LIST_HEAD(&em->list);
|
| 54 | return em;
|
| 55 | }
|
| 56 |
|
| 57 | |
| 58 | * Drop the reference out on @em by one and free the structure if the reference
|
| 59 | * count hits zero.
|
| 60 |
|
| 61 | void btrfs_free_extent_map(struct extent_map *em)
|
| 62 | {
|
| 63 | if (!em)
|
| 64 | return;
|
| 65 | if (refcount_dec_and_test(&em->refs)) {
|
| 66 | WARN_ON(btrfs_extent_map_in_tree(em));
|
| 67 | WARN_ON(!list_empty(&em->list));
|
| 68 | kmem_cache_free(extent_map_cache, em);
|
| 69 | }
|
| 70 | }
|
| 71 |
|
| 72 |
|
| 73 | static u64 range_end(u64 start, u64 len)
|
| 74 | {
|
| 75 | if (start + len < start)
|
| 76 | return (u64)-1;
|
| 77 | return start + len;
|
| 78 | }
|
| 79 |
|
| 80 | static void remove_em(struct btrfs_inode *inode, struct extent_map *em)
|
| 81 | {
|
| 82 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 83 |
|
| 84 | rb_erase(&em->rb_node, &inode->extent_tree.root);
|
| 85 | RB_CLEAR_NODE(&em->rb_node);
|
| 86 |
|
| 87 | if (!btrfs_is_testing(fs_info) && btrfs_is_fstree(btrfs_root_id(inode->root)))
|
| 88 | percpu_counter_dec(&fs_info->evictable_extent_maps);
|
| 89 | }
|
| 90 |
|
| 91 | static int tree_insert(struct rb_root *root, struct extent_map *em)
|
| 92 | {
|
| 93 | struct rb_node **p = &root->rb_node;
|
| 94 | struct rb_node *parent = NULL;
|
| 95 | struct extent_map *entry = NULL;
|
| 96 | struct rb_node *orig_parent = NULL;
|
| 97 | u64 end = range_end(em->start, em->len);
|
| 98 |
|
| 99 | while (*p) {
|
| 100 | parent = *p;
|
| 101 | entry = rb_entry(parent, struct extent_map, rb_node);
|
| 102 |
|
| 103 | if (em->start < entry->start)
|
| 104 | p = &(*p)->rb_left;
|
| 105 | else if (em->start >= btrfs_extent_map_end(entry))
|
| 106 | p = &(*p)->rb_right;
|
| 107 | else
|
| 108 | return -EEXIST;
|
| 109 | }
|
| 110 |
|
| 111 | orig_parent = parent;
|
| 112 | while (parent && em->start >= btrfs_extent_map_end(entry)) {
|
| 113 | parent = rb_next(parent);
|
| 114 | entry = rb_entry(parent, struct extent_map, rb_node);
|
| 115 | }
|
| 116 | if (parent)
|
| 117 | if (end > entry->start && em->start < btrfs_extent_map_end(entry))
|
| 118 | return -EEXIST;
|
| 119 |
|
| 120 | parent = orig_parent;
|
| 121 | entry = rb_entry(parent, struct extent_map, rb_node);
|
| 122 | while (parent && em->start < entry->start) {
|
| 123 | parent = rb_prev(parent);
|
| 124 | entry = rb_entry(parent, struct extent_map, rb_node);
|
| 125 | }
|
| 126 | if (parent)
|
| 127 | if (end > entry->start && em->start < btrfs_extent_map_end(entry))
|
| 128 | return -EEXIST;
|
| 129 |
|
| 130 | rb_link_node(&em->rb_node, orig_parent, p);
|
| 131 | rb_insert_color(&em->rb_node, root);
|
| 132 | return 0;
|
| 133 | }
|
| 134 |
|
| 135 | |
| 136 | * Search through the tree for an extent_map with a given offset. If it can't
|
| 137 | * be found, try to find some neighboring extents
|
| 138 |
|
| 139 | static struct rb_node *tree_search(struct rb_root *root, u64 offset,
|
| 140 | struct rb_node **prev_or_next_ret)
|
| 141 | {
|
| 142 | struct rb_node *n = root->rb_node;
|
| 143 | struct rb_node *prev = NULL;
|
| 144 | struct rb_node *orig_prev = NULL;
|
| 145 | struct extent_map *entry;
|
| 146 | struct extent_map *prev_entry = NULL;
|
| 147 |
|
| 148 | ASSERT(prev_or_next_ret);
|
| 149 |
|
| 150 | while (n) {
|
| 151 | entry = rb_entry(n, struct extent_map, rb_node);
|
| 152 | prev = n;
|
| 153 | prev_entry = entry;
|
| 154 |
|
| 155 | if (offset < entry->start)
|
| 156 | n = n->rb_left;
|
| 157 | else if (offset >= btrfs_extent_map_end(entry))
|
| 158 | n = n->rb_right;
|
| 159 | else
|
| 160 | return n;
|
| 161 | }
|
| 162 |
|
| 163 | orig_prev = prev;
|
| 164 | while (prev && offset >= btrfs_extent_map_end(prev_entry)) {
|
| 165 | prev = rb_next(prev);
|
| 166 | prev_entry = rb_entry(prev, struct extent_map, rb_node);
|
| 167 | }
|
| 168 |
|
| 169 | |
| 170 | * Previous extent map found, return as in this case the caller does not
|
| 171 | * care about the next one.
|
| 172 |
|
| 173 | if (prev) {
|
| 174 | *prev_or_next_ret = prev;
|
| 175 | return NULL;
|
| 176 | }
|
| 177 |
|
| 178 | prev = orig_prev;
|
| 179 | prev_entry = rb_entry(prev, struct extent_map, rb_node);
|
| 180 | while (prev && offset < prev_entry->start) {
|
| 181 | prev = rb_prev(prev);
|
| 182 | prev_entry = rb_entry(prev, struct extent_map, rb_node);
|
| 183 | }
|
| 184 | *prev_or_next_ret = prev;
|
| 185 |
|
| 186 | return NULL;
|
| 187 | }
|
| 188 |
|
| 189 | static inline u64 extent_map_block_len(const struct extent_map *em)
|
| 190 | {
|
| 191 | if (btrfs_extent_map_is_compressed(em))
|
| 192 | return em->disk_num_bytes;
|
| 193 | return em->len;
|
| 194 | }
|
| 195 |
|
| 196 | static inline u64 extent_map_block_end(const struct extent_map *em)
|
| 197 | {
|
| 198 | const u64 block_start = btrfs_extent_map_block_start(em);
|
| 199 | const u64 block_end = block_start + extent_map_block_len(em);
|
| 200 |
|
| 201 | if (block_end < block_start)
|
| 202 | return (u64)-1;
|
| 203 |
|
| 204 | return block_end;
|
| 205 | }
|
| 206 |
|
| 207 | static bool can_merge_extent_map(const struct extent_map *em)
|
| 208 | {
|
| 209 | if (em->flags & EXTENT_FLAG_PINNED)
|
| 210 | return false;
|
| 211 |
|
| 212 |
|
| 213 | if (btrfs_extent_map_is_compressed(em))
|
| 214 | return false;
|
| 215 |
|
| 216 | if (em->flags & EXTENT_FLAG_LOGGING)
|
| 217 | return false;
|
| 218 |
|
| 219 | |
| 220 | * We don't want to merge stuff that hasn't been written to the log yet
|
| 221 | * since it may not reflect exactly what is on disk, and that would be
|
| 222 | * bad.
|
| 223 |
|
| 224 | if (!list_empty(&em->list))
|
| 225 | return false;
|
| 226 |
|
| 227 | return true;
|
| 228 | }
|
| 229 |
|
| 230 |
|
| 231 | static bool mergeable_maps(const struct extent_map *prev, const struct extent_map *next)
|
| 232 | {
|
| 233 | if (btrfs_extent_map_end(prev) != next->start)
|
| 234 | return false;
|
| 235 |
|
| 236 | |
| 237 | * The merged flag is not an on-disk flag, it just indicates we had the
|
| 238 | * extent maps of 2 (or more) adjacent extents merged, so factor it out.
|
| 239 |
|
| 240 | if ((prev->flags & ~EXTENT_FLAG_MERGED) !=
|
| 241 | (next->flags & ~EXTENT_FLAG_MERGED))
|
| 242 | return false;
|
| 243 |
|
| 244 | if (next->disk_bytenr < EXTENT_MAP_LAST_BYTE - 1)
|
| 245 | return btrfs_extent_map_block_start(next) == extent_map_block_end(prev);
|
| 246 |
|
| 247 |
|
| 248 | return next->disk_bytenr == prev->disk_bytenr;
|
| 249 | }
|
| 250 |
|
| 251 | |
| 252 | * Handle the on-disk data extents merge for @prev and @next.
|
| 253 | *
|
| 254 | * @prev: left extent to merge
|
| 255 | * @next: right extent to merge
|
| 256 | * @merged: the extent we will not discard after the merge; updated with new values
|
| 257 | *
|
| 258 | * After this, one of the two extents is the new merged extent and the other is
|
| 259 | * removed from the tree and likely freed. Note that @merged is one of @prev/@next
|
| 260 | * so there is const/non-const aliasing occurring here.
|
| 261 | *
|
| 262 | * Only touches disk_bytenr/disk_num_bytes/offset/ram_bytes.
|
| 263 | * For now only uncompressed regular extent can be merged.
|
| 264 |
|
| 265 | static void merge_ondisk_extents(const struct extent_map *prev, const struct extent_map *next,
|
| 266 | struct extent_map *merged)
|
| 267 | {
|
| 268 | u64 new_disk_bytenr;
|
| 269 | u64 new_disk_num_bytes;
|
| 270 | u64 new_offset;
|
| 271 |
|
| 272 |
|
| 273 | ASSERT(!btrfs_extent_map_is_compressed(prev));
|
| 274 | ASSERT(!btrfs_extent_map_is_compressed(next));
|
| 275 |
|
| 276 | |
| 277 | * There are two different cases where @prev and @next can be merged.
|
| 278 | *
|
| 279 | * 1) They are referring to the same data extent:
|
| 280 | *
|
| 281 | * |<----- data extent A ----->|
|
| 282 | * |<- prev ->|<- next ->|
|
| 283 | *
|
| 284 | * 2) They are referring to different data extents but still adjacent:
|
| 285 | *
|
| 286 | * |<-- data extent A -->|<-- data extent B -->|
|
| 287 | * |<- prev ->|<- next ->|
|
| 288 | *
|
| 289 | * The calculation here always merges the data extents first, then updates
|
| 290 | * @offset using the new data extents.
|
| 291 | *
|
| 292 | * For case 1), the merged data extent would be the same.
|
| 293 | * For case 2), we just merge the two data extents into one.
|
| 294 |
|
| 295 | new_disk_bytenr = min(prev->disk_bytenr, next->disk_bytenr);
|
| 296 | new_disk_num_bytes = max(prev->disk_bytenr + prev->disk_num_bytes,
|
| 297 | next->disk_bytenr + next->disk_num_bytes) -
|
| 298 | new_disk_bytenr;
|
| 299 | new_offset = prev->disk_bytenr + prev->offset - new_disk_bytenr;
|
| 300 |
|
| 301 | merged->disk_bytenr = new_disk_bytenr;
|
| 302 | merged->disk_num_bytes = new_disk_num_bytes;
|
| 303 | merged->ram_bytes = new_disk_num_bytes;
|
| 304 | merged->offset = new_offset;
|
| 305 | }
|
| 306 |
|
| 307 | static void dump_extent_map(struct btrfs_fs_info *fs_info, const char *prefix,
|
| 308 | struct extent_map *em)
|
| 309 | {
|
| 310 | if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
|
| 311 | return;
|
| 312 | btrfs_crit(fs_info,
|
| 313 | "%s, start=%llu len=%llu disk_bytenr=%llu disk_num_bytes=%llu ram_bytes=%llu offset=%llu flags=0x%x",
|
| 314 | prefix, em->start, em->len, em->disk_bytenr, em->disk_num_bytes,
|
| 315 | em->ram_bytes, em->offset, em->flags);
|
| 316 | ASSERT(0);
|
| 317 | }
|
| 318 |
|
| 319 |
|
| 320 | static void validate_extent_map(struct btrfs_fs_info *fs_info, struct extent_map *em)
|
| 321 | {
|
| 322 | const u32 blocksize = fs_info->sectorsize;
|
| 323 |
|
| 324 | if (!IS_ENABLED(CONFIG_BTRFS_DEBUG))
|
| 325 | return;
|
| 326 |
|
| 327 | if (!IS_ALIGNED(em->start, blocksize) ||
|
| 328 | !IS_ALIGNED(em->len, blocksize))
|
| 329 | dump_extent_map(fs_info, "unaligned start offset or length members", em);
|
| 330 |
|
| 331 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
|
| 332 | if (em->disk_num_bytes == 0)
|
| 333 | dump_extent_map(fs_info, "zero disk_num_bytes", em);
|
| 334 | if (em->offset + em->len > em->ram_bytes)
|
| 335 | dump_extent_map(fs_info, "ram_bytes too small", em);
|
| 336 | if (em->offset + em->len > em->disk_num_bytes &&
|
| 337 | !btrfs_extent_map_is_compressed(em))
|
| 338 | dump_extent_map(fs_info, "disk_num_bytes too small", em);
|
| 339 | if (!btrfs_extent_map_is_compressed(em) &&
|
| 340 | em->ram_bytes != em->disk_num_bytes)
|
| 341 | dump_extent_map(fs_info,
|
| 342 | "ram_bytes mismatch with disk_num_bytes for non-compressed em",
|
| 343 | em);
|
| 344 | if (!IS_ALIGNED(em->disk_bytenr, blocksize) ||
|
| 345 | !IS_ALIGNED(em->disk_num_bytes, blocksize) ||
|
| 346 | !IS_ALIGNED(em->offset, blocksize) ||
|
| 347 | !IS_ALIGNED(em->ram_bytes, blocksize))
|
| 348 | dump_extent_map(fs_info, "unaligned members", em);
|
| 349 | } else if (em->offset) {
|
| 350 | dump_extent_map(fs_info, "non-zero offset for hole/inline", em);
|
| 351 | }
|
| 352 | }
|
| 353 |
|
| 354 | static void try_merge_map(struct btrfs_inode *inode, struct extent_map *em)
|
| 355 | {
|
| 356 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 357 | struct extent_map *merge = NULL;
|
| 358 | struct rb_node *rb;
|
| 359 |
|
| 360 | |
| 361 | * We can't modify an extent map that is in the tree and that is being
|
| 362 | * used by another task, as it can cause that other task to see it in
|
| 363 | * inconsistent state during the merging. We always have 1 reference for
|
| 364 | * the tree and 1 for this task (which is unpinning the extent map or
|
| 365 | * clearing the logging flag), so anything > 2 means it's being used by
|
| 366 | * other tasks too.
|
| 367 |
|
| 368 | if (refcount_read(&em->refs) > 2)
|
| 369 | return;
|
| 370 |
|
| 371 | if (!can_merge_extent_map(em))
|
| 372 | return;
|
| 373 |
|
| 374 | if (em->start != 0) {
|
| 375 | rb = rb_prev(&em->rb_node);
|
| 376 | merge = rb_entry_safe(rb, struct extent_map, rb_node);
|
| 377 |
|
| 378 | if (rb && can_merge_extent_map(merge) && mergeable_maps(merge, em)) {
|
| 379 | em->start = merge->start;
|
| 380 | em->len += merge->len;
|
| 381 | em->generation = max(em->generation, merge->generation);
|
| 382 |
|
| 383 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
|
| 384 | merge_ondisk_extents(merge, em, em);
|
| 385 | em->flags |= EXTENT_FLAG_MERGED;
|
| 386 |
|
| 387 | validate_extent_map(fs_info, em);
|
| 388 | remove_em(inode, merge);
|
| 389 | btrfs_free_extent_map(merge);
|
| 390 | }
|
| 391 | }
|
| 392 |
|
| 393 | rb = rb_next(&em->rb_node);
|
| 394 | merge = rb_entry_safe(rb, struct extent_map, rb_node);
|
| 395 |
|
| 396 | if (rb && can_merge_extent_map(merge) && mergeable_maps(em, merge)) {
|
| 397 | em->len += merge->len;
|
| 398 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
|
| 399 | merge_ondisk_extents(em, merge, em);
|
| 400 | validate_extent_map(fs_info, em);
|
| 401 | em->generation = max(em->generation, merge->generation);
|
| 402 | em->flags |= EXTENT_FLAG_MERGED;
|
| 403 | remove_em(inode, merge);
|
| 404 | btrfs_free_extent_map(merge);
|
| 405 | }
|
| 406 | }
|
| 407 |
|
| 408 | |
| 409 | * Unpin an extent from the cache.
|
| 410 | *
|
| 411 | * @inode: the inode from which we are unpinning an extent range
|
| 412 | * @start: logical offset in the file
|
| 413 | * @len: length of the extent
|
| 414 | * @gen: generation that this extent has been modified in
|
| 415 | *
|
| 416 | * Called after an extent has been written to disk properly. Set the generation
|
| 417 | * to the generation that actually added the file item to the inode so we know
|
| 418 | * we need to sync this extent when we call fsync().
|
| 419 | *
|
| 420 | * Returns: 0 on success
|
| 421 | * -ENOENT when the extent is not found in the tree
|
| 422 | * -EUCLEAN if the found extent does not match the expected start
|
| 423 |
|
| 424 | int btrfs_unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen)
|
| 425 | {
|
| 426 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 427 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 428 | int ret = 0;
|
| 429 | struct extent_map *em;
|
| 430 |
|
| 431 | write_lock(&tree->lock);
|
| 432 | em = btrfs_lookup_extent_mapping(tree, start, len);
|
| 433 |
|
| 434 | if (WARN_ON(!em)) {
|
| 435 | btrfs_warn(fs_info,
|
| 436 | "no extent map found for inode %llu (root %lld) when unpinning extent range [%llu, %llu), generation %llu",
|
| 437 | btrfs_ino(inode), btrfs_root_id(inode->root),
|
| 438 | start, start + len, gen);
|
| 439 | ret = -ENOENT;
|
| 440 | goto out;
|
| 441 | }
|
| 442 |
|
| 443 | if (WARN_ON(em->start != start)) {
|
| 444 | btrfs_warn(fs_info,
|
| 445 | "found extent map for inode %llu (root %lld) with unexpected start offset %llu when unpinning extent range [%llu, %llu), generation %llu",
|
| 446 | btrfs_ino(inode), btrfs_root_id(inode->root),
|
| 447 | em->start, start, start + len, gen);
|
| 448 | ret = -EUCLEAN;
|
| 449 | goto out;
|
| 450 | }
|
| 451 |
|
| 452 | em->generation = gen;
|
| 453 | em->flags &= ~EXTENT_FLAG_PINNED;
|
| 454 |
|
| 455 | try_merge_map(inode, em);
|
| 456 |
|
| 457 | out:
|
| 458 | write_unlock(&tree->lock);
|
| 459 | btrfs_free_extent_map(em);
|
| 460 | return ret;
|
| 461 |
|
| 462 | }
|
| 463 |
|
| 464 | void btrfs_clear_em_logging(struct btrfs_inode *inode, struct extent_map *em)
|
| 465 | {
|
| 466 | lockdep_assert_held_write(&inode->extent_tree.lock);
|
| 467 |
|
| 468 | em->flags &= ~EXTENT_FLAG_LOGGING;
|
| 469 | if (btrfs_extent_map_in_tree(em))
|
| 470 | try_merge_map(inode, em);
|
| 471 | }
|
| 472 |
|
| 473 | static inline void setup_extent_mapping(struct btrfs_inode *inode,
|
| 474 | struct extent_map *em,
|
| 475 | bool modified)
|
| 476 | {
|
| 477 | refcount_inc(&em->refs);
|
| 478 |
|
| 479 | ASSERT(list_empty(&em->list));
|
| 480 |
|
| 481 | if (modified)
|
| 482 | list_add(&em->list, &inode->extent_tree.modified_extents);
|
| 483 | else
|
| 484 | try_merge_map(inode, em);
|
| 485 | }
|
| 486 |
|
| 487 | |
| 488 | * Add a new extent map to an inode's extent map tree.
|
| 489 | *
|
| 490 | * @inode: the target inode
|
| 491 | * @em: map to insert
|
| 492 | * @modified: indicate whether the given @em should be added to the
|
| 493 | * modified list, which indicates the extent needs to be logged
|
| 494 | *
|
| 495 | * Insert @em into the @inode's extent map tree or perform a simple
|
| 496 | * forward/backward merge with existing mappings. The extent_map struct passed
|
| 497 | * in will be inserted into the tree directly, with an additional reference
|
| 498 | * taken, or a reference dropped if the merge attempt was successful.
|
| 499 |
|
| 500 | static int add_extent_mapping(struct btrfs_inode *inode,
|
| 501 | struct extent_map *em, bool modified)
|
| 502 | {
|
| 503 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 504 | struct btrfs_root *root = inode->root;
|
| 505 | struct btrfs_fs_info *fs_info = root->fs_info;
|
| 506 | int ret;
|
| 507 |
|
| 508 | lockdep_assert_held_write(&tree->lock);
|
| 509 |
|
| 510 | validate_extent_map(fs_info, em);
|
| 511 | ret = tree_insert(&tree->root, em);
|
| 512 | if (ret)
|
| 513 | return ret;
|
| 514 |
|
| 515 | setup_extent_mapping(inode, em, modified);
|
| 516 |
|
| 517 | if (!btrfs_is_testing(fs_info) && btrfs_is_fstree(btrfs_root_id(root)))
|
| 518 | percpu_counter_inc(&fs_info->evictable_extent_maps);
|
| 519 |
|
| 520 | return 0;
|
| 521 | }
|
| 522 |
|
| 523 | static struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
|
| 524 | u64 start, u64 len, bool strict)
|
| 525 | {
|
| 526 | struct extent_map *em;
|
| 527 | struct rb_node *rb_node;
|
| 528 | struct rb_node *prev_or_next = NULL;
|
| 529 | u64 end = range_end(start, len);
|
| 530 |
|
| 531 | rb_node = tree_search(&tree->root, start, &prev_or_next);
|
| 532 | if (!rb_node) {
|
| 533 | if (prev_or_next)
|
| 534 | rb_node = prev_or_next;
|
| 535 | else
|
| 536 | return NULL;
|
| 537 | }
|
| 538 |
|
| 539 | em = rb_entry(rb_node, struct extent_map, rb_node);
|
| 540 |
|
| 541 | if (strict && !(end > em->start && start < btrfs_extent_map_end(em)))
|
| 542 | return NULL;
|
| 543 |
|
| 544 | refcount_inc(&em->refs);
|
| 545 | return em;
|
| 546 | }
|
| 547 |
|
| 548 | |
| 549 | * Lookup extent_map that intersects @start + @len range.
|
| 550 | *
|
| 551 | * @tree: tree to lookup in
|
| 552 | * @start: byte offset to start the search
|
| 553 | * @len: length of the lookup range
|
| 554 | *
|
| 555 | * Find and return the first extent_map struct in @tree that intersects the
|
| 556 | * [start, len] range. There may be additional objects in the tree that
|
| 557 | * intersect, so check the object returned carefully to make sure that no
|
| 558 | * additional lookups are needed.
|
| 559 |
|
| 560 | struct extent_map *btrfs_lookup_extent_mapping(struct extent_map_tree *tree,
|
| 561 | u64 start, u64 len)
|
| 562 | {
|
| 563 | return lookup_extent_mapping(tree, start, len, true);
|
| 564 | }
|
| 565 |
|
| 566 | |
| 567 | * Find a nearby extent map intersecting @start + @len (not an exact search).
|
| 568 | *
|
| 569 | * @tree: tree to lookup in
|
| 570 | * @start: byte offset to start the search
|
| 571 | * @len: length of the lookup range
|
| 572 | *
|
| 573 | * Find and return the first extent_map struct in @tree that intersects the
|
| 574 | * [start, len] range.
|
| 575 | *
|
| 576 | * If one can't be found, any nearby extent may be returned
|
| 577 |
|
| 578 | struct extent_map *btrfs_search_extent_mapping(struct extent_map_tree *tree,
|
| 579 | u64 start, u64 len)
|
| 580 | {
|
| 581 | return lookup_extent_mapping(tree, start, len, false);
|
| 582 | }
|
| 583 |
|
| 584 | |
| 585 | * Remove an extent_map from its inode's extent tree.
|
| 586 | *
|
| 587 | * @inode: the inode the extent map belongs to
|
| 588 | * @em: extent map being removed
|
| 589 | *
|
| 590 | * Remove @em from the extent tree of @inode. No reference counts are dropped,
|
| 591 | * and no checks are done to see if the range is in use.
|
| 592 |
|
| 593 | void btrfs_remove_extent_mapping(struct btrfs_inode *inode, struct extent_map *em)
|
| 594 | {
|
| 595 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 596 |
|
| 597 | lockdep_assert_held_write(&tree->lock);
|
| 598 |
|
| 599 | WARN_ON(em->flags & EXTENT_FLAG_PINNED);
|
| 600 | if (!(em->flags & EXTENT_FLAG_LOGGING))
|
| 601 | list_del_init(&em->list);
|
| 602 |
|
| 603 | remove_em(inode, em);
|
| 604 | }
|
| 605 |
|
| 606 | static void replace_extent_mapping(struct btrfs_inode *inode,
|
| 607 | struct extent_map *cur,
|
| 608 | struct extent_map *new,
|
| 609 | bool modified)
|
| 610 | {
|
| 611 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 612 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 613 |
|
| 614 | lockdep_assert_held_write(&tree->lock);
|
| 615 |
|
| 616 | validate_extent_map(fs_info, new);
|
| 617 |
|
| 618 | WARN_ON(cur->flags & EXTENT_FLAG_PINNED);
|
| 619 | ASSERT(btrfs_extent_map_in_tree(cur));
|
| 620 | if (!(cur->flags & EXTENT_FLAG_LOGGING))
|
| 621 | list_del_init(&cur->list);
|
| 622 | rb_replace_node(&cur->rb_node, &new->rb_node, &tree->root);
|
| 623 | RB_CLEAR_NODE(&cur->rb_node);
|
| 624 |
|
| 625 | setup_extent_mapping(inode, new, modified);
|
| 626 | }
|
| 627 |
|
| 628 | static struct extent_map *next_extent_map(const struct extent_map *em)
|
| 629 | {
|
| 630 | struct rb_node *next;
|
| 631 |
|
| 632 | next = rb_next(&em->rb_node);
|
| 633 | if (!next)
|
| 634 | return NULL;
|
| 635 | return container_of(next, struct extent_map, rb_node);
|
| 636 | }
|
| 637 |
|
| 638 | static struct extent_map *prev_extent_map(struct extent_map *em)
|
| 639 | {
|
| 640 | struct rb_node *prev;
|
| 641 |
|
| 642 | prev = rb_prev(&em->rb_node);
|
| 643 | if (!prev)
|
| 644 | return NULL;
|
| 645 | return container_of(prev, struct extent_map, rb_node);
|
| 646 | }
|
| 647 |
|
| 648 | |
| 649 | * Helper for btrfs_get_extent. Given an existing extent in the tree,
|
| 650 | * the existing extent is the nearest extent to map_start,
|
| 651 | * and an extent that you want to insert, deal with overlap and insert
|
| 652 | * the best fitted new extent into the tree.
|
| 653 |
|
| 654 | static noinline int merge_extent_mapping(struct btrfs_inode *inode,
|
| 655 | struct extent_map *existing,
|
| 656 | struct extent_map *em,
|
| 657 | u64 map_start)
|
| 658 | {
|
| 659 | struct extent_map *prev;
|
| 660 | struct extent_map *next;
|
| 661 | u64 start;
|
| 662 | u64 end;
|
| 663 | u64 start_diff;
|
| 664 |
|
| 665 | if (map_start < em->start || map_start >= btrfs_extent_map_end(em))
|
| 666 | return -EINVAL;
|
| 667 |
|
| 668 | if (existing->start > map_start) {
|
| 669 | next = existing;
|
| 670 | prev = prev_extent_map(next);
|
| 671 | } else {
|
| 672 | prev = existing;
|
| 673 | next = next_extent_map(prev);
|
| 674 | }
|
| 675 |
|
| 676 | start = prev ? btrfs_extent_map_end(prev) : em->start;
|
| 677 | start = max_t(u64, start, em->start);
|
| 678 | end = next ? next->start : btrfs_extent_map_end(em);
|
| 679 | end = min_t(u64, end, btrfs_extent_map_end(em));
|
| 680 | start_diff = start - em->start;
|
| 681 | em->start = start;
|
| 682 | em->len = end - start;
|
| 683 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
|
| 684 | em->offset += start_diff;
|
| 685 | return add_extent_mapping(inode, em, false);
|
| 686 | }
|
| 687 |
|
| 688 | |
| 689 | * Add extent mapping into an inode's extent map tree.
|
| 690 | *
|
| 691 | * @inode: target inode
|
| 692 | * @em_in: extent we are inserting
|
| 693 | * @start: start of the logical range btrfs_get_extent() is requesting
|
| 694 | * @len: length of the logical range btrfs_get_extent() is requesting
|
| 695 | *
|
| 696 | * Note that @em_in's range may be different from [start, start+len),
|
| 697 | * but they must be overlapped.
|
| 698 | *
|
| 699 | * Insert @em_in into the inode's extent map tree. In case there is an
|
| 700 | * overlapping range, handle the -EEXIST by either:
|
| 701 | * a) Returning the existing extent in @em_in if @start is within the
|
| 702 | * existing em.
|
| 703 | * b) Merge the existing extent with @em_in passed in.
|
| 704 | *
|
| 705 | * Return 0 on success, otherwise -EEXIST.
|
| 706 | *
|
| 707 |
|
| 708 | int btrfs_add_extent_mapping(struct btrfs_inode *inode,
|
| 709 | struct extent_map **em_in, u64 start, u64 len)
|
| 710 | {
|
| 711 | int ret;
|
| 712 | struct extent_map *em = *em_in;
|
| 713 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 714 |
|
| 715 | |
| 716 | * Tree-checker should have rejected any inline extent with non-zero
|
| 717 | * file offset. Here just do a sanity check.
|
| 718 |
|
| 719 | if (em->disk_bytenr == EXTENT_MAP_INLINE)
|
| 720 | ASSERT(em->start == 0, "em->start=%llu", em->start);
|
| 721 |
|
| 722 | ret = add_extent_mapping(inode, em, false);
|
| 723 | |
| 724 | * while we had the lock dropped. It is also possible that
|
| 725 | * an overlapping map exists in the tree
|
| 726 |
|
| 727 | if (ret == -EEXIST) {
|
| 728 | struct extent_map *existing;
|
| 729 |
|
| 730 | existing = btrfs_search_extent_mapping(&inode->extent_tree, start, len);
|
| 731 |
|
| 732 | trace_btrfs_handle_em_exist(fs_info, existing, em, start, len);
|
| 733 |
|
| 734 | |
| 735 | * existing will always be non-NULL, since there must be
|
| 736 | * extent causing the -EEXIST.
|
| 737 |
|
| 738 | if (start >= existing->start &&
|
| 739 | start < btrfs_extent_map_end(existing)) {
|
| 740 | btrfs_free_extent_map(em);
|
| 741 | *em_in = existing;
|
| 742 | ret = 0;
|
| 743 | } else {
|
| 744 | u64 orig_start = em->start;
|
| 745 | u64 orig_len = em->len;
|
| 746 |
|
| 747 | |
| 748 | * The existing extent map is the one nearest to
|
| 749 | * the [start, start + len) range which overlaps
|
| 750 |
|
| 751 | ret = merge_extent_mapping(inode, existing, em, start);
|
| 752 | if (WARN_ON(ret)) {
|
| 753 | btrfs_free_extent_map(em);
|
| 754 | *em_in = NULL;
|
| 755 | btrfs_warn(fs_info,
|
| 756 | "extent map merge error existing [%llu, %llu) with em [%llu, %llu) start %llu",
|
| 757 | existing->start, btrfs_extent_map_end(existing),
|
| 758 | orig_start, orig_start + orig_len, start);
|
| 759 | }
|
| 760 | btrfs_free_extent_map(existing);
|
| 761 | }
|
| 762 | }
|
| 763 |
|
| 764 | ASSERT(ret == 0 || ret == -EEXIST, "ret=%d", ret);
|
| 765 | return ret;
|
| 766 | }
|
| 767 |
|
| 768 | |
| 769 | * Drop all extent maps from a tree in the fastest possible way, rescheduling
|
| 770 | * if needed. This avoids searching the tree, from the root down to the first
|
| 771 | * extent map, before each deletion.
|
| 772 |
|
| 773 | static void drop_all_extent_maps_fast(struct btrfs_inode *inode)
|
| 774 | {
|
| 775 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 776 | struct rb_node *node;
|
| 777 |
|
| 778 | write_lock(&tree->lock);
|
| 779 | node = rb_first(&tree->root);
|
| 780 | while (node) {
|
| 781 | struct extent_map *em;
|
| 782 | struct rb_node *next = rb_next(node);
|
| 783 |
|
| 784 | em = rb_entry(node, struct extent_map, rb_node);
|
| 785 | em->flags &= ~(EXTENT_FLAG_PINNED | EXTENT_FLAG_LOGGING);
|
| 786 | btrfs_remove_extent_mapping(inode, em);
|
| 787 | btrfs_free_extent_map(em);
|
| 788 |
|
| 789 | if (cond_resched_rwlock_write(&tree->lock))
|
| 790 | node = rb_first(&tree->root);
|
| 791 | else
|
| 792 | node = next;
|
| 793 | }
|
| 794 | write_unlock(&tree->lock);
|
| 795 | }
|
| 796 |
|
| 797 | |
| 798 | * Drop all extent maps in a given range.
|
| 799 | *
|
| 800 | * @inode: The target inode.
|
| 801 | * @start: Start offset of the range.
|
| 802 | * @end: End offset of the range (inclusive value).
|
| 803 | * @skip_pinned: Indicate if pinned extent maps should be ignored or not.
|
| 804 | *
|
| 805 | * This drops all the extent maps that intersect the given range [@start, @end].
|
| 806 | * Extent maps that partially overlap the range and extend behind or beyond it,
|
| 807 | * are split.
|
| 808 | * The caller should have locked an appropriate file range in the inode's io
|
| 809 | * tree before calling this function.
|
| 810 |
|
| 811 | void btrfs_drop_extent_map_range(struct btrfs_inode *inode, u64 start, u64 end,
|
| 812 | bool skip_pinned)
|
| 813 | {
|
| 814 | struct extent_map *split;
|
| 815 | struct extent_map *split2;
|
| 816 | struct extent_map *em;
|
| 817 | struct extent_map_tree *em_tree = &inode->extent_tree;
|
| 818 | u64 len = end - start + 1;
|
| 819 |
|
| 820 | WARN_ON(end < start);
|
| 821 | if (end == (u64)-1) {
|
| 822 | if (start == 0 && !skip_pinned) {
|
| 823 | drop_all_extent_maps_fast(inode);
|
| 824 | return;
|
| 825 | }
|
| 826 | len = (u64)-1;
|
| 827 | } else {
|
| 828 |
|
| 829 | end++;
|
| 830 | }
|
| 831 |
|
| 832 | |
| 833 | * It's ok if we fail to allocate the extent maps, see the comment near
|
| 834 | * the bottom of the loop below. We only need two spare extent maps in
|
| 835 | * the worst case, where the first extent map that intersects our range
|
| 836 | * starts before the range and the last extent map that intersects our
|
| 837 | * range ends after our range (and they might be the same extent map),
|
| 838 | * because we need to split those two extent maps at the boundaries.
|
| 839 |
|
| 840 | split = btrfs_alloc_extent_map();
|
| 841 | split2 = btrfs_alloc_extent_map();
|
| 842 |
|
| 843 | write_lock(&em_tree->lock);
|
| 844 | em = btrfs_lookup_extent_mapping(em_tree, start, len);
|
| 845 |
|
| 846 | while (em) {
|
| 847 |
|
| 848 | const u64 em_end = btrfs_extent_map_end(em);
|
| 849 | struct extent_map *next_em = NULL;
|
| 850 | u64 gen;
|
| 851 | unsigned long flags;
|
| 852 | bool modified;
|
| 853 |
|
| 854 | if (em_end < end) {
|
| 855 | next_em = next_extent_map(em);
|
| 856 | if (next_em) {
|
| 857 | if (next_em->start < end)
|
| 858 | refcount_inc(&next_em->refs);
|
| 859 | else
|
| 860 | next_em = NULL;
|
| 861 | }
|
| 862 | }
|
| 863 |
|
| 864 | if (skip_pinned && (em->flags & EXTENT_FLAG_PINNED)) {
|
| 865 | start = em_end;
|
| 866 | goto next;
|
| 867 | }
|
| 868 |
|
| 869 | |
| 870 | * In case we split the extent map, we want to preserve the
|
| 871 | * EXTENT_FLAG_LOGGING flag on our extent map, but we don't want
|
| 872 | * it on the new extent maps.
|
| 873 |
|
| 874 | flags = em->flags & ~EXTENT_FLAG_LOGGING;
|
| 875 | em->flags &= ~EXTENT_FLAG_PINNED;
|
| 876 | modified = !list_empty(&em->list);
|
| 877 |
|
| 878 | |
| 879 | * The extent map does not cross our target range, so no need to
|
| 880 | * split it, we can remove it directly.
|
| 881 |
|
| 882 | if (em->start >= start && em_end <= end)
|
| 883 | goto remove_em;
|
| 884 |
|
| 885 | gen = em->generation;
|
| 886 |
|
| 887 | if (em->start < start) {
|
| 888 | if (!split) {
|
| 889 | split = split2;
|
| 890 | split2 = NULL;
|
| 891 | if (!split)
|
| 892 | goto remove_em;
|
| 893 | }
|
| 894 | split->start = em->start;
|
| 895 | split->len = start - em->start;
|
| 896 |
|
| 897 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
|
| 898 | split->disk_bytenr = em->disk_bytenr;
|
| 899 | split->disk_num_bytes = em->disk_num_bytes;
|
| 900 | split->offset = em->offset;
|
| 901 | split->ram_bytes = em->ram_bytes;
|
| 902 | } else {
|
| 903 | split->disk_bytenr = em->disk_bytenr;
|
| 904 | split->disk_num_bytes = 0;
|
| 905 | split->offset = 0;
|
| 906 | split->ram_bytes = split->len;
|
| 907 | }
|
| 908 |
|
| 909 | split->generation = gen;
|
| 910 | split->flags = flags;
|
| 911 | replace_extent_mapping(inode, em, split, modified);
|
| 912 | btrfs_free_extent_map(split);
|
| 913 | split = split2;
|
| 914 | split2 = NULL;
|
| 915 | }
|
| 916 | if (em_end > end) {
|
| 917 | if (!split) {
|
| 918 | split = split2;
|
| 919 | split2 = NULL;
|
| 920 | if (!split)
|
| 921 | goto remove_em;
|
| 922 | }
|
| 923 | split->start = end;
|
| 924 | split->len = em_end - end;
|
| 925 | split->disk_bytenr = em->disk_bytenr;
|
| 926 | split->flags = flags;
|
| 927 | split->generation = gen;
|
| 928 |
|
| 929 | if (em->disk_bytenr < EXTENT_MAP_LAST_BYTE) {
|
| 930 | split->disk_num_bytes = em->disk_num_bytes;
|
| 931 | split->offset = em->offset + end - em->start;
|
| 932 | split->ram_bytes = em->ram_bytes;
|
| 933 | } else {
|
| 934 | split->disk_num_bytes = 0;
|
| 935 | split->offset = 0;
|
| 936 | split->ram_bytes = split->len;
|
| 937 | }
|
| 938 |
|
| 939 | if (btrfs_extent_map_in_tree(em)) {
|
| 940 | replace_extent_mapping(inode, em, split, modified);
|
| 941 | } else {
|
| 942 | int ret;
|
| 943 |
|
| 944 | ret = add_extent_mapping(inode, split, modified);
|
| 945 |
|
| 946 | ASSERT(ret == 0, "ret=%d", ret);
|
| 947 | if (WARN_ON(ret != 0) && modified)
|
| 948 | btrfs_set_inode_full_sync(inode);
|
| 949 | }
|
| 950 | btrfs_free_extent_map(split);
|
| 951 | split = NULL;
|
| 952 | }
|
| 953 | remove_em:
|
| 954 | if (btrfs_extent_map_in_tree(em)) {
|
| 955 | |
| 956 | * If the extent map is still in the tree it means that
|
| 957 | * either of the following is true:
|
| 958 | *
|
| 959 | * 1) It fits entirely in our range (doesn't end beyond
|
| 960 | * it or starts before it);
|
| 961 | *
|
| 962 | * 2) It starts before our range and/or ends after our
|
| 963 | * range, and we were not able to allocate the extent
|
| 964 | * maps for split operations, @split and @split2.
|
| 965 | *
|
| 966 | * If we are at case 2) then we just remove the entire
|
| 967 | * extent map - this is fine since if anyone needs it to
|
| 968 | * access the subranges outside our range, will just
|
| 969 | * load it again from the subvolume tree's file extent
|
| 970 | * item. However if the extent map was in the list of
|
| 971 | * modified extents, then we must mark the inode for a
|
| 972 | * full fsync, otherwise a fast fsync will miss this
|
| 973 | * extent if it's new and needs to be logged.
|
| 974 |
|
| 975 | if ((em->start < start || em_end > end) && modified) {
|
| 976 | ASSERT(!split);
|
| 977 | btrfs_set_inode_full_sync(inode);
|
| 978 | }
|
| 979 | btrfs_remove_extent_mapping(inode, em);
|
| 980 | }
|
| 981 |
|
| 982 | |
| 983 | * Once for the tree reference (we replaced or removed the
|
| 984 | * extent map from the tree).
|
| 985 |
|
| 986 | btrfs_free_extent_map(em);
|
| 987 | next:
|
| 988 |
|
| 989 | btrfs_free_extent_map(em);
|
| 990 |
|
| 991 | em = next_em;
|
| 992 | }
|
| 993 |
|
| 994 | write_unlock(&em_tree->lock);
|
| 995 |
|
| 996 | btrfs_free_extent_map(split);
|
| 997 | btrfs_free_extent_map(split2);
|
| 998 | }
|
| 999 |
|
| 1000 | |
| 1001 | * Replace a range in the inode's extent map tree with a new extent map.
|
| 1002 | *
|
| 1003 | * @inode: The target inode.
|
| 1004 | * @new_em: The new extent map to add to the inode's extent map tree.
|
| 1005 | * @modified: Indicate if the new extent map should be added to the list of
|
| 1006 | * modified extents (for fast fsync tracking).
|
| 1007 | *
|
| 1008 | * Drops all the extent maps in the inode's extent map tree that intersect the
|
| 1009 | * range of the new extent map and adds the new extent map to the tree.
|
| 1010 | * The caller should have locked an appropriate file range in the inode's io
|
| 1011 | * tree before calling this function.
|
| 1012 |
|
| 1013 | int btrfs_replace_extent_map_range(struct btrfs_inode *inode,
|
| 1014 | struct extent_map *new_em,
|
| 1015 | bool modified)
|
| 1016 | {
|
| 1017 | const u64 end = new_em->start + new_em->len - 1;
|
| 1018 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 1019 | int ret;
|
| 1020 |
|
| 1021 | ASSERT(!btrfs_extent_map_in_tree(new_em));
|
| 1022 |
|
| 1023 | |
| 1024 | * The caller has locked an appropriate file range in the inode's io
|
| 1025 | * tree, but getting -EEXIST when adding the new extent map can still
|
| 1026 | * happen in case there are extents that partially cover the range, and
|
| 1027 | * this is due to two tasks operating on different parts of the extent.
|
| 1028 | * See commit 18e83ac75bfe67 ("Btrfs: fix unexpected EEXIST from
|
| 1029 | * btrfs_get_extent") for an example and details.
|
| 1030 |
|
| 1031 | do {
|
| 1032 | btrfs_drop_extent_map_range(inode, new_em->start, end, false);
|
| 1033 | write_lock(&tree->lock);
|
| 1034 | ret = add_extent_mapping(inode, new_em, modified);
|
| 1035 | write_unlock(&tree->lock);
|
| 1036 | } while (ret == -EEXIST);
|
| 1037 |
|
| 1038 | return ret;
|
| 1039 | }
|
| 1040 |
|
| 1041 | |
| 1042 | * Split off the first pre bytes from the extent_map at [start, start + len],
|
| 1043 | * and set the block_start for it to new_logical.
|
| 1044 | *
|
| 1045 | * This function is used when an ordered_extent needs to be split.
|
| 1046 |
|
| 1047 | int btrfs_split_extent_map(struct btrfs_inode *inode, u64 start, u64 len, u64 pre,
|
| 1048 | u64 new_logical)
|
| 1049 | {
|
| 1050 | struct extent_map_tree *em_tree = &inode->extent_tree;
|
| 1051 | struct extent_map *em;
|
| 1052 | struct extent_map *split_pre = NULL;
|
| 1053 | struct extent_map *split_mid = NULL;
|
| 1054 | int ret = 0;
|
| 1055 | unsigned long flags;
|
| 1056 |
|
| 1057 | ASSERT(pre != 0);
|
| 1058 | ASSERT(pre < len);
|
| 1059 |
|
| 1060 | split_pre = btrfs_alloc_extent_map();
|
| 1061 | if (!split_pre)
|
| 1062 | return -ENOMEM;
|
| 1063 | split_mid = btrfs_alloc_extent_map();
|
| 1064 | if (!split_mid) {
|
| 1065 | ret = -ENOMEM;
|
| 1066 | goto out_free_pre;
|
| 1067 | }
|
| 1068 |
|
| 1069 | btrfs_lock_extent(&inode->io_tree, start, start + len - 1, NULL);
|
| 1070 | write_lock(&em_tree->lock);
|
| 1071 | em = btrfs_lookup_extent_mapping(em_tree, start, len);
|
| 1072 | if (unlikely(!em)) {
|
| 1073 | ret = -EIO;
|
| 1074 | goto out_unlock;
|
| 1075 | }
|
| 1076 |
|
| 1077 | ASSERT(em->len == len);
|
| 1078 | ASSERT(!btrfs_extent_map_is_compressed(em));
|
| 1079 | ASSERT(em->disk_bytenr < EXTENT_MAP_LAST_BYTE);
|
| 1080 | ASSERT(em->flags & EXTENT_FLAG_PINNED);
|
| 1081 | ASSERT(!(em->flags & EXTENT_FLAG_LOGGING));
|
| 1082 | ASSERT(!list_empty(&em->list));
|
| 1083 |
|
| 1084 | flags = em->flags;
|
| 1085 | em->flags &= ~EXTENT_FLAG_PINNED;
|
| 1086 |
|
| 1087 |
|
| 1088 | split_pre->start = em->start;
|
| 1089 | split_pre->len = pre;
|
| 1090 | split_pre->disk_bytenr = new_logical;
|
| 1091 | split_pre->disk_num_bytes = split_pre->len;
|
| 1092 | split_pre->offset = 0;
|
| 1093 | split_pre->ram_bytes = split_pre->len;
|
| 1094 | split_pre->flags = flags;
|
| 1095 | split_pre->generation = em->generation;
|
| 1096 |
|
| 1097 | replace_extent_mapping(inode, em, split_pre, true);
|
| 1098 |
|
| 1099 | |
| 1100 | * Now we only have an extent_map at:
|
| 1101 | * [em->start, em->start + pre]
|
| 1102 |
|
| 1103 |
|
| 1104 |
|
| 1105 | split_mid->start = em->start + pre;
|
| 1106 | split_mid->len = em->len - pre;
|
| 1107 | split_mid->disk_bytenr = btrfs_extent_map_block_start(em) + pre;
|
| 1108 | split_mid->disk_num_bytes = split_mid->len;
|
| 1109 | split_mid->offset = 0;
|
| 1110 | split_mid->ram_bytes = split_mid->len;
|
| 1111 | split_mid->flags = flags;
|
| 1112 | split_mid->generation = em->generation;
|
| 1113 | add_extent_mapping(inode, split_mid, true);
|
| 1114 |
|
| 1115 |
|
| 1116 | btrfs_free_extent_map(em);
|
| 1117 |
|
| 1118 | btrfs_free_extent_map(em);
|
| 1119 |
|
| 1120 | out_unlock:
|
| 1121 | write_unlock(&em_tree->lock);
|
| 1122 | btrfs_unlock_extent(&inode->io_tree, start, start + len - 1, NULL);
|
| 1123 | btrfs_free_extent_map(split_mid);
|
| 1124 | out_free_pre:
|
| 1125 | btrfs_free_extent_map(split_pre);
|
| 1126 | return ret;
|
| 1127 | }
|
| 1128 |
|
| 1129 | struct btrfs_em_shrink_ctx {
|
| 1130 | long nr_to_scan;
|
| 1131 | long scanned;
|
| 1132 | };
|
| 1133 |
|
| 1134 | static long btrfs_scan_inode(struct btrfs_inode *inode, struct btrfs_em_shrink_ctx *ctx)
|
| 1135 | {
|
| 1136 | struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
| 1137 | const u64 cur_fs_gen = btrfs_get_fs_generation(fs_info);
|
| 1138 | struct extent_map_tree *tree = &inode->extent_tree;
|
| 1139 | long nr_dropped = 0;
|
| 1140 | struct rb_node *node;
|
| 1141 |
|
| 1142 | lockdep_assert_held_write(&tree->lock);
|
| 1143 |
|
| 1144 | |
| 1145 | * Take the mmap lock so that we serialize with the inode logging phase
|
| 1146 | * of fsync because we may need to set the full sync flag on the inode,
|
| 1147 | * in case we have to remove extent maps in the tree's list of modified
|
| 1148 | * extents. If we set the full sync flag in the inode while an fsync is
|
| 1149 | * in progress, we may risk missing new extents because before the flag
|
| 1150 | * is set, fsync decides to only wait for writeback to complete and then
|
| 1151 | * during inode logging it sees the flag set and uses the subvolume tree
|
| 1152 | * to find new extents, which may not be there yet because ordered
|
| 1153 | * extents haven't completed yet.
|
| 1154 | *
|
| 1155 | * We also do a try lock because we don't want to block for too long and
|
| 1156 | * we are holding the extent map tree's lock in write mode.
|
| 1157 |
|
| 1158 | if (!down_read_trylock(&inode->i_mmap_lock))
|
| 1159 | return 0;
|
| 1160 |
|
| 1161 | node = rb_first(&tree->root);
|
| 1162 | while (node) {
|
| 1163 | struct rb_node *next = rb_next(node);
|
| 1164 | struct extent_map *em;
|
| 1165 |
|
| 1166 | em = rb_entry(node, struct extent_map, rb_node);
|
| 1167 | ctx->scanned++;
|
| 1168 |
|
| 1169 | if (em->flags & EXTENT_FLAG_PINNED)
|
| 1170 | goto next;
|
| 1171 |
|
| 1172 | |
| 1173 | * If the inode is in the list of modified extents (new) and its
|
| 1174 | * generation is the same (or is greater than) the current fs
|
| 1175 | * generation, it means it was not yet persisted so we have to
|
| 1176 | * set the full sync flag so that the next fsync will not miss
|
| 1177 | * it.
|
| 1178 |
|
| 1179 | if (!list_empty(&em->list) && em->generation >= cur_fs_gen)
|
| 1180 | btrfs_set_inode_full_sync(inode);
|
| 1181 |
|
| 1182 | btrfs_remove_extent_mapping(inode, em);
|
| 1183 | trace_btrfs_extent_map_shrinker_remove_em(inode, em);
|
| 1184 |
|
| 1185 | btrfs_free_extent_map(em);
|
| 1186 | nr_dropped++;
|
| 1187 | next:
|
| 1188 | if (ctx->scanned >= ctx->nr_to_scan)
|
| 1189 | break;
|
| 1190 |
|
| 1191 | |
| 1192 | * Stop if we need to reschedule or there's contention on the
|
| 1193 | * lock. This is to avoid slowing other tasks trying to take the
|
| 1194 | * lock.
|
| 1195 |
|
| 1196 | if (need_resched() || rwlock_needbreak(&tree->lock) ||
|
| 1197 | btrfs_fs_closing(fs_info))
|
| 1198 | break;
|
| 1199 | node = next;
|
| 1200 | }
|
| 1201 | up_read(&inode->i_mmap_lock);
|
| 1202 |
|
| 1203 | return nr_dropped;
|
| 1204 | }
|
| 1205 |
|
| 1206 | static struct btrfs_inode *find_first_inode_to_shrink(struct btrfs_root *root,
|
| 1207 | u64 min_ino)
|
| 1208 | {
|
| 1209 | struct btrfs_inode *inode;
|
| 1210 | unsigned long from = min_ino;
|
| 1211 |
|
| 1212 | xa_lock(&root->inodes);
|
| 1213 | while (true) {
|
| 1214 | struct extent_map_tree *tree;
|
| 1215 |
|
| 1216 | inode = xa_find(&root->inodes, &from, ULONG_MAX, XA_PRESENT);
|
| 1217 | if (!inode)
|
| 1218 | break;
|
| 1219 |
|
| 1220 | tree = &inode->extent_tree;
|
| 1221 |
|
| 1222 | |
| 1223 | * Most inodes have no extent maps, so check without the lock.
|
| 1224 | * The race is harmless: a false empty just defers the inode to
|
| 1225 | * a later scan, and a false non-empty is caught under the lock.
|
| 1226 |
|
| 1227 | if (data_race(RB_EMPTY_ROOT(&tree->root)))
|
| 1228 | goto next;
|
| 1229 |
|
| 1230 | |
| 1231 | * We want to be fast so if the lock is busy we don't want to
|
| 1232 | * spend time waiting for it (some task is about to do IO for
|
| 1233 | * the inode).
|
| 1234 |
|
| 1235 | if (!write_trylock(&tree->lock))
|
| 1236 | goto next;
|
| 1237 |
|
| 1238 | |
| 1239 | * Skip inode if it doesn't have loaded extent maps, so we avoid
|
| 1240 | * getting a reference and doing an iput later. This includes
|
| 1241 | * cases like files that were opened for things like stat(2), or
|
| 1242 | * files with all extent maps previously released through the
|
| 1243 | * release folio callback (btrfs_release_folio()) or released in
|
| 1244 | * a previous run, or directories which never have extent maps.
|
| 1245 |
|
| 1246 | if (RB_EMPTY_ROOT(&tree->root)) {
|
| 1247 | write_unlock(&tree->lock);
|
| 1248 | goto next;
|
| 1249 | }
|
| 1250 |
|
| 1251 | if (igrab(&inode->vfs_inode))
|
| 1252 | break;
|
| 1253 |
|
| 1254 | write_unlock(&tree->lock);
|
| 1255 | next:
|
| 1256 | from = btrfs_ino(inode) + 1;
|
| 1257 | xa_unlock(&root->inodes);
|
| 1258 | cond_resched();
|
| 1259 | xa_lock(&root->inodes);
|
| 1260 | }
|
| 1261 | xa_unlock(&root->inodes);
|
| 1262 |
|
| 1263 | return inode;
|
| 1264 | }
|
| 1265 |
|
| 1266 | static long btrfs_scan_root(struct btrfs_root *root, struct btrfs_em_shrink_ctx *ctx)
|
| 1267 | {
|
| 1268 | struct btrfs_fs_info *fs_info = root->fs_info;
|
| 1269 | struct btrfs_inode *inode;
|
| 1270 | long nr_dropped = 0;
|
| 1271 | u64 min_ino = fs_info->em_shrinker_last_ino + 1;
|
| 1272 |
|
| 1273 | inode = find_first_inode_to_shrink(root, min_ino);
|
| 1274 | while (inode) {
|
| 1275 | nr_dropped += btrfs_scan_inode(inode, ctx);
|
| 1276 | write_unlock(&inode->extent_tree.lock);
|
| 1277 |
|
| 1278 | min_ino = btrfs_ino(inode) + 1;
|
| 1279 | fs_info->em_shrinker_last_ino = btrfs_ino(inode);
|
| 1280 | iput(&inode->vfs_inode);
|
| 1281 |
|
| 1282 | if (ctx->scanned >= ctx->nr_to_scan || btrfs_fs_closing(fs_info))
|
| 1283 | break;
|
| 1284 |
|
| 1285 | cond_resched();
|
| 1286 |
|
| 1287 | inode = find_first_inode_to_shrink(root, min_ino);
|
| 1288 | }
|
| 1289 |
|
| 1290 | if (inode) {
|
| 1291 | |
| 1292 | * There are still inodes in this root or we happened to process
|
| 1293 | * the last one and reached the scan limit. In either case set
|
| 1294 | * the current root to this one, so we'll resume from the next
|
| 1295 | * inode if there is one or we will find out this was the last
|
| 1296 | * one and move to the next root.
|
| 1297 |
|
| 1298 | fs_info->em_shrinker_last_root = btrfs_root_id(root);
|
| 1299 | } else {
|
| 1300 | |
| 1301 | * No more inodes in this root, set extent_map_shrinker_last_ino to 0 so
|
| 1302 | * that when processing the next root we start from its first inode.
|
| 1303 |
|
| 1304 | fs_info->em_shrinker_last_ino = 0;
|
| 1305 | fs_info->em_shrinker_last_root = btrfs_root_id(root) + 1;
|
| 1306 | }
|
| 1307 |
|
| 1308 | return nr_dropped;
|
| 1309 | }
|
| 1310 |
|
| 1311 | static void btrfs_extent_map_shrinker_worker(struct work_struct *work)
|
| 1312 | {
|
| 1313 | struct btrfs_fs_info *fs_info;
|
| 1314 | struct btrfs_em_shrink_ctx ctx;
|
| 1315 | u64 start_root_id;
|
| 1316 | u64 next_root_id;
|
| 1317 | bool cycled = false;
|
| 1318 | long nr_dropped = 0;
|
| 1319 |
|
| 1320 | fs_info = container_of(work, struct btrfs_fs_info, em_shrinker_work);
|
| 1321 |
|
| 1322 | ctx.scanned = 0;
|
| 1323 | ctx.nr_to_scan = atomic64_read(&fs_info->em_shrinker_nr_to_scan);
|
| 1324 |
|
| 1325 | start_root_id = fs_info->em_shrinker_last_root;
|
| 1326 | next_root_id = fs_info->em_shrinker_last_root;
|
| 1327 |
|
| 1328 | if (trace_btrfs_extent_map_shrinker_scan_enter_enabled()) {
|
| 1329 | s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps);
|
| 1330 |
|
| 1331 | trace_call__btrfs_extent_map_shrinker_scan_enter(fs_info, nr);
|
| 1332 | }
|
| 1333 |
|
| 1334 | while (ctx.scanned < ctx.nr_to_scan && !btrfs_fs_closing(fs_info)) {
|
| 1335 | struct btrfs_root *root;
|
| 1336 | unsigned long count;
|
| 1337 |
|
| 1338 | cond_resched();
|
| 1339 |
|
| 1340 | spin_lock(&fs_info->fs_roots_radix_lock);
|
| 1341 | count = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
|
| 1342 | (void **)&root,
|
| 1343 | (unsigned long)next_root_id, 1);
|
| 1344 | if (count == 0) {
|
| 1345 | spin_unlock(&fs_info->fs_roots_radix_lock);
|
| 1346 | if (start_root_id > 0 && !cycled) {
|
| 1347 | next_root_id = 0;
|
| 1348 | fs_info->em_shrinker_last_root = 0;
|
| 1349 | fs_info->em_shrinker_last_ino = 0;
|
| 1350 | cycled = true;
|
| 1351 | continue;
|
| 1352 | }
|
| 1353 | break;
|
| 1354 | }
|
| 1355 | next_root_id = btrfs_root_id(root) + 1;
|
| 1356 | root = btrfs_grab_root(root);
|
| 1357 | spin_unlock(&fs_info->fs_roots_radix_lock);
|
| 1358 |
|
| 1359 | if (!root)
|
| 1360 | continue;
|
| 1361 |
|
| 1362 | if (btrfs_is_fstree(btrfs_root_id(root)))
|
| 1363 | nr_dropped += btrfs_scan_root(root, &ctx);
|
| 1364 |
|
| 1365 | btrfs_put_root(root);
|
| 1366 | }
|
| 1367 |
|
| 1368 | if (trace_btrfs_extent_map_shrinker_scan_exit_enabled()) {
|
| 1369 | s64 nr = percpu_counter_sum_positive(&fs_info->evictable_extent_maps);
|
| 1370 |
|
| 1371 | trace_call__btrfs_extent_map_shrinker_scan_exit(fs_info, nr_dropped, nr);
|
| 1372 | }
|
| 1373 |
|
| 1374 | atomic64_set(&fs_info->em_shrinker_nr_to_scan, 0);
|
| 1375 | }
|
| 1376 |
|
| 1377 | void btrfs_free_extent_maps(struct btrfs_fs_info *fs_info, long nr_to_scan)
|
| 1378 | {
|
| 1379 | |
| 1380 | * Do nothing if the shrinker is already running. In case of high memory
|
| 1381 | * pressure we can have a lot of tasks calling us and all passing the
|
| 1382 | * same nr_to_scan value, but in reality we may need only to free
|
| 1383 | * nr_to_scan extent maps (or less). In case we need to free more than
|
| 1384 | * that, we will be called again by the fs shrinker, so no worries about
|
| 1385 | * not doing enough work to reclaim memory from extent maps.
|
| 1386 | * We can also be repeatedly called with the same nr_to_scan value
|
| 1387 | * simply because the shrinker runs asynchronously and multiple calls
|
| 1388 | * to this function are made before the shrinker does enough progress.
|
| 1389 | *
|
| 1390 | * That's why we set the atomic counter to nr_to_scan only if its
|
| 1391 | * current value is zero, instead of incrementing the counter by
|
| 1392 | * nr_to_scan.
|
| 1393 |
|
| 1394 | if (atomic64_cmpxchg(&fs_info->em_shrinker_nr_to_scan, 0, nr_to_scan) != 0)
|
| 1395 | return;
|
| 1396 |
|
| 1397 | queue_work(system_dfl_wq, &fs_info->em_shrinker_work);
|
| 1398 | }
|
| 1399 |
|
| 1400 | void btrfs_init_extent_map_shrinker_work(struct btrfs_fs_info *fs_info)
|
| 1401 | {
|
| 1402 | atomic64_set(&fs_info->em_shrinker_nr_to_scan, 0);
|
| 1403 | INIT_WORK(&fs_info->em_shrinker_work, btrfs_extent_map_shrinker_worker);
|
| 1404 | }
|