|
17 | 17 | #include "fs.h"
|
18 | 18 | #include "accessors.h"
|
19 | 19 | #include "bio.h"
|
| 20 | +#include "transaction.h" |
20 | 21 |
|
21 | 22 | /* Maximum number of zones to report per blkdev_report_zones() call */
|
22 | 23 | #define BTRFS_REPORT_NR_ZONES 4096
|
@@ -2501,6 +2502,66 @@ void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg)
|
2501 | 2502 | spin_unlock(&fs_info->relocation_bg_lock);
|
2502 | 2503 | }
|
2503 | 2504 |
|
| 2505 | +void btrfs_zoned_reserve_data_reloc_bg(struct btrfs_fs_info *fs_info) |
| 2506 | +{ |
| 2507 | + struct btrfs_space_info *data_sinfo = fs_info->data_sinfo; |
| 2508 | + struct btrfs_space_info *space_info = data_sinfo->sub_group[0]; |
| 2509 | + struct btrfs_trans_handle *trans; |
| 2510 | + struct btrfs_block_group *bg; |
| 2511 | + struct list_head *bg_list; |
| 2512 | + u64 alloc_flags; |
| 2513 | + bool initial = false; |
| 2514 | + bool did_chunk_alloc = false; |
| 2515 | + int index; |
| 2516 | + int ret; |
| 2517 | + |
| 2518 | + if (!btrfs_is_zoned(fs_info)) |
| 2519 | + return; |
| 2520 | + |
| 2521 | + if (fs_info->data_reloc_bg) |
| 2522 | + return; |
| 2523 | + |
| 2524 | + if (sb_rdonly(fs_info->sb)) |
| 2525 | + return; |
| 2526 | + |
| 2527 | + ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_DATA_RELOC); |
| 2528 | + alloc_flags = btrfs_get_alloc_profile(fs_info, space_info->flags); |
| 2529 | + index = btrfs_bg_flags_to_raid_index(alloc_flags); |
| 2530 | + |
| 2531 | + bg_list = &data_sinfo->block_groups[index]; |
| 2532 | +again: |
| 2533 | + list_for_each_entry(bg, bg_list, list) { |
| 2534 | + if (bg->used > 0) |
| 2535 | + continue; |
| 2536 | + |
| 2537 | + if (!initial) { |
| 2538 | + initial = true; |
| 2539 | + continue; |
| 2540 | + } |
| 2541 | + |
| 2542 | + fs_info->data_reloc_bg = bg->start; |
| 2543 | + set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &bg->runtime_flags); |
| 2544 | + btrfs_zone_activate(bg); |
| 2545 | + |
| 2546 | + return; |
| 2547 | + } |
| 2548 | + |
| 2549 | + if (did_chunk_alloc) |
| 2550 | + return; |
| 2551 | + |
| 2552 | + trans = btrfs_join_transaction(fs_info->tree_root); |
| 2553 | + if (IS_ERR(trans)) |
| 2554 | + return; |
| 2555 | + |
| 2556 | + ret = btrfs_chunk_alloc(trans, space_info, alloc_flags, CHUNK_ALLOC_FORCE); |
| 2557 | + btrfs_end_transaction(trans); |
| 2558 | + if (ret == 1) { |
| 2559 | + did_chunk_alloc = true; |
| 2560 | + bg_list = &space_info->block_groups[index]; |
| 2561 | + goto again; |
| 2562 | + } |
| 2563 | +} |
| 2564 | + |
2504 | 2565 | void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info)
|
2505 | 2566 | {
|
2506 | 2567 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
|
|
0 commit comments