18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2008 Red Hat. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 78c2ecf20Sopenharmony_ci#include <linux/sched.h> 88c2ecf20Sopenharmony_ci#include <linux/sched/signal.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include <linux/math64.h> 118c2ecf20Sopenharmony_ci#include <linux/ratelimit.h> 128c2ecf20Sopenharmony_ci#include <linux/error-injection.h> 138c2ecf20Sopenharmony_ci#include <linux/sched/mm.h> 148c2ecf20Sopenharmony_ci#include "ctree.h" 158c2ecf20Sopenharmony_ci#include "free-space-cache.h" 168c2ecf20Sopenharmony_ci#include "transaction.h" 178c2ecf20Sopenharmony_ci#include "disk-io.h" 188c2ecf20Sopenharmony_ci#include "extent_io.h" 198c2ecf20Sopenharmony_ci#include "inode-map.h" 208c2ecf20Sopenharmony_ci#include "volumes.h" 218c2ecf20Sopenharmony_ci#include "space-info.h" 228c2ecf20Sopenharmony_ci#include "delalloc-space.h" 238c2ecf20Sopenharmony_ci#include "block-group.h" 248c2ecf20Sopenharmony_ci#include "discard.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define BITS_PER_BITMAP (PAGE_SIZE * 8UL) 278c2ecf20Sopenharmony_ci#define MAX_CACHE_BYTES_PER_GIG SZ_64K 288c2ecf20Sopenharmony_ci#define FORCE_EXTENT_THRESHOLD SZ_1M 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistruct btrfs_trim_range { 318c2ecf20Sopenharmony_ci u64 start; 328c2ecf20Sopenharmony_ci u64 bytes; 338c2ecf20Sopenharmony_ci struct list_head list; 348c2ecf20Sopenharmony_ci}; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic int count_bitmap_extents(struct btrfs_free_space_ctl *ctl, 378c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info); 388c2ecf20Sopenharmony_cistatic int link_free_space(struct btrfs_free_space_ctl *ctl, 398c2ecf20Sopenharmony_ci struct btrfs_free_space *info); 408c2ecf20Sopenharmony_cistatic void unlink_free_space(struct btrfs_free_space_ctl *ctl, 418c2ecf20Sopenharmony_ci struct btrfs_free_space *info); 428c2ecf20Sopenharmony_cistatic int btrfs_wait_cache_io_root(struct btrfs_root *root, 438c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 448c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 458c2ecf20Sopenharmony_ci struct btrfs_path *path); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic struct inode *__lookup_free_space_inode(struct btrfs_root *root, 488c2ecf20Sopenharmony_ci struct btrfs_path *path, 498c2ecf20Sopenharmony_ci u64 offset) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 528c2ecf20Sopenharmony_ci struct btrfs_key key; 538c2ecf20Sopenharmony_ci struct btrfs_key location; 548c2ecf20Sopenharmony_ci struct btrfs_disk_key disk_key; 558c2ecf20Sopenharmony_ci struct btrfs_free_space_header *header; 568c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 578c2ecf20Sopenharmony_ci struct inode *inode = NULL; 588c2ecf20Sopenharmony_ci unsigned nofs_flag; 598c2ecf20Sopenharmony_ci int ret; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci key.objectid = BTRFS_FREE_SPACE_OBJECTID; 628c2ecf20Sopenharmony_ci key.offset = offset; 638c2ecf20Sopenharmony_ci key.type = 0; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 668c2ecf20Sopenharmony_ci if (ret < 0) 678c2ecf20Sopenharmony_ci return ERR_PTR(ret); 688c2ecf20Sopenharmony_ci if (ret > 0) { 698c2ecf20Sopenharmony_ci btrfs_release_path(path); 708c2ecf20Sopenharmony_ci return ERR_PTR(-ENOENT); 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 748c2ecf20Sopenharmony_ci header = btrfs_item_ptr(leaf, path->slots[0], 758c2ecf20Sopenharmony_ci struct btrfs_free_space_header); 768c2ecf20Sopenharmony_ci btrfs_free_space_key(leaf, header, &disk_key); 778c2ecf20Sopenharmony_ci btrfs_disk_key_to_cpu(&location, &disk_key); 788c2ecf20Sopenharmony_ci btrfs_release_path(path); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci /* 818c2ecf20Sopenharmony_ci * We are often under a trans handle at this point, so we need to make 828c2ecf20Sopenharmony_ci * sure NOFS is set to keep us from deadlocking. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci nofs_flag = memalloc_nofs_save(); 858c2ecf20Sopenharmony_ci inode = btrfs_iget_path(fs_info->sb, location.objectid, root, path); 868c2ecf20Sopenharmony_ci btrfs_release_path(path); 878c2ecf20Sopenharmony_ci memalloc_nofs_restore(nofs_flag); 888c2ecf20Sopenharmony_ci if (IS_ERR(inode)) 898c2ecf20Sopenharmony_ci return inode; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci mapping_set_gfp_mask(inode->i_mapping, 928c2ecf20Sopenharmony_ci mapping_gfp_constraint(inode->i_mapping, 938c2ecf20Sopenharmony_ci ~(__GFP_FS | __GFP_HIGHMEM))); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci return inode; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistruct inode *lookup_free_space_inode(struct btrfs_block_group *block_group, 998c2ecf20Sopenharmony_ci struct btrfs_path *path) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 1028c2ecf20Sopenharmony_ci struct inode *inode = NULL; 1038c2ecf20Sopenharmony_ci u32 flags = BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 1068c2ecf20Sopenharmony_ci if (block_group->inode) 1078c2ecf20Sopenharmony_ci inode = igrab(block_group->inode); 1088c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 1098c2ecf20Sopenharmony_ci if (inode) 1108c2ecf20Sopenharmony_ci return inode; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci inode = __lookup_free_space_inode(fs_info->tree_root, path, 1138c2ecf20Sopenharmony_ci block_group->start); 1148c2ecf20Sopenharmony_ci if (IS_ERR(inode)) 1158c2ecf20Sopenharmony_ci return inode; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 1188c2ecf20Sopenharmony_ci if (!((BTRFS_I(inode)->flags & flags) == flags)) { 1198c2ecf20Sopenharmony_ci btrfs_info(fs_info, "Old style space inode found, converting."); 1208c2ecf20Sopenharmony_ci BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM | 1218c2ecf20Sopenharmony_ci BTRFS_INODE_NODATACOW; 1228c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_CLEAR; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci if (!block_group->iref) { 1268c2ecf20Sopenharmony_ci block_group->inode = igrab(inode); 1278c2ecf20Sopenharmony_ci block_group->iref = 1; 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci return inode; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic int __create_free_space_inode(struct btrfs_root *root, 1358c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 1368c2ecf20Sopenharmony_ci struct btrfs_path *path, 1378c2ecf20Sopenharmony_ci u64 ino, u64 offset) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci struct btrfs_key key; 1408c2ecf20Sopenharmony_ci struct btrfs_disk_key disk_key; 1418c2ecf20Sopenharmony_ci struct btrfs_free_space_header *header; 1428c2ecf20Sopenharmony_ci struct btrfs_inode_item *inode_item; 1438c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 1448c2ecf20Sopenharmony_ci u64 flags = BTRFS_INODE_NOCOMPRESS | BTRFS_INODE_PREALLOC; 1458c2ecf20Sopenharmony_ci int ret; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci ret = btrfs_insert_empty_inode(trans, root, path, ino); 1488c2ecf20Sopenharmony_ci if (ret) 1498c2ecf20Sopenharmony_ci return ret; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci /* We inline crc's for the free disk space cache */ 1528c2ecf20Sopenharmony_ci if (ino != BTRFS_FREE_INO_OBJECTID) 1538c2ecf20Sopenharmony_ci flags |= BTRFS_INODE_NODATASUM | BTRFS_INODE_NODATACOW; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 1568c2ecf20Sopenharmony_ci inode_item = btrfs_item_ptr(leaf, path->slots[0], 1578c2ecf20Sopenharmony_ci struct btrfs_inode_item); 1588c2ecf20Sopenharmony_ci btrfs_item_key(leaf, &disk_key, path->slots[0]); 1598c2ecf20Sopenharmony_ci memzero_extent_buffer(leaf, (unsigned long)inode_item, 1608c2ecf20Sopenharmony_ci sizeof(*inode_item)); 1618c2ecf20Sopenharmony_ci btrfs_set_inode_generation(leaf, inode_item, trans->transid); 1628c2ecf20Sopenharmony_ci btrfs_set_inode_size(leaf, inode_item, 0); 1638c2ecf20Sopenharmony_ci btrfs_set_inode_nbytes(leaf, inode_item, 0); 1648c2ecf20Sopenharmony_ci btrfs_set_inode_uid(leaf, inode_item, 0); 1658c2ecf20Sopenharmony_ci btrfs_set_inode_gid(leaf, inode_item, 0); 1668c2ecf20Sopenharmony_ci btrfs_set_inode_mode(leaf, inode_item, S_IFREG | 0600); 1678c2ecf20Sopenharmony_ci btrfs_set_inode_flags(leaf, inode_item, flags); 1688c2ecf20Sopenharmony_ci btrfs_set_inode_nlink(leaf, inode_item, 1); 1698c2ecf20Sopenharmony_ci btrfs_set_inode_transid(leaf, inode_item, trans->transid); 1708c2ecf20Sopenharmony_ci btrfs_set_inode_block_group(leaf, inode_item, offset); 1718c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(leaf); 1728c2ecf20Sopenharmony_ci btrfs_release_path(path); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci key.objectid = BTRFS_FREE_SPACE_OBJECTID; 1758c2ecf20Sopenharmony_ci key.offset = offset; 1768c2ecf20Sopenharmony_ci key.type = 0; 1778c2ecf20Sopenharmony_ci ret = btrfs_insert_empty_item(trans, root, path, &key, 1788c2ecf20Sopenharmony_ci sizeof(struct btrfs_free_space_header)); 1798c2ecf20Sopenharmony_ci if (ret < 0) { 1808c2ecf20Sopenharmony_ci btrfs_release_path(path); 1818c2ecf20Sopenharmony_ci return ret; 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 1858c2ecf20Sopenharmony_ci header = btrfs_item_ptr(leaf, path->slots[0], 1868c2ecf20Sopenharmony_ci struct btrfs_free_space_header); 1878c2ecf20Sopenharmony_ci memzero_extent_buffer(leaf, (unsigned long)header, sizeof(*header)); 1888c2ecf20Sopenharmony_ci btrfs_set_free_space_key(leaf, header, &disk_key); 1898c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(leaf); 1908c2ecf20Sopenharmony_ci btrfs_release_path(path); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci return 0; 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ciint create_free_space_inode(struct btrfs_trans_handle *trans, 1968c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 1978c2ecf20Sopenharmony_ci struct btrfs_path *path) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci int ret; 2008c2ecf20Sopenharmony_ci u64 ino; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci ret = btrfs_find_free_objectid(trans->fs_info->tree_root, &ino); 2038c2ecf20Sopenharmony_ci if (ret < 0) 2048c2ecf20Sopenharmony_ci return ret; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci return __create_free_space_inode(trans->fs_info->tree_root, trans, path, 2078c2ecf20Sopenharmony_ci ino, block_group->start); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ciint btrfs_check_trunc_cache_free_space(struct btrfs_fs_info *fs_info, 2118c2ecf20Sopenharmony_ci struct btrfs_block_rsv *rsv) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci u64 needed_bytes; 2148c2ecf20Sopenharmony_ci int ret; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* 1 for slack space, 1 for updating the inode */ 2178c2ecf20Sopenharmony_ci needed_bytes = btrfs_calc_insert_metadata_size(fs_info, 1) + 2188c2ecf20Sopenharmony_ci btrfs_calc_metadata_size(fs_info, 1); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci spin_lock(&rsv->lock); 2218c2ecf20Sopenharmony_ci if (rsv->reserved < needed_bytes) 2228c2ecf20Sopenharmony_ci ret = -ENOSPC; 2238c2ecf20Sopenharmony_ci else 2248c2ecf20Sopenharmony_ci ret = 0; 2258c2ecf20Sopenharmony_ci spin_unlock(&rsv->lock); 2268c2ecf20Sopenharmony_ci return ret; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciint btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans, 2308c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 2318c2ecf20Sopenharmony_ci struct inode *inode) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci struct btrfs_root *root = BTRFS_I(inode)->root; 2348c2ecf20Sopenharmony_ci int ret = 0; 2358c2ecf20Sopenharmony_ci bool locked = false; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci if (block_group) { 2388c2ecf20Sopenharmony_ci struct btrfs_path *path = btrfs_alloc_path(); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (!path) { 2418c2ecf20Sopenharmony_ci ret = -ENOMEM; 2428c2ecf20Sopenharmony_ci goto fail; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci locked = true; 2458c2ecf20Sopenharmony_ci mutex_lock(&trans->transaction->cache_write_mutex); 2468c2ecf20Sopenharmony_ci if (!list_empty(&block_group->io_list)) { 2478c2ecf20Sopenharmony_ci list_del_init(&block_group->io_list); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci btrfs_wait_cache_io(trans, block_group, path); 2508c2ecf20Sopenharmony_ci btrfs_put_block_group(block_group); 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci /* 2548c2ecf20Sopenharmony_ci * now that we've truncated the cache away, its no longer 2558c2ecf20Sopenharmony_ci * setup or written 2568c2ecf20Sopenharmony_ci */ 2578c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 2588c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_CLEAR; 2598c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 2608c2ecf20Sopenharmony_ci btrfs_free_path(path); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci btrfs_i_size_write(BTRFS_I(inode), 0); 2648c2ecf20Sopenharmony_ci truncate_pagecache(inode, 0); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci /* 2678c2ecf20Sopenharmony_ci * We skip the throttling logic for free space cache inodes, so we don't 2688c2ecf20Sopenharmony_ci * need to check for -EAGAIN. 2698c2ecf20Sopenharmony_ci */ 2708c2ecf20Sopenharmony_ci ret = btrfs_truncate_inode_items(trans, root, inode, 2718c2ecf20Sopenharmony_ci 0, BTRFS_EXTENT_DATA_KEY); 2728c2ecf20Sopenharmony_ci if (ret) 2738c2ecf20Sopenharmony_ci goto fail; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci ret = btrfs_update_inode(trans, root, inode); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cifail: 2788c2ecf20Sopenharmony_ci if (locked) 2798c2ecf20Sopenharmony_ci mutex_unlock(&trans->transaction->cache_write_mutex); 2808c2ecf20Sopenharmony_ci if (ret) 2818c2ecf20Sopenharmony_ci btrfs_abort_transaction(trans, ret); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci return ret; 2848c2ecf20Sopenharmony_ci} 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistatic void readahead_cache(struct inode *inode) 2878c2ecf20Sopenharmony_ci{ 2888c2ecf20Sopenharmony_ci struct file_ra_state *ra; 2898c2ecf20Sopenharmony_ci unsigned long last_index; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci ra = kzalloc(sizeof(*ra), GFP_NOFS); 2928c2ecf20Sopenharmony_ci if (!ra) 2938c2ecf20Sopenharmony_ci return; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci file_ra_state_init(ra, inode->i_mapping); 2968c2ecf20Sopenharmony_ci last_index = (i_size_read(inode) - 1) >> PAGE_SHIFT; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci page_cache_sync_readahead(inode->i_mapping, ra, NULL, 0, last_index); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci kfree(ra); 3018c2ecf20Sopenharmony_ci} 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, 3048c2ecf20Sopenharmony_ci int write) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci int num_pages; 3078c2ecf20Sopenharmony_ci int check_crcs = 0; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (btrfs_ino(BTRFS_I(inode)) != BTRFS_FREE_INO_OBJECTID) 3128c2ecf20Sopenharmony_ci check_crcs = 1; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci /* Make sure we can fit our crcs and generation into the first page */ 3158c2ecf20Sopenharmony_ci if (write && check_crcs && 3168c2ecf20Sopenharmony_ci (num_pages * sizeof(u32) + sizeof(u64)) > PAGE_SIZE) 3178c2ecf20Sopenharmony_ci return -ENOSPC; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci memset(io_ctl, 0, sizeof(struct btrfs_io_ctl)); 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS); 3228c2ecf20Sopenharmony_ci if (!io_ctl->pages) 3238c2ecf20Sopenharmony_ci return -ENOMEM; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci io_ctl->num_pages = num_pages; 3268c2ecf20Sopenharmony_ci io_ctl->fs_info = btrfs_sb(inode->i_sb); 3278c2ecf20Sopenharmony_ci io_ctl->check_crcs = check_crcs; 3288c2ecf20Sopenharmony_ci io_ctl->inode = inode; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci return 0; 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ciALLOW_ERROR_INJECTION(io_ctl_init, ERRNO); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic void io_ctl_free(struct btrfs_io_ctl *io_ctl) 3358c2ecf20Sopenharmony_ci{ 3368c2ecf20Sopenharmony_ci kfree(io_ctl->pages); 3378c2ecf20Sopenharmony_ci io_ctl->pages = NULL; 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic void io_ctl_unmap_page(struct btrfs_io_ctl *io_ctl) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci if (io_ctl->cur) { 3438c2ecf20Sopenharmony_ci io_ctl->cur = NULL; 3448c2ecf20Sopenharmony_ci io_ctl->orig = NULL; 3458c2ecf20Sopenharmony_ci } 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic void io_ctl_map_page(struct btrfs_io_ctl *io_ctl, int clear) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci ASSERT(io_ctl->index < io_ctl->num_pages); 3518c2ecf20Sopenharmony_ci io_ctl->page = io_ctl->pages[io_ctl->index++]; 3528c2ecf20Sopenharmony_ci io_ctl->cur = page_address(io_ctl->page); 3538c2ecf20Sopenharmony_ci io_ctl->orig = io_ctl->cur; 3548c2ecf20Sopenharmony_ci io_ctl->size = PAGE_SIZE; 3558c2ecf20Sopenharmony_ci if (clear) 3568c2ecf20Sopenharmony_ci clear_page(io_ctl->cur); 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic void io_ctl_drop_pages(struct btrfs_io_ctl *io_ctl) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci int i; 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci for (i = 0; i < io_ctl->num_pages; i++) { 3668c2ecf20Sopenharmony_ci if (io_ctl->pages[i]) { 3678c2ecf20Sopenharmony_ci ClearPageChecked(io_ctl->pages[i]); 3688c2ecf20Sopenharmony_ci unlock_page(io_ctl->pages[i]); 3698c2ecf20Sopenharmony_ci put_page(io_ctl->pages[i]); 3708c2ecf20Sopenharmony_ci } 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci} 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_cistatic int io_ctl_prepare_pages(struct btrfs_io_ctl *io_ctl, bool uptodate) 3758c2ecf20Sopenharmony_ci{ 3768c2ecf20Sopenharmony_ci struct page *page; 3778c2ecf20Sopenharmony_ci struct inode *inode = io_ctl->inode; 3788c2ecf20Sopenharmony_ci gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); 3798c2ecf20Sopenharmony_ci int i; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci for (i = 0; i < io_ctl->num_pages; i++) { 3828c2ecf20Sopenharmony_ci page = find_or_create_page(inode->i_mapping, i, mask); 3838c2ecf20Sopenharmony_ci if (!page) { 3848c2ecf20Sopenharmony_ci io_ctl_drop_pages(io_ctl); 3858c2ecf20Sopenharmony_ci return -ENOMEM; 3868c2ecf20Sopenharmony_ci } 3878c2ecf20Sopenharmony_ci io_ctl->pages[i] = page; 3888c2ecf20Sopenharmony_ci if (uptodate && !PageUptodate(page)) { 3898c2ecf20Sopenharmony_ci btrfs_readpage(NULL, page); 3908c2ecf20Sopenharmony_ci lock_page(page); 3918c2ecf20Sopenharmony_ci if (page->mapping != inode->i_mapping) { 3928c2ecf20Sopenharmony_ci btrfs_err(BTRFS_I(inode)->root->fs_info, 3938c2ecf20Sopenharmony_ci "free space cache page truncated"); 3948c2ecf20Sopenharmony_ci io_ctl_drop_pages(io_ctl); 3958c2ecf20Sopenharmony_ci return -EIO; 3968c2ecf20Sopenharmony_ci } 3978c2ecf20Sopenharmony_ci if (!PageUptodate(page)) { 3988c2ecf20Sopenharmony_ci btrfs_err(BTRFS_I(inode)->root->fs_info, 3998c2ecf20Sopenharmony_ci "error reading free space cache"); 4008c2ecf20Sopenharmony_ci io_ctl_drop_pages(io_ctl); 4018c2ecf20Sopenharmony_ci return -EIO; 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci } 4048c2ecf20Sopenharmony_ci } 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci for (i = 0; i < io_ctl->num_pages; i++) { 4078c2ecf20Sopenharmony_ci clear_page_dirty_for_io(io_ctl->pages[i]); 4088c2ecf20Sopenharmony_ci set_page_extent_mapped(io_ctl->pages[i]); 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci return 0; 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_cistatic void io_ctl_set_generation(struct btrfs_io_ctl *io_ctl, u64 generation) 4158c2ecf20Sopenharmony_ci{ 4168c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 1); 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci /* 4198c2ecf20Sopenharmony_ci * Skip the csum areas. If we don't check crcs then we just have a 4208c2ecf20Sopenharmony_ci * 64bit chunk at the front of the first page. 4218c2ecf20Sopenharmony_ci */ 4228c2ecf20Sopenharmony_ci if (io_ctl->check_crcs) { 4238c2ecf20Sopenharmony_ci io_ctl->cur += (sizeof(u32) * io_ctl->num_pages); 4248c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(u64) + (sizeof(u32) * io_ctl->num_pages); 4258c2ecf20Sopenharmony_ci } else { 4268c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(u64); 4278c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(u64) * 2; 4288c2ecf20Sopenharmony_ci } 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci put_unaligned_le64(generation, io_ctl->cur); 4318c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(u64); 4328c2ecf20Sopenharmony_ci} 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_cistatic int io_ctl_check_generation(struct btrfs_io_ctl *io_ctl, u64 generation) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci u64 cache_gen; 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci /* 4398c2ecf20Sopenharmony_ci * Skip the crc area. If we don't check crcs then we just have a 64bit 4408c2ecf20Sopenharmony_ci * chunk at the front of the first page. 4418c2ecf20Sopenharmony_ci */ 4428c2ecf20Sopenharmony_ci if (io_ctl->check_crcs) { 4438c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(u32) * io_ctl->num_pages; 4448c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(u64) + 4458c2ecf20Sopenharmony_ci (sizeof(u32) * io_ctl->num_pages); 4468c2ecf20Sopenharmony_ci } else { 4478c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(u64); 4488c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(u64) * 2; 4498c2ecf20Sopenharmony_ci } 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci cache_gen = get_unaligned_le64(io_ctl->cur); 4528c2ecf20Sopenharmony_ci if (cache_gen != generation) { 4538c2ecf20Sopenharmony_ci btrfs_err_rl(io_ctl->fs_info, 4548c2ecf20Sopenharmony_ci "space cache generation (%llu) does not match inode (%llu)", 4558c2ecf20Sopenharmony_ci cache_gen, generation); 4568c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 4578c2ecf20Sopenharmony_ci return -EIO; 4588c2ecf20Sopenharmony_ci } 4598c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(u64); 4608c2ecf20Sopenharmony_ci return 0; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic void io_ctl_set_crc(struct btrfs_io_ctl *io_ctl, int index) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci u32 *tmp; 4668c2ecf20Sopenharmony_ci u32 crc = ~(u32)0; 4678c2ecf20Sopenharmony_ci unsigned offset = 0; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci if (!io_ctl->check_crcs) { 4708c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 4718c2ecf20Sopenharmony_ci return; 4728c2ecf20Sopenharmony_ci } 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci if (index == 0) 4758c2ecf20Sopenharmony_ci offset = sizeof(u32) * io_ctl->num_pages; 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci crc = btrfs_crc32c(crc, io_ctl->orig + offset, PAGE_SIZE - offset); 4788c2ecf20Sopenharmony_ci btrfs_crc32c_final(crc, (u8 *)&crc); 4798c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 4808c2ecf20Sopenharmony_ci tmp = page_address(io_ctl->pages[0]); 4818c2ecf20Sopenharmony_ci tmp += index; 4828c2ecf20Sopenharmony_ci *tmp = crc; 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic int io_ctl_check_crc(struct btrfs_io_ctl *io_ctl, int index) 4868c2ecf20Sopenharmony_ci{ 4878c2ecf20Sopenharmony_ci u32 *tmp, val; 4888c2ecf20Sopenharmony_ci u32 crc = ~(u32)0; 4898c2ecf20Sopenharmony_ci unsigned offset = 0; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci if (!io_ctl->check_crcs) { 4928c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 0); 4938c2ecf20Sopenharmony_ci return 0; 4948c2ecf20Sopenharmony_ci } 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci if (index == 0) 4978c2ecf20Sopenharmony_ci offset = sizeof(u32) * io_ctl->num_pages; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci tmp = page_address(io_ctl->pages[0]); 5008c2ecf20Sopenharmony_ci tmp += index; 5018c2ecf20Sopenharmony_ci val = *tmp; 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 0); 5048c2ecf20Sopenharmony_ci crc = btrfs_crc32c(crc, io_ctl->orig + offset, PAGE_SIZE - offset); 5058c2ecf20Sopenharmony_ci btrfs_crc32c_final(crc, (u8 *)&crc); 5068c2ecf20Sopenharmony_ci if (val != crc) { 5078c2ecf20Sopenharmony_ci btrfs_err_rl(io_ctl->fs_info, 5088c2ecf20Sopenharmony_ci "csum mismatch on free space cache"); 5098c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 5108c2ecf20Sopenharmony_ci return -EIO; 5118c2ecf20Sopenharmony_ci } 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci return 0; 5148c2ecf20Sopenharmony_ci} 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_cistatic int io_ctl_add_entry(struct btrfs_io_ctl *io_ctl, u64 offset, u64 bytes, 5178c2ecf20Sopenharmony_ci void *bitmap) 5188c2ecf20Sopenharmony_ci{ 5198c2ecf20Sopenharmony_ci struct btrfs_free_space_entry *entry; 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci if (!io_ctl->cur) 5228c2ecf20Sopenharmony_ci return -ENOSPC; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci entry = io_ctl->cur; 5258c2ecf20Sopenharmony_ci put_unaligned_le64(offset, &entry->offset); 5268c2ecf20Sopenharmony_ci put_unaligned_le64(bytes, &entry->bytes); 5278c2ecf20Sopenharmony_ci entry->type = (bitmap) ? BTRFS_FREE_SPACE_BITMAP : 5288c2ecf20Sopenharmony_ci BTRFS_FREE_SPACE_EXTENT; 5298c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(struct btrfs_free_space_entry); 5308c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(struct btrfs_free_space_entry); 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci if (io_ctl->size >= sizeof(struct btrfs_free_space_entry)) 5338c2ecf20Sopenharmony_ci return 0; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci io_ctl_set_crc(io_ctl, io_ctl->index - 1); 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci /* No more pages to map */ 5388c2ecf20Sopenharmony_ci if (io_ctl->index >= io_ctl->num_pages) 5398c2ecf20Sopenharmony_ci return 0; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci /* map the next page */ 5428c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 1); 5438c2ecf20Sopenharmony_ci return 0; 5448c2ecf20Sopenharmony_ci} 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_cistatic int io_ctl_add_bitmap(struct btrfs_io_ctl *io_ctl, void *bitmap) 5478c2ecf20Sopenharmony_ci{ 5488c2ecf20Sopenharmony_ci if (!io_ctl->cur) 5498c2ecf20Sopenharmony_ci return -ENOSPC; 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci /* 5528c2ecf20Sopenharmony_ci * If we aren't at the start of the current page, unmap this one and 5538c2ecf20Sopenharmony_ci * map the next one if there is any left. 5548c2ecf20Sopenharmony_ci */ 5558c2ecf20Sopenharmony_ci if (io_ctl->cur != io_ctl->orig) { 5568c2ecf20Sopenharmony_ci io_ctl_set_crc(io_ctl, io_ctl->index - 1); 5578c2ecf20Sopenharmony_ci if (io_ctl->index >= io_ctl->num_pages) 5588c2ecf20Sopenharmony_ci return -ENOSPC; 5598c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 0); 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci copy_page(io_ctl->cur, bitmap); 5638c2ecf20Sopenharmony_ci io_ctl_set_crc(io_ctl, io_ctl->index - 1); 5648c2ecf20Sopenharmony_ci if (io_ctl->index < io_ctl->num_pages) 5658c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 0); 5668c2ecf20Sopenharmony_ci return 0; 5678c2ecf20Sopenharmony_ci} 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_cistatic void io_ctl_zero_remaining_pages(struct btrfs_io_ctl *io_ctl) 5708c2ecf20Sopenharmony_ci{ 5718c2ecf20Sopenharmony_ci /* 5728c2ecf20Sopenharmony_ci * If we're not on the boundary we know we've modified the page and we 5738c2ecf20Sopenharmony_ci * need to crc the page. 5748c2ecf20Sopenharmony_ci */ 5758c2ecf20Sopenharmony_ci if (io_ctl->cur != io_ctl->orig) 5768c2ecf20Sopenharmony_ci io_ctl_set_crc(io_ctl, io_ctl->index - 1); 5778c2ecf20Sopenharmony_ci else 5788c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci while (io_ctl->index < io_ctl->num_pages) { 5818c2ecf20Sopenharmony_ci io_ctl_map_page(io_ctl, 1); 5828c2ecf20Sopenharmony_ci io_ctl_set_crc(io_ctl, io_ctl->index - 1); 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci} 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_cistatic int io_ctl_read_entry(struct btrfs_io_ctl *io_ctl, 5878c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, u8 *type) 5888c2ecf20Sopenharmony_ci{ 5898c2ecf20Sopenharmony_ci struct btrfs_free_space_entry *e; 5908c2ecf20Sopenharmony_ci int ret; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci if (!io_ctl->cur) { 5938c2ecf20Sopenharmony_ci ret = io_ctl_check_crc(io_ctl, io_ctl->index); 5948c2ecf20Sopenharmony_ci if (ret) 5958c2ecf20Sopenharmony_ci return ret; 5968c2ecf20Sopenharmony_ci } 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci e = io_ctl->cur; 5998c2ecf20Sopenharmony_ci entry->offset = get_unaligned_le64(&e->offset); 6008c2ecf20Sopenharmony_ci entry->bytes = get_unaligned_le64(&e->bytes); 6018c2ecf20Sopenharmony_ci *type = e->type; 6028c2ecf20Sopenharmony_ci io_ctl->cur += sizeof(struct btrfs_free_space_entry); 6038c2ecf20Sopenharmony_ci io_ctl->size -= sizeof(struct btrfs_free_space_entry); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (io_ctl->size >= sizeof(struct btrfs_free_space_entry)) 6068c2ecf20Sopenharmony_ci return 0; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ci return 0; 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic int io_ctl_read_bitmap(struct btrfs_io_ctl *io_ctl, 6148c2ecf20Sopenharmony_ci struct btrfs_free_space *entry) 6158c2ecf20Sopenharmony_ci{ 6168c2ecf20Sopenharmony_ci int ret; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci ret = io_ctl_check_crc(io_ctl, io_ctl->index); 6198c2ecf20Sopenharmony_ci if (ret) 6208c2ecf20Sopenharmony_ci return ret; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci copy_page(entry->bitmap, io_ctl->cur); 6238c2ecf20Sopenharmony_ci io_ctl_unmap_page(io_ctl); 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci return 0; 6268c2ecf20Sopenharmony_ci} 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci/* 6298c2ecf20Sopenharmony_ci * Since we attach pinned extents after the fact we can have contiguous sections 6308c2ecf20Sopenharmony_ci * of free space that are split up in entries. This poses a problem with the 6318c2ecf20Sopenharmony_ci * tree logging stuff since it could have allocated across what appears to be 2 6328c2ecf20Sopenharmony_ci * entries since we would have merged the entries when adding the pinned extents 6338c2ecf20Sopenharmony_ci * back to the free space cache. So run through the space cache that we just 6348c2ecf20Sopenharmony_ci * loaded and merge contiguous entries. This will make the log replay stuff not 6358c2ecf20Sopenharmony_ci * blow up and it will make for nicer allocator behavior. 6368c2ecf20Sopenharmony_ci */ 6378c2ecf20Sopenharmony_cistatic void merge_space_tree(struct btrfs_free_space_ctl *ctl) 6388c2ecf20Sopenharmony_ci{ 6398c2ecf20Sopenharmony_ci struct btrfs_free_space *e, *prev = NULL; 6408c2ecf20Sopenharmony_ci struct rb_node *n; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ciagain: 6438c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 6448c2ecf20Sopenharmony_ci for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) { 6458c2ecf20Sopenharmony_ci e = rb_entry(n, struct btrfs_free_space, offset_index); 6468c2ecf20Sopenharmony_ci if (!prev) 6478c2ecf20Sopenharmony_ci goto next; 6488c2ecf20Sopenharmony_ci if (e->bitmap || prev->bitmap) 6498c2ecf20Sopenharmony_ci goto next; 6508c2ecf20Sopenharmony_ci if (prev->offset + prev->bytes == e->offset) { 6518c2ecf20Sopenharmony_ci unlink_free_space(ctl, prev); 6528c2ecf20Sopenharmony_ci unlink_free_space(ctl, e); 6538c2ecf20Sopenharmony_ci prev->bytes += e->bytes; 6548c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, e); 6558c2ecf20Sopenharmony_ci link_free_space(ctl, prev); 6568c2ecf20Sopenharmony_ci prev = NULL; 6578c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 6588c2ecf20Sopenharmony_ci goto again; 6598c2ecf20Sopenharmony_ci } 6608c2ecf20Sopenharmony_cinext: 6618c2ecf20Sopenharmony_ci prev = e; 6628c2ecf20Sopenharmony_ci } 6638c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 6648c2ecf20Sopenharmony_ci} 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_cistatic int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, 6678c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl, 6688c2ecf20Sopenharmony_ci struct btrfs_path *path, u64 offset) 6698c2ecf20Sopenharmony_ci{ 6708c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 6718c2ecf20Sopenharmony_ci struct btrfs_free_space_header *header; 6728c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 6738c2ecf20Sopenharmony_ci struct btrfs_io_ctl io_ctl; 6748c2ecf20Sopenharmony_ci struct btrfs_key key; 6758c2ecf20Sopenharmony_ci struct btrfs_free_space *e, *n; 6768c2ecf20Sopenharmony_ci LIST_HEAD(bitmaps); 6778c2ecf20Sopenharmony_ci u64 num_entries; 6788c2ecf20Sopenharmony_ci u64 num_bitmaps; 6798c2ecf20Sopenharmony_ci u64 generation; 6808c2ecf20Sopenharmony_ci u8 type; 6818c2ecf20Sopenharmony_ci int ret = 0; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci /* Nothing in the space cache, goodbye */ 6848c2ecf20Sopenharmony_ci if (!i_size_read(inode)) 6858c2ecf20Sopenharmony_ci return 0; 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_ci key.objectid = BTRFS_FREE_SPACE_OBJECTID; 6888c2ecf20Sopenharmony_ci key.offset = offset; 6898c2ecf20Sopenharmony_ci key.type = 0; 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 6928c2ecf20Sopenharmony_ci if (ret < 0) 6938c2ecf20Sopenharmony_ci return 0; 6948c2ecf20Sopenharmony_ci else if (ret > 0) { 6958c2ecf20Sopenharmony_ci btrfs_release_path(path); 6968c2ecf20Sopenharmony_ci return 0; 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci ret = -1; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 7028c2ecf20Sopenharmony_ci header = btrfs_item_ptr(leaf, path->slots[0], 7038c2ecf20Sopenharmony_ci struct btrfs_free_space_header); 7048c2ecf20Sopenharmony_ci num_entries = btrfs_free_space_entries(leaf, header); 7058c2ecf20Sopenharmony_ci num_bitmaps = btrfs_free_space_bitmaps(leaf, header); 7068c2ecf20Sopenharmony_ci generation = btrfs_free_space_generation(leaf, header); 7078c2ecf20Sopenharmony_ci btrfs_release_path(path); 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci if (!BTRFS_I(inode)->generation) { 7108c2ecf20Sopenharmony_ci btrfs_info(fs_info, 7118c2ecf20Sopenharmony_ci "the free space cache file (%llu) is invalid, skip it", 7128c2ecf20Sopenharmony_ci offset); 7138c2ecf20Sopenharmony_ci return 0; 7148c2ecf20Sopenharmony_ci } 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci if (BTRFS_I(inode)->generation != generation) { 7178c2ecf20Sopenharmony_ci btrfs_err(fs_info, 7188c2ecf20Sopenharmony_ci "free space inode generation (%llu) did not match free space cache generation (%llu)", 7198c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation, generation); 7208c2ecf20Sopenharmony_ci return 0; 7218c2ecf20Sopenharmony_ci } 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (!num_entries) 7248c2ecf20Sopenharmony_ci return 0; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci ret = io_ctl_init(&io_ctl, inode, 0); 7278c2ecf20Sopenharmony_ci if (ret) 7288c2ecf20Sopenharmony_ci return ret; 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci readahead_cache(inode); 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci ret = io_ctl_prepare_pages(&io_ctl, true); 7338c2ecf20Sopenharmony_ci if (ret) 7348c2ecf20Sopenharmony_ci goto out; 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci ret = io_ctl_check_crc(&io_ctl, 0); 7378c2ecf20Sopenharmony_ci if (ret) 7388c2ecf20Sopenharmony_ci goto free_cache; 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci ret = io_ctl_check_generation(&io_ctl, generation); 7418c2ecf20Sopenharmony_ci if (ret) 7428c2ecf20Sopenharmony_ci goto free_cache; 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci while (num_entries) { 7458c2ecf20Sopenharmony_ci e = kmem_cache_zalloc(btrfs_free_space_cachep, 7468c2ecf20Sopenharmony_ci GFP_NOFS); 7478c2ecf20Sopenharmony_ci if (!e) { 7488c2ecf20Sopenharmony_ci ret = -ENOMEM; 7498c2ecf20Sopenharmony_ci goto free_cache; 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci ret = io_ctl_read_entry(&io_ctl, e, &type); 7538c2ecf20Sopenharmony_ci if (ret) { 7548c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, e); 7558c2ecf20Sopenharmony_ci goto free_cache; 7568c2ecf20Sopenharmony_ci } 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci /* 7598c2ecf20Sopenharmony_ci * Sync discard ensures that the free space cache is always 7608c2ecf20Sopenharmony_ci * trimmed. So when reading this in, the state should reflect 7618c2ecf20Sopenharmony_ci * that. We also do this for async as a stop gap for lack of 7628c2ecf20Sopenharmony_ci * persistence. 7638c2ecf20Sopenharmony_ci */ 7648c2ecf20Sopenharmony_ci if (btrfs_test_opt(fs_info, DISCARD_SYNC) || 7658c2ecf20Sopenharmony_ci btrfs_test_opt(fs_info, DISCARD_ASYNC)) 7668c2ecf20Sopenharmony_ci e->trim_state = BTRFS_TRIM_STATE_TRIMMED; 7678c2ecf20Sopenharmony_ci 7688c2ecf20Sopenharmony_ci if (!e->bytes) { 7698c2ecf20Sopenharmony_ci ret = -1; 7708c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, e); 7718c2ecf20Sopenharmony_ci goto free_cache; 7728c2ecf20Sopenharmony_ci } 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_ci if (type == BTRFS_FREE_SPACE_EXTENT) { 7758c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 7768c2ecf20Sopenharmony_ci ret = link_free_space(ctl, e); 7778c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 7788c2ecf20Sopenharmony_ci if (ret) { 7798c2ecf20Sopenharmony_ci btrfs_err(fs_info, 7808c2ecf20Sopenharmony_ci "Duplicate entries in free space cache, dumping"); 7818c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, e); 7828c2ecf20Sopenharmony_ci goto free_cache; 7838c2ecf20Sopenharmony_ci } 7848c2ecf20Sopenharmony_ci } else { 7858c2ecf20Sopenharmony_ci ASSERT(num_bitmaps); 7868c2ecf20Sopenharmony_ci num_bitmaps--; 7878c2ecf20Sopenharmony_ci e->bitmap = kmem_cache_zalloc( 7888c2ecf20Sopenharmony_ci btrfs_free_space_bitmap_cachep, GFP_NOFS); 7898c2ecf20Sopenharmony_ci if (!e->bitmap) { 7908c2ecf20Sopenharmony_ci ret = -ENOMEM; 7918c2ecf20Sopenharmony_ci kmem_cache_free( 7928c2ecf20Sopenharmony_ci btrfs_free_space_cachep, e); 7938c2ecf20Sopenharmony_ci goto free_cache; 7948c2ecf20Sopenharmony_ci } 7958c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 7968c2ecf20Sopenharmony_ci ret = link_free_space(ctl, e); 7978c2ecf20Sopenharmony_ci if (ret) { 7988c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 7998c2ecf20Sopenharmony_ci btrfs_err(fs_info, 8008c2ecf20Sopenharmony_ci "Duplicate entries in free space cache, dumping"); 8018c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, e); 8028c2ecf20Sopenharmony_ci goto free_cache; 8038c2ecf20Sopenharmony_ci } 8048c2ecf20Sopenharmony_ci ctl->total_bitmaps++; 8058c2ecf20Sopenharmony_ci ctl->op->recalc_thresholds(ctl); 8068c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 8078c2ecf20Sopenharmony_ci list_add_tail(&e->list, &bitmaps); 8088c2ecf20Sopenharmony_ci } 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci num_entries--; 8118c2ecf20Sopenharmony_ci } 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci io_ctl_unmap_page(&io_ctl); 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci /* 8168c2ecf20Sopenharmony_ci * We add the bitmaps at the end of the entries in order that 8178c2ecf20Sopenharmony_ci * the bitmap entries are added to the cache. 8188c2ecf20Sopenharmony_ci */ 8198c2ecf20Sopenharmony_ci list_for_each_entry_safe(e, n, &bitmaps, list) { 8208c2ecf20Sopenharmony_ci list_del_init(&e->list); 8218c2ecf20Sopenharmony_ci ret = io_ctl_read_bitmap(&io_ctl, e); 8228c2ecf20Sopenharmony_ci if (ret) 8238c2ecf20Sopenharmony_ci goto free_cache; 8248c2ecf20Sopenharmony_ci e->bitmap_extents = count_bitmap_extents(ctl, e); 8258c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(e)) { 8268c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] += 8278c2ecf20Sopenharmony_ci e->bitmap_extents; 8288c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += e->bytes; 8298c2ecf20Sopenharmony_ci } 8308c2ecf20Sopenharmony_ci } 8318c2ecf20Sopenharmony_ci 8328c2ecf20Sopenharmony_ci io_ctl_drop_pages(&io_ctl); 8338c2ecf20Sopenharmony_ci merge_space_tree(ctl); 8348c2ecf20Sopenharmony_ci ret = 1; 8358c2ecf20Sopenharmony_ciout: 8368c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(ctl->private, ctl); 8378c2ecf20Sopenharmony_ci io_ctl_free(&io_ctl); 8388c2ecf20Sopenharmony_ci return ret; 8398c2ecf20Sopenharmony_cifree_cache: 8408c2ecf20Sopenharmony_ci io_ctl_drop_pages(&io_ctl); 8418c2ecf20Sopenharmony_ci __btrfs_remove_free_space_cache(ctl); 8428c2ecf20Sopenharmony_ci goto out; 8438c2ecf20Sopenharmony_ci} 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_ciint load_free_space_cache(struct btrfs_block_group *block_group) 8468c2ecf20Sopenharmony_ci{ 8478c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 8488c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 8498c2ecf20Sopenharmony_ci struct inode *inode; 8508c2ecf20Sopenharmony_ci struct btrfs_path *path; 8518c2ecf20Sopenharmony_ci int ret = 0; 8528c2ecf20Sopenharmony_ci bool matched; 8538c2ecf20Sopenharmony_ci u64 used = block_group->used; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci /* 8568c2ecf20Sopenharmony_ci * If this block group has been marked to be cleared for one reason or 8578c2ecf20Sopenharmony_ci * another then we can't trust the on disk cache, so just return. 8588c2ecf20Sopenharmony_ci */ 8598c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 8608c2ecf20Sopenharmony_ci if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) { 8618c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 8628c2ecf20Sopenharmony_ci return 0; 8638c2ecf20Sopenharmony_ci } 8648c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 8678c2ecf20Sopenharmony_ci if (!path) 8688c2ecf20Sopenharmony_ci return 0; 8698c2ecf20Sopenharmony_ci path->search_commit_root = 1; 8708c2ecf20Sopenharmony_ci path->skip_locking = 1; 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci /* 8738c2ecf20Sopenharmony_ci * We must pass a path with search_commit_root set to btrfs_iget in 8748c2ecf20Sopenharmony_ci * order to avoid a deadlock when allocating extents for the tree root. 8758c2ecf20Sopenharmony_ci * 8768c2ecf20Sopenharmony_ci * When we are COWing an extent buffer from the tree root, when looking 8778c2ecf20Sopenharmony_ci * for a free extent, at extent-tree.c:find_free_extent(), we can find 8788c2ecf20Sopenharmony_ci * block group without its free space cache loaded. When we find one 8798c2ecf20Sopenharmony_ci * we must load its space cache which requires reading its free space 8808c2ecf20Sopenharmony_ci * cache's inode item from the root tree. If this inode item is located 8818c2ecf20Sopenharmony_ci * in the same leaf that we started COWing before, then we end up in 8828c2ecf20Sopenharmony_ci * deadlock on the extent buffer (trying to read lock it when we 8838c2ecf20Sopenharmony_ci * previously write locked it). 8848c2ecf20Sopenharmony_ci * 8858c2ecf20Sopenharmony_ci * It's safe to read the inode item using the commit root because 8868c2ecf20Sopenharmony_ci * block groups, once loaded, stay in memory forever (until they are 8878c2ecf20Sopenharmony_ci * removed) as well as their space caches once loaded. New block groups 8888c2ecf20Sopenharmony_ci * once created get their ->cached field set to BTRFS_CACHE_FINISHED so 8898c2ecf20Sopenharmony_ci * we will never try to read their inode item while the fs is mounted. 8908c2ecf20Sopenharmony_ci */ 8918c2ecf20Sopenharmony_ci inode = lookup_free_space_inode(block_group, path); 8928c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 8938c2ecf20Sopenharmony_ci btrfs_free_path(path); 8948c2ecf20Sopenharmony_ci return 0; 8958c2ecf20Sopenharmony_ci } 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci /* We may have converted the inode and made the cache invalid. */ 8988c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 8998c2ecf20Sopenharmony_ci if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) { 9008c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 9018c2ecf20Sopenharmony_ci btrfs_free_path(path); 9028c2ecf20Sopenharmony_ci goto out; 9038c2ecf20Sopenharmony_ci } 9048c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci ret = __load_free_space_cache(fs_info->tree_root, inode, ctl, 9078c2ecf20Sopenharmony_ci path, block_group->start); 9088c2ecf20Sopenharmony_ci btrfs_free_path(path); 9098c2ecf20Sopenharmony_ci if (ret <= 0) 9108c2ecf20Sopenharmony_ci goto out; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 9138c2ecf20Sopenharmony_ci matched = (ctl->free_space == (block_group->length - used - 9148c2ecf20Sopenharmony_ci block_group->bytes_super)); 9158c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 9168c2ecf20Sopenharmony_ci 9178c2ecf20Sopenharmony_ci if (!matched) { 9188c2ecf20Sopenharmony_ci __btrfs_remove_free_space_cache(ctl); 9198c2ecf20Sopenharmony_ci btrfs_warn(fs_info, 9208c2ecf20Sopenharmony_ci "block group %llu has wrong amount of free space", 9218c2ecf20Sopenharmony_ci block_group->start); 9228c2ecf20Sopenharmony_ci ret = -1; 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ciout: 9258c2ecf20Sopenharmony_ci if (ret < 0) { 9268c2ecf20Sopenharmony_ci /* This cache is bogus, make sure it gets cleared */ 9278c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 9288c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_CLEAR; 9298c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 9308c2ecf20Sopenharmony_ci ret = 0; 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci btrfs_warn(fs_info, 9338c2ecf20Sopenharmony_ci "failed to load free space cache for block group %llu, rebuilding it now", 9348c2ecf20Sopenharmony_ci block_group->start); 9358c2ecf20Sopenharmony_ci } 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci iput(inode); 9388c2ecf20Sopenharmony_ci return ret; 9398c2ecf20Sopenharmony_ci} 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_cistatic noinline_for_stack 9428c2ecf20Sopenharmony_ciint write_cache_extent_entries(struct btrfs_io_ctl *io_ctl, 9438c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl, 9448c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 9458c2ecf20Sopenharmony_ci int *entries, int *bitmaps, 9468c2ecf20Sopenharmony_ci struct list_head *bitmap_list) 9478c2ecf20Sopenharmony_ci{ 9488c2ecf20Sopenharmony_ci int ret; 9498c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster = NULL; 9508c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster_locked = NULL; 9518c2ecf20Sopenharmony_ci struct rb_node *node = rb_first(&ctl->free_space_offset); 9528c2ecf20Sopenharmony_ci struct btrfs_trim_range *trim_entry; 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci /* Get the cluster for this block_group if it exists */ 9558c2ecf20Sopenharmony_ci if (block_group && !list_empty(&block_group->cluster_list)) { 9568c2ecf20Sopenharmony_ci cluster = list_entry(block_group->cluster_list.next, 9578c2ecf20Sopenharmony_ci struct btrfs_free_cluster, 9588c2ecf20Sopenharmony_ci block_group_list); 9598c2ecf20Sopenharmony_ci } 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci if (!node && cluster) { 9628c2ecf20Sopenharmony_ci cluster_locked = cluster; 9638c2ecf20Sopenharmony_ci spin_lock(&cluster_locked->lock); 9648c2ecf20Sopenharmony_ci node = rb_first(&cluster->root); 9658c2ecf20Sopenharmony_ci cluster = NULL; 9668c2ecf20Sopenharmony_ci } 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_ci /* Write out the extent entries */ 9698c2ecf20Sopenharmony_ci while (node) { 9708c2ecf20Sopenharmony_ci struct btrfs_free_space *e; 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci e = rb_entry(node, struct btrfs_free_space, offset_index); 9738c2ecf20Sopenharmony_ci *entries += 1; 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci ret = io_ctl_add_entry(io_ctl, e->offset, e->bytes, 9768c2ecf20Sopenharmony_ci e->bitmap); 9778c2ecf20Sopenharmony_ci if (ret) 9788c2ecf20Sopenharmony_ci goto fail; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci if (e->bitmap) { 9818c2ecf20Sopenharmony_ci list_add_tail(&e->list, bitmap_list); 9828c2ecf20Sopenharmony_ci *bitmaps += 1; 9838c2ecf20Sopenharmony_ci } 9848c2ecf20Sopenharmony_ci node = rb_next(node); 9858c2ecf20Sopenharmony_ci if (!node && cluster) { 9868c2ecf20Sopenharmony_ci node = rb_first(&cluster->root); 9878c2ecf20Sopenharmony_ci cluster_locked = cluster; 9888c2ecf20Sopenharmony_ci spin_lock(&cluster_locked->lock); 9898c2ecf20Sopenharmony_ci cluster = NULL; 9908c2ecf20Sopenharmony_ci } 9918c2ecf20Sopenharmony_ci } 9928c2ecf20Sopenharmony_ci if (cluster_locked) { 9938c2ecf20Sopenharmony_ci spin_unlock(&cluster_locked->lock); 9948c2ecf20Sopenharmony_ci cluster_locked = NULL; 9958c2ecf20Sopenharmony_ci } 9968c2ecf20Sopenharmony_ci 9978c2ecf20Sopenharmony_ci /* 9988c2ecf20Sopenharmony_ci * Make sure we don't miss any range that was removed from our rbtree 9998c2ecf20Sopenharmony_ci * because trimming is running. Otherwise after a umount+mount (or crash 10008c2ecf20Sopenharmony_ci * after committing the transaction) we would leak free space and get 10018c2ecf20Sopenharmony_ci * an inconsistent free space cache report from fsck. 10028c2ecf20Sopenharmony_ci */ 10038c2ecf20Sopenharmony_ci list_for_each_entry(trim_entry, &ctl->trimming_ranges, list) { 10048c2ecf20Sopenharmony_ci ret = io_ctl_add_entry(io_ctl, trim_entry->start, 10058c2ecf20Sopenharmony_ci trim_entry->bytes, NULL); 10068c2ecf20Sopenharmony_ci if (ret) 10078c2ecf20Sopenharmony_ci goto fail; 10088c2ecf20Sopenharmony_ci *entries += 1; 10098c2ecf20Sopenharmony_ci } 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci return 0; 10128c2ecf20Sopenharmony_cifail: 10138c2ecf20Sopenharmony_ci if (cluster_locked) 10148c2ecf20Sopenharmony_ci spin_unlock(&cluster_locked->lock); 10158c2ecf20Sopenharmony_ci return -ENOSPC; 10168c2ecf20Sopenharmony_ci} 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_cistatic noinline_for_stack int 10198c2ecf20Sopenharmony_ciupdate_cache_item(struct btrfs_trans_handle *trans, 10208c2ecf20Sopenharmony_ci struct btrfs_root *root, 10218c2ecf20Sopenharmony_ci struct inode *inode, 10228c2ecf20Sopenharmony_ci struct btrfs_path *path, u64 offset, 10238c2ecf20Sopenharmony_ci int entries, int bitmaps) 10248c2ecf20Sopenharmony_ci{ 10258c2ecf20Sopenharmony_ci struct btrfs_key key; 10268c2ecf20Sopenharmony_ci struct btrfs_free_space_header *header; 10278c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 10288c2ecf20Sopenharmony_ci int ret; 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci key.objectid = BTRFS_FREE_SPACE_OBJECTID; 10318c2ecf20Sopenharmony_ci key.offset = offset; 10328c2ecf20Sopenharmony_ci key.type = 0; 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci ret = btrfs_search_slot(trans, root, &key, path, 0, 1); 10358c2ecf20Sopenharmony_ci if (ret < 0) { 10368c2ecf20Sopenharmony_ci clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, 10378c2ecf20Sopenharmony_ci EXTENT_DELALLOC, 0, 0, NULL); 10388c2ecf20Sopenharmony_ci goto fail; 10398c2ecf20Sopenharmony_ci } 10408c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 10418c2ecf20Sopenharmony_ci if (ret > 0) { 10428c2ecf20Sopenharmony_ci struct btrfs_key found_key; 10438c2ecf20Sopenharmony_ci ASSERT(path->slots[0]); 10448c2ecf20Sopenharmony_ci path->slots[0]--; 10458c2ecf20Sopenharmony_ci btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 10468c2ecf20Sopenharmony_ci if (found_key.objectid != BTRFS_FREE_SPACE_OBJECTID || 10478c2ecf20Sopenharmony_ci found_key.offset != offset) { 10488c2ecf20Sopenharmony_ci clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, 10498c2ecf20Sopenharmony_ci inode->i_size - 1, EXTENT_DELALLOC, 0, 10508c2ecf20Sopenharmony_ci 0, NULL); 10518c2ecf20Sopenharmony_ci btrfs_release_path(path); 10528c2ecf20Sopenharmony_ci goto fail; 10538c2ecf20Sopenharmony_ci } 10548c2ecf20Sopenharmony_ci } 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation = trans->transid; 10578c2ecf20Sopenharmony_ci header = btrfs_item_ptr(leaf, path->slots[0], 10588c2ecf20Sopenharmony_ci struct btrfs_free_space_header); 10598c2ecf20Sopenharmony_ci btrfs_set_free_space_entries(leaf, header, entries); 10608c2ecf20Sopenharmony_ci btrfs_set_free_space_bitmaps(leaf, header, bitmaps); 10618c2ecf20Sopenharmony_ci btrfs_set_free_space_generation(leaf, header, trans->transid); 10628c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(leaf); 10638c2ecf20Sopenharmony_ci btrfs_release_path(path); 10648c2ecf20Sopenharmony_ci 10658c2ecf20Sopenharmony_ci return 0; 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_cifail: 10688c2ecf20Sopenharmony_ci return -1; 10698c2ecf20Sopenharmony_ci} 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_cistatic noinline_for_stack int write_pinned_extent_entries( 10728c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 10738c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 10748c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 10758c2ecf20Sopenharmony_ci int *entries) 10768c2ecf20Sopenharmony_ci{ 10778c2ecf20Sopenharmony_ci u64 start, extent_start, extent_end, len; 10788c2ecf20Sopenharmony_ci struct extent_io_tree *unpin = NULL; 10798c2ecf20Sopenharmony_ci int ret; 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci if (!block_group) 10828c2ecf20Sopenharmony_ci return 0; 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci /* 10858c2ecf20Sopenharmony_ci * We want to add any pinned extents to our free space cache 10868c2ecf20Sopenharmony_ci * so we don't leak the space 10878c2ecf20Sopenharmony_ci * 10888c2ecf20Sopenharmony_ci * We shouldn't have switched the pinned extents yet so this is the 10898c2ecf20Sopenharmony_ci * right one 10908c2ecf20Sopenharmony_ci */ 10918c2ecf20Sopenharmony_ci unpin = &trans->transaction->pinned_extents; 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci start = block_group->start; 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci while (start < block_group->start + block_group->length) { 10968c2ecf20Sopenharmony_ci ret = find_first_extent_bit(unpin, start, 10978c2ecf20Sopenharmony_ci &extent_start, &extent_end, 10988c2ecf20Sopenharmony_ci EXTENT_DIRTY, NULL); 10998c2ecf20Sopenharmony_ci if (ret) 11008c2ecf20Sopenharmony_ci return 0; 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_ci /* This pinned extent is out of our range */ 11038c2ecf20Sopenharmony_ci if (extent_start >= block_group->start + block_group->length) 11048c2ecf20Sopenharmony_ci return 0; 11058c2ecf20Sopenharmony_ci 11068c2ecf20Sopenharmony_ci extent_start = max(extent_start, start); 11078c2ecf20Sopenharmony_ci extent_end = min(block_group->start + block_group->length, 11088c2ecf20Sopenharmony_ci extent_end + 1); 11098c2ecf20Sopenharmony_ci len = extent_end - extent_start; 11108c2ecf20Sopenharmony_ci 11118c2ecf20Sopenharmony_ci *entries += 1; 11128c2ecf20Sopenharmony_ci ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL); 11138c2ecf20Sopenharmony_ci if (ret) 11148c2ecf20Sopenharmony_ci return -ENOSPC; 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci start = extent_end; 11178c2ecf20Sopenharmony_ci } 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_ci return 0; 11208c2ecf20Sopenharmony_ci} 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_cistatic noinline_for_stack int 11238c2ecf20Sopenharmony_ciwrite_bitmap_entries(struct btrfs_io_ctl *io_ctl, struct list_head *bitmap_list) 11248c2ecf20Sopenharmony_ci{ 11258c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, *next; 11268c2ecf20Sopenharmony_ci int ret; 11278c2ecf20Sopenharmony_ci 11288c2ecf20Sopenharmony_ci /* Write out the bitmaps */ 11298c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, next, bitmap_list, list) { 11308c2ecf20Sopenharmony_ci ret = io_ctl_add_bitmap(io_ctl, entry->bitmap); 11318c2ecf20Sopenharmony_ci if (ret) 11328c2ecf20Sopenharmony_ci return -ENOSPC; 11338c2ecf20Sopenharmony_ci list_del_init(&entry->list); 11348c2ecf20Sopenharmony_ci } 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci return 0; 11378c2ecf20Sopenharmony_ci} 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_cistatic int flush_dirty_cache(struct inode *inode) 11408c2ecf20Sopenharmony_ci{ 11418c2ecf20Sopenharmony_ci int ret; 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_ci ret = btrfs_wait_ordered_range(inode, 0, (u64)-1); 11448c2ecf20Sopenharmony_ci if (ret) 11458c2ecf20Sopenharmony_ci clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, 11468c2ecf20Sopenharmony_ci EXTENT_DELALLOC, 0, 0, NULL); 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci return ret; 11498c2ecf20Sopenharmony_ci} 11508c2ecf20Sopenharmony_ci 11518c2ecf20Sopenharmony_cistatic void noinline_for_stack 11528c2ecf20Sopenharmony_cicleanup_bitmap_list(struct list_head *bitmap_list) 11538c2ecf20Sopenharmony_ci{ 11548c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, *next; 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, next, bitmap_list, list) 11578c2ecf20Sopenharmony_ci list_del_init(&entry->list); 11588c2ecf20Sopenharmony_ci} 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_cistatic void noinline_for_stack 11618c2ecf20Sopenharmony_cicleanup_write_cache_enospc(struct inode *inode, 11628c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 11638c2ecf20Sopenharmony_ci struct extent_state **cached_state) 11648c2ecf20Sopenharmony_ci{ 11658c2ecf20Sopenharmony_ci io_ctl_drop_pages(io_ctl); 11668c2ecf20Sopenharmony_ci unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 11678c2ecf20Sopenharmony_ci i_size_read(inode) - 1, cached_state); 11688c2ecf20Sopenharmony_ci} 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_cistatic int __btrfs_wait_cache_io(struct btrfs_root *root, 11718c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 11728c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 11738c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 11748c2ecf20Sopenharmony_ci struct btrfs_path *path, u64 offset) 11758c2ecf20Sopenharmony_ci{ 11768c2ecf20Sopenharmony_ci int ret; 11778c2ecf20Sopenharmony_ci struct inode *inode = io_ctl->inode; 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci if (!inode) 11808c2ecf20Sopenharmony_ci return 0; 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ci /* Flush the dirty pages in the cache file. */ 11838c2ecf20Sopenharmony_ci ret = flush_dirty_cache(inode); 11848c2ecf20Sopenharmony_ci if (ret) 11858c2ecf20Sopenharmony_ci goto out; 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci /* Update the cache item to tell everyone this cache file is valid. */ 11888c2ecf20Sopenharmony_ci ret = update_cache_item(trans, root, inode, path, offset, 11898c2ecf20Sopenharmony_ci io_ctl->entries, io_ctl->bitmaps); 11908c2ecf20Sopenharmony_ciout: 11918c2ecf20Sopenharmony_ci if (ret) { 11928c2ecf20Sopenharmony_ci invalidate_inode_pages2(inode->i_mapping); 11938c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation = 0; 11948c2ecf20Sopenharmony_ci if (block_group) 11958c2ecf20Sopenharmony_ci btrfs_debug(root->fs_info, 11968c2ecf20Sopenharmony_ci "failed to write free space cache for block group %llu error %d", 11978c2ecf20Sopenharmony_ci block_group->start, ret); 11988c2ecf20Sopenharmony_ci } 11998c2ecf20Sopenharmony_ci btrfs_update_inode(trans, root, inode); 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci if (block_group) { 12028c2ecf20Sopenharmony_ci /* the dirty list is protected by the dirty_bgs_lock */ 12038c2ecf20Sopenharmony_ci spin_lock(&trans->transaction->dirty_bgs_lock); 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci /* the disk_cache_state is protected by the block group lock */ 12068c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 12078c2ecf20Sopenharmony_ci 12088c2ecf20Sopenharmony_ci /* 12098c2ecf20Sopenharmony_ci * only mark this as written if we didn't get put back on 12108c2ecf20Sopenharmony_ci * the dirty list while waiting for IO. Otherwise our 12118c2ecf20Sopenharmony_ci * cache state won't be right, and we won't get written again 12128c2ecf20Sopenharmony_ci */ 12138c2ecf20Sopenharmony_ci if (!ret && list_empty(&block_group->dirty_list)) 12148c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_WRITTEN; 12158c2ecf20Sopenharmony_ci else if (ret) 12168c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_ERROR; 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 12198c2ecf20Sopenharmony_ci spin_unlock(&trans->transaction->dirty_bgs_lock); 12208c2ecf20Sopenharmony_ci io_ctl->inode = NULL; 12218c2ecf20Sopenharmony_ci iput(inode); 12228c2ecf20Sopenharmony_ci } 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci return ret; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci} 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_cistatic int btrfs_wait_cache_io_root(struct btrfs_root *root, 12298c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 12308c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 12318c2ecf20Sopenharmony_ci struct btrfs_path *path) 12328c2ecf20Sopenharmony_ci{ 12338c2ecf20Sopenharmony_ci return __btrfs_wait_cache_io(root, trans, NULL, io_ctl, path, 0); 12348c2ecf20Sopenharmony_ci} 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ciint btrfs_wait_cache_io(struct btrfs_trans_handle *trans, 12378c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 12388c2ecf20Sopenharmony_ci struct btrfs_path *path) 12398c2ecf20Sopenharmony_ci{ 12408c2ecf20Sopenharmony_ci return __btrfs_wait_cache_io(block_group->fs_info->tree_root, trans, 12418c2ecf20Sopenharmony_ci block_group, &block_group->io_ctl, 12428c2ecf20Sopenharmony_ci path, block_group->start); 12438c2ecf20Sopenharmony_ci} 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci/** 12468c2ecf20Sopenharmony_ci * __btrfs_write_out_cache - write out cached info to an inode 12478c2ecf20Sopenharmony_ci * @root - the root the inode belongs to 12488c2ecf20Sopenharmony_ci * @ctl - the free space cache we are going to write out 12498c2ecf20Sopenharmony_ci * @block_group - the block_group for this cache if it belongs to a block_group 12508c2ecf20Sopenharmony_ci * @trans - the trans handle 12518c2ecf20Sopenharmony_ci * 12528c2ecf20Sopenharmony_ci * This function writes out a free space cache struct to disk for quick recovery 12538c2ecf20Sopenharmony_ci * on mount. This will return 0 if it was successful in writing the cache out, 12548c2ecf20Sopenharmony_ci * or an errno if it was not. 12558c2ecf20Sopenharmony_ci */ 12568c2ecf20Sopenharmony_cistatic int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, 12578c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl, 12588c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 12598c2ecf20Sopenharmony_ci struct btrfs_io_ctl *io_ctl, 12608c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans) 12618c2ecf20Sopenharmony_ci{ 12628c2ecf20Sopenharmony_ci struct extent_state *cached_state = NULL; 12638c2ecf20Sopenharmony_ci LIST_HEAD(bitmap_list); 12648c2ecf20Sopenharmony_ci int entries = 0; 12658c2ecf20Sopenharmony_ci int bitmaps = 0; 12668c2ecf20Sopenharmony_ci int ret; 12678c2ecf20Sopenharmony_ci int must_iput = 0; 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci if (!i_size_read(inode)) 12708c2ecf20Sopenharmony_ci return -EIO; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci WARN_ON(io_ctl->pages); 12738c2ecf20Sopenharmony_ci ret = io_ctl_init(io_ctl, inode, 1); 12748c2ecf20Sopenharmony_ci if (ret) 12758c2ecf20Sopenharmony_ci return ret; 12768c2ecf20Sopenharmony_ci 12778c2ecf20Sopenharmony_ci if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) { 12788c2ecf20Sopenharmony_ci down_write(&block_group->data_rwsem); 12798c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 12808c2ecf20Sopenharmony_ci if (block_group->delalloc_bytes) { 12818c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_WRITTEN; 12828c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 12838c2ecf20Sopenharmony_ci up_write(&block_group->data_rwsem); 12848c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation = 0; 12858c2ecf20Sopenharmony_ci ret = 0; 12868c2ecf20Sopenharmony_ci must_iput = 1; 12878c2ecf20Sopenharmony_ci goto out; 12888c2ecf20Sopenharmony_ci } 12898c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 12908c2ecf20Sopenharmony_ci } 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci /* Lock all pages first so we can lock the extent safely. */ 12938c2ecf20Sopenharmony_ci ret = io_ctl_prepare_pages(io_ctl, false); 12948c2ecf20Sopenharmony_ci if (ret) 12958c2ecf20Sopenharmony_ci goto out_unlock; 12968c2ecf20Sopenharmony_ci 12978c2ecf20Sopenharmony_ci lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, 12988c2ecf20Sopenharmony_ci &cached_state); 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci io_ctl_set_generation(io_ctl, trans->transid); 13018c2ecf20Sopenharmony_ci 13028c2ecf20Sopenharmony_ci mutex_lock(&ctl->cache_writeout_mutex); 13038c2ecf20Sopenharmony_ci /* Write out the extent entries in the free space cache */ 13048c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 13058c2ecf20Sopenharmony_ci ret = write_cache_extent_entries(io_ctl, ctl, 13068c2ecf20Sopenharmony_ci block_group, &entries, &bitmaps, 13078c2ecf20Sopenharmony_ci &bitmap_list); 13088c2ecf20Sopenharmony_ci if (ret) 13098c2ecf20Sopenharmony_ci goto out_nospc_locked; 13108c2ecf20Sopenharmony_ci 13118c2ecf20Sopenharmony_ci /* 13128c2ecf20Sopenharmony_ci * Some spaces that are freed in the current transaction are pinned, 13138c2ecf20Sopenharmony_ci * they will be added into free space cache after the transaction is 13148c2ecf20Sopenharmony_ci * committed, we shouldn't lose them. 13158c2ecf20Sopenharmony_ci * 13168c2ecf20Sopenharmony_ci * If this changes while we are working we'll get added back to 13178c2ecf20Sopenharmony_ci * the dirty list and redo it. No locking needed 13188c2ecf20Sopenharmony_ci */ 13198c2ecf20Sopenharmony_ci ret = write_pinned_extent_entries(trans, block_group, io_ctl, &entries); 13208c2ecf20Sopenharmony_ci if (ret) 13218c2ecf20Sopenharmony_ci goto out_nospc_locked; 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_ci /* 13248c2ecf20Sopenharmony_ci * At last, we write out all the bitmaps and keep cache_writeout_mutex 13258c2ecf20Sopenharmony_ci * locked while doing it because a concurrent trim can be manipulating 13268c2ecf20Sopenharmony_ci * or freeing the bitmap. 13278c2ecf20Sopenharmony_ci */ 13288c2ecf20Sopenharmony_ci ret = write_bitmap_entries(io_ctl, &bitmap_list); 13298c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 13308c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 13318c2ecf20Sopenharmony_ci if (ret) 13328c2ecf20Sopenharmony_ci goto out_nospc; 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci /* Zero out the rest of the pages just to make sure */ 13358c2ecf20Sopenharmony_ci io_ctl_zero_remaining_pages(io_ctl); 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_ci /* Everything is written out, now we dirty the pages in the file. */ 13388c2ecf20Sopenharmony_ci ret = btrfs_dirty_pages(BTRFS_I(inode), io_ctl->pages, 13398c2ecf20Sopenharmony_ci io_ctl->num_pages, 0, i_size_read(inode), 13408c2ecf20Sopenharmony_ci &cached_state); 13418c2ecf20Sopenharmony_ci if (ret) 13428c2ecf20Sopenharmony_ci goto out_nospc; 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) 13458c2ecf20Sopenharmony_ci up_write(&block_group->data_rwsem); 13468c2ecf20Sopenharmony_ci /* 13478c2ecf20Sopenharmony_ci * Release the pages and unlock the extent, we will flush 13488c2ecf20Sopenharmony_ci * them out later 13498c2ecf20Sopenharmony_ci */ 13508c2ecf20Sopenharmony_ci io_ctl_drop_pages(io_ctl); 13518c2ecf20Sopenharmony_ci io_ctl_free(io_ctl); 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, 13548c2ecf20Sopenharmony_ci i_size_read(inode) - 1, &cached_state); 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci /* 13578c2ecf20Sopenharmony_ci * at this point the pages are under IO and we're happy, 13588c2ecf20Sopenharmony_ci * The caller is responsible for waiting on them and updating 13598c2ecf20Sopenharmony_ci * the cache and the inode 13608c2ecf20Sopenharmony_ci */ 13618c2ecf20Sopenharmony_ci io_ctl->entries = entries; 13628c2ecf20Sopenharmony_ci io_ctl->bitmaps = bitmaps; 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_ci ret = btrfs_fdatawrite_range(inode, 0, (u64)-1); 13658c2ecf20Sopenharmony_ci if (ret) 13668c2ecf20Sopenharmony_ci goto out; 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci return 0; 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ciout_nospc_locked: 13718c2ecf20Sopenharmony_ci cleanup_bitmap_list(&bitmap_list); 13728c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 13738c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ciout_nospc: 13768c2ecf20Sopenharmony_ci cleanup_write_cache_enospc(inode, io_ctl, &cached_state); 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_ciout_unlock: 13798c2ecf20Sopenharmony_ci if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) 13808c2ecf20Sopenharmony_ci up_write(&block_group->data_rwsem); 13818c2ecf20Sopenharmony_ci 13828c2ecf20Sopenharmony_ciout: 13838c2ecf20Sopenharmony_ci io_ctl->inode = NULL; 13848c2ecf20Sopenharmony_ci io_ctl_free(io_ctl); 13858c2ecf20Sopenharmony_ci if (ret) { 13868c2ecf20Sopenharmony_ci invalidate_inode_pages2(inode->i_mapping); 13878c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation = 0; 13888c2ecf20Sopenharmony_ci } 13898c2ecf20Sopenharmony_ci btrfs_update_inode(trans, root, inode); 13908c2ecf20Sopenharmony_ci if (must_iput) 13918c2ecf20Sopenharmony_ci iput(inode); 13928c2ecf20Sopenharmony_ci return ret; 13938c2ecf20Sopenharmony_ci} 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ciint btrfs_write_out_cache(struct btrfs_trans_handle *trans, 13968c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 13978c2ecf20Sopenharmony_ci struct btrfs_path *path) 13988c2ecf20Sopenharmony_ci{ 13998c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = trans->fs_info; 14008c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 14018c2ecf20Sopenharmony_ci struct inode *inode; 14028c2ecf20Sopenharmony_ci int ret = 0; 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 14058c2ecf20Sopenharmony_ci if (block_group->disk_cache_state < BTRFS_DC_SETUP) { 14068c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 14078c2ecf20Sopenharmony_ci return 0; 14088c2ecf20Sopenharmony_ci } 14098c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci inode = lookup_free_space_inode(block_group, path); 14128c2ecf20Sopenharmony_ci if (IS_ERR(inode)) 14138c2ecf20Sopenharmony_ci return 0; 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci ret = __btrfs_write_out_cache(fs_info->tree_root, inode, ctl, 14168c2ecf20Sopenharmony_ci block_group, &block_group->io_ctl, trans); 14178c2ecf20Sopenharmony_ci if (ret) { 14188c2ecf20Sopenharmony_ci btrfs_debug(fs_info, 14198c2ecf20Sopenharmony_ci "failed to write free space cache for block group %llu error %d", 14208c2ecf20Sopenharmony_ci block_group->start, ret); 14218c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 14228c2ecf20Sopenharmony_ci block_group->disk_cache_state = BTRFS_DC_ERROR; 14238c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci block_group->io_ctl.inode = NULL; 14268c2ecf20Sopenharmony_ci iput(inode); 14278c2ecf20Sopenharmony_ci } 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_ci /* 14308c2ecf20Sopenharmony_ci * if ret == 0 the caller is expected to call btrfs_wait_cache_io 14318c2ecf20Sopenharmony_ci * to wait for IO and put the inode 14328c2ecf20Sopenharmony_ci */ 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci return ret; 14358c2ecf20Sopenharmony_ci} 14368c2ecf20Sopenharmony_ci 14378c2ecf20Sopenharmony_cistatic inline unsigned long offset_to_bit(u64 bitmap_start, u32 unit, 14388c2ecf20Sopenharmony_ci u64 offset) 14398c2ecf20Sopenharmony_ci{ 14408c2ecf20Sopenharmony_ci ASSERT(offset >= bitmap_start); 14418c2ecf20Sopenharmony_ci offset -= bitmap_start; 14428c2ecf20Sopenharmony_ci return (unsigned long)(div_u64(offset, unit)); 14438c2ecf20Sopenharmony_ci} 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_cistatic inline unsigned long bytes_to_bits(u64 bytes, u32 unit) 14468c2ecf20Sopenharmony_ci{ 14478c2ecf20Sopenharmony_ci return (unsigned long)(div_u64(bytes, unit)); 14488c2ecf20Sopenharmony_ci} 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_cistatic inline u64 offset_to_bitmap(struct btrfs_free_space_ctl *ctl, 14518c2ecf20Sopenharmony_ci u64 offset) 14528c2ecf20Sopenharmony_ci{ 14538c2ecf20Sopenharmony_ci u64 bitmap_start; 14548c2ecf20Sopenharmony_ci u64 bytes_per_bitmap; 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci bytes_per_bitmap = BITS_PER_BITMAP * ctl->unit; 14578c2ecf20Sopenharmony_ci bitmap_start = offset - ctl->start; 14588c2ecf20Sopenharmony_ci bitmap_start = div64_u64(bitmap_start, bytes_per_bitmap); 14598c2ecf20Sopenharmony_ci bitmap_start *= bytes_per_bitmap; 14608c2ecf20Sopenharmony_ci bitmap_start += ctl->start; 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci return bitmap_start; 14638c2ecf20Sopenharmony_ci} 14648c2ecf20Sopenharmony_ci 14658c2ecf20Sopenharmony_cistatic int tree_insert_offset(struct rb_root *root, u64 offset, 14668c2ecf20Sopenharmony_ci struct rb_node *node, int bitmap) 14678c2ecf20Sopenharmony_ci{ 14688c2ecf20Sopenharmony_ci struct rb_node **p = &root->rb_node; 14698c2ecf20Sopenharmony_ci struct rb_node *parent = NULL; 14708c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_ci while (*p) { 14738c2ecf20Sopenharmony_ci parent = *p; 14748c2ecf20Sopenharmony_ci info = rb_entry(parent, struct btrfs_free_space, offset_index); 14758c2ecf20Sopenharmony_ci 14768c2ecf20Sopenharmony_ci if (offset < info->offset) { 14778c2ecf20Sopenharmony_ci p = &(*p)->rb_left; 14788c2ecf20Sopenharmony_ci } else if (offset > info->offset) { 14798c2ecf20Sopenharmony_ci p = &(*p)->rb_right; 14808c2ecf20Sopenharmony_ci } else { 14818c2ecf20Sopenharmony_ci /* 14828c2ecf20Sopenharmony_ci * we could have a bitmap entry and an extent entry 14838c2ecf20Sopenharmony_ci * share the same offset. If this is the case, we want 14848c2ecf20Sopenharmony_ci * the extent entry to always be found first if we do a 14858c2ecf20Sopenharmony_ci * linear search through the tree, since we want to have 14868c2ecf20Sopenharmony_ci * the quickest allocation time, and allocating from an 14878c2ecf20Sopenharmony_ci * extent is faster than allocating from a bitmap. So 14888c2ecf20Sopenharmony_ci * if we're inserting a bitmap and we find an entry at 14898c2ecf20Sopenharmony_ci * this offset, we want to go right, or after this entry 14908c2ecf20Sopenharmony_ci * logically. If we are inserting an extent and we've 14918c2ecf20Sopenharmony_ci * found a bitmap, we want to go left, or before 14928c2ecf20Sopenharmony_ci * logically. 14938c2ecf20Sopenharmony_ci */ 14948c2ecf20Sopenharmony_ci if (bitmap) { 14958c2ecf20Sopenharmony_ci if (info->bitmap) { 14968c2ecf20Sopenharmony_ci WARN_ON_ONCE(1); 14978c2ecf20Sopenharmony_ci return -EEXIST; 14988c2ecf20Sopenharmony_ci } 14998c2ecf20Sopenharmony_ci p = &(*p)->rb_right; 15008c2ecf20Sopenharmony_ci } else { 15018c2ecf20Sopenharmony_ci if (!info->bitmap) { 15028c2ecf20Sopenharmony_ci WARN_ON_ONCE(1); 15038c2ecf20Sopenharmony_ci return -EEXIST; 15048c2ecf20Sopenharmony_ci } 15058c2ecf20Sopenharmony_ci p = &(*p)->rb_left; 15068c2ecf20Sopenharmony_ci } 15078c2ecf20Sopenharmony_ci } 15088c2ecf20Sopenharmony_ci } 15098c2ecf20Sopenharmony_ci 15108c2ecf20Sopenharmony_ci rb_link_node(node, parent, p); 15118c2ecf20Sopenharmony_ci rb_insert_color(node, root); 15128c2ecf20Sopenharmony_ci 15138c2ecf20Sopenharmony_ci return 0; 15148c2ecf20Sopenharmony_ci} 15158c2ecf20Sopenharmony_ci 15168c2ecf20Sopenharmony_ci/* 15178c2ecf20Sopenharmony_ci * searches the tree for the given offset. 15188c2ecf20Sopenharmony_ci * 15198c2ecf20Sopenharmony_ci * fuzzy - If this is set, then we are trying to make an allocation, and we just 15208c2ecf20Sopenharmony_ci * want a section that has at least bytes size and comes at or after the given 15218c2ecf20Sopenharmony_ci * offset. 15228c2ecf20Sopenharmony_ci */ 15238c2ecf20Sopenharmony_cistatic struct btrfs_free_space * 15248c2ecf20Sopenharmony_citree_search_offset(struct btrfs_free_space_ctl *ctl, 15258c2ecf20Sopenharmony_ci u64 offset, int bitmap_only, int fuzzy) 15268c2ecf20Sopenharmony_ci{ 15278c2ecf20Sopenharmony_ci struct rb_node *n = ctl->free_space_offset.rb_node; 15288c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, *prev = NULL; 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci /* find entry that is closest to the 'offset' */ 15318c2ecf20Sopenharmony_ci while (1) { 15328c2ecf20Sopenharmony_ci if (!n) { 15338c2ecf20Sopenharmony_ci entry = NULL; 15348c2ecf20Sopenharmony_ci break; 15358c2ecf20Sopenharmony_ci } 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_ci entry = rb_entry(n, struct btrfs_free_space, offset_index); 15388c2ecf20Sopenharmony_ci prev = entry; 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci if (offset < entry->offset) 15418c2ecf20Sopenharmony_ci n = n->rb_left; 15428c2ecf20Sopenharmony_ci else if (offset > entry->offset) 15438c2ecf20Sopenharmony_ci n = n->rb_right; 15448c2ecf20Sopenharmony_ci else 15458c2ecf20Sopenharmony_ci break; 15468c2ecf20Sopenharmony_ci } 15478c2ecf20Sopenharmony_ci 15488c2ecf20Sopenharmony_ci if (bitmap_only) { 15498c2ecf20Sopenharmony_ci if (!entry) 15508c2ecf20Sopenharmony_ci return NULL; 15518c2ecf20Sopenharmony_ci if (entry->bitmap) 15528c2ecf20Sopenharmony_ci return entry; 15538c2ecf20Sopenharmony_ci 15548c2ecf20Sopenharmony_ci /* 15558c2ecf20Sopenharmony_ci * bitmap entry and extent entry may share same offset, 15568c2ecf20Sopenharmony_ci * in that case, bitmap entry comes after extent entry. 15578c2ecf20Sopenharmony_ci */ 15588c2ecf20Sopenharmony_ci n = rb_next(n); 15598c2ecf20Sopenharmony_ci if (!n) 15608c2ecf20Sopenharmony_ci return NULL; 15618c2ecf20Sopenharmony_ci entry = rb_entry(n, struct btrfs_free_space, offset_index); 15628c2ecf20Sopenharmony_ci if (entry->offset != offset) 15638c2ecf20Sopenharmony_ci return NULL; 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_ci WARN_ON(!entry->bitmap); 15668c2ecf20Sopenharmony_ci return entry; 15678c2ecf20Sopenharmony_ci } else if (entry) { 15688c2ecf20Sopenharmony_ci if (entry->bitmap) { 15698c2ecf20Sopenharmony_ci /* 15708c2ecf20Sopenharmony_ci * if previous extent entry covers the offset, 15718c2ecf20Sopenharmony_ci * we should return it instead of the bitmap entry 15728c2ecf20Sopenharmony_ci */ 15738c2ecf20Sopenharmony_ci n = rb_prev(&entry->offset_index); 15748c2ecf20Sopenharmony_ci if (n) { 15758c2ecf20Sopenharmony_ci prev = rb_entry(n, struct btrfs_free_space, 15768c2ecf20Sopenharmony_ci offset_index); 15778c2ecf20Sopenharmony_ci if (!prev->bitmap && 15788c2ecf20Sopenharmony_ci prev->offset + prev->bytes > offset) 15798c2ecf20Sopenharmony_ci entry = prev; 15808c2ecf20Sopenharmony_ci } 15818c2ecf20Sopenharmony_ci } 15828c2ecf20Sopenharmony_ci return entry; 15838c2ecf20Sopenharmony_ci } 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci if (!prev) 15868c2ecf20Sopenharmony_ci return NULL; 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_ci /* find last entry before the 'offset' */ 15898c2ecf20Sopenharmony_ci entry = prev; 15908c2ecf20Sopenharmony_ci if (entry->offset > offset) { 15918c2ecf20Sopenharmony_ci n = rb_prev(&entry->offset_index); 15928c2ecf20Sopenharmony_ci if (n) { 15938c2ecf20Sopenharmony_ci entry = rb_entry(n, struct btrfs_free_space, 15948c2ecf20Sopenharmony_ci offset_index); 15958c2ecf20Sopenharmony_ci ASSERT(entry->offset <= offset); 15968c2ecf20Sopenharmony_ci } else { 15978c2ecf20Sopenharmony_ci if (fuzzy) 15988c2ecf20Sopenharmony_ci return entry; 15998c2ecf20Sopenharmony_ci else 16008c2ecf20Sopenharmony_ci return NULL; 16018c2ecf20Sopenharmony_ci } 16028c2ecf20Sopenharmony_ci } 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci if (entry->bitmap) { 16058c2ecf20Sopenharmony_ci n = rb_prev(&entry->offset_index); 16068c2ecf20Sopenharmony_ci if (n) { 16078c2ecf20Sopenharmony_ci prev = rb_entry(n, struct btrfs_free_space, 16088c2ecf20Sopenharmony_ci offset_index); 16098c2ecf20Sopenharmony_ci if (!prev->bitmap && 16108c2ecf20Sopenharmony_ci prev->offset + prev->bytes > offset) 16118c2ecf20Sopenharmony_ci return prev; 16128c2ecf20Sopenharmony_ci } 16138c2ecf20Sopenharmony_ci if (entry->offset + BITS_PER_BITMAP * ctl->unit > offset) 16148c2ecf20Sopenharmony_ci return entry; 16158c2ecf20Sopenharmony_ci } else if (entry->offset + entry->bytes > offset) 16168c2ecf20Sopenharmony_ci return entry; 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci if (!fuzzy) 16198c2ecf20Sopenharmony_ci return NULL; 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci while (1) { 16228c2ecf20Sopenharmony_ci if (entry->bitmap) { 16238c2ecf20Sopenharmony_ci if (entry->offset + BITS_PER_BITMAP * 16248c2ecf20Sopenharmony_ci ctl->unit > offset) 16258c2ecf20Sopenharmony_ci break; 16268c2ecf20Sopenharmony_ci } else { 16278c2ecf20Sopenharmony_ci if (entry->offset + entry->bytes > offset) 16288c2ecf20Sopenharmony_ci break; 16298c2ecf20Sopenharmony_ci } 16308c2ecf20Sopenharmony_ci 16318c2ecf20Sopenharmony_ci n = rb_next(&entry->offset_index); 16328c2ecf20Sopenharmony_ci if (!n) 16338c2ecf20Sopenharmony_ci return NULL; 16348c2ecf20Sopenharmony_ci entry = rb_entry(n, struct btrfs_free_space, offset_index); 16358c2ecf20Sopenharmony_ci } 16368c2ecf20Sopenharmony_ci return entry; 16378c2ecf20Sopenharmony_ci} 16388c2ecf20Sopenharmony_ci 16398c2ecf20Sopenharmony_cistatic inline void 16408c2ecf20Sopenharmony_ci__unlink_free_space(struct btrfs_free_space_ctl *ctl, 16418c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 16428c2ecf20Sopenharmony_ci{ 16438c2ecf20Sopenharmony_ci rb_erase(&info->offset_index, &ctl->free_space_offset); 16448c2ecf20Sopenharmony_ci ctl->free_extents--; 16458c2ecf20Sopenharmony_ci 16468c2ecf20Sopenharmony_ci if (!info->bitmap && !btrfs_free_space_trimmed(info)) { 16478c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR]--; 16488c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= info->bytes; 16498c2ecf20Sopenharmony_ci } 16508c2ecf20Sopenharmony_ci} 16518c2ecf20Sopenharmony_ci 16528c2ecf20Sopenharmony_cistatic void unlink_free_space(struct btrfs_free_space_ctl *ctl, 16538c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 16548c2ecf20Sopenharmony_ci{ 16558c2ecf20Sopenharmony_ci __unlink_free_space(ctl, info); 16568c2ecf20Sopenharmony_ci ctl->free_space -= info->bytes; 16578c2ecf20Sopenharmony_ci} 16588c2ecf20Sopenharmony_ci 16598c2ecf20Sopenharmony_cistatic int link_free_space(struct btrfs_free_space_ctl *ctl, 16608c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 16618c2ecf20Sopenharmony_ci{ 16628c2ecf20Sopenharmony_ci int ret = 0; 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_ci ASSERT(info->bytes || info->bitmap); 16658c2ecf20Sopenharmony_ci ret = tree_insert_offset(&ctl->free_space_offset, info->offset, 16668c2ecf20Sopenharmony_ci &info->offset_index, (info->bitmap != NULL)); 16678c2ecf20Sopenharmony_ci if (ret) 16688c2ecf20Sopenharmony_ci return ret; 16698c2ecf20Sopenharmony_ci 16708c2ecf20Sopenharmony_ci if (!info->bitmap && !btrfs_free_space_trimmed(info)) { 16718c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR]++; 16728c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += info->bytes; 16738c2ecf20Sopenharmony_ci } 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci ctl->free_space += info->bytes; 16768c2ecf20Sopenharmony_ci ctl->free_extents++; 16778c2ecf20Sopenharmony_ci return ret; 16788c2ecf20Sopenharmony_ci} 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_cistatic void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) 16818c2ecf20Sopenharmony_ci{ 16828c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group = ctl->private; 16838c2ecf20Sopenharmony_ci u64 max_bytes; 16848c2ecf20Sopenharmony_ci u64 bitmap_bytes; 16858c2ecf20Sopenharmony_ci u64 extent_bytes; 16868c2ecf20Sopenharmony_ci u64 size = block_group->length; 16878c2ecf20Sopenharmony_ci u64 bytes_per_bg = BITS_PER_BITMAP * ctl->unit; 16888c2ecf20Sopenharmony_ci u64 max_bitmaps = div64_u64(size + bytes_per_bg - 1, bytes_per_bg); 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci max_bitmaps = max_t(u64, max_bitmaps, 1); 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci ASSERT(ctl->total_bitmaps <= max_bitmaps); 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci /* 16958c2ecf20Sopenharmony_ci * We are trying to keep the total amount of memory used per 1GiB of 16968c2ecf20Sopenharmony_ci * space to be MAX_CACHE_BYTES_PER_GIG. However, with a reclamation 16978c2ecf20Sopenharmony_ci * mechanism of pulling extents >= FORCE_EXTENT_THRESHOLD out of 16988c2ecf20Sopenharmony_ci * bitmaps, we may end up using more memory than this. 16998c2ecf20Sopenharmony_ci */ 17008c2ecf20Sopenharmony_ci if (size < SZ_1G) 17018c2ecf20Sopenharmony_ci max_bytes = MAX_CACHE_BYTES_PER_GIG; 17028c2ecf20Sopenharmony_ci else 17038c2ecf20Sopenharmony_ci max_bytes = MAX_CACHE_BYTES_PER_GIG * div_u64(size, SZ_1G); 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_ci bitmap_bytes = ctl->total_bitmaps * ctl->unit; 17068c2ecf20Sopenharmony_ci 17078c2ecf20Sopenharmony_ci /* 17088c2ecf20Sopenharmony_ci * we want the extent entry threshold to always be at most 1/2 the max 17098c2ecf20Sopenharmony_ci * bytes we can have, or whatever is less than that. 17108c2ecf20Sopenharmony_ci */ 17118c2ecf20Sopenharmony_ci extent_bytes = max_bytes - bitmap_bytes; 17128c2ecf20Sopenharmony_ci extent_bytes = min_t(u64, extent_bytes, max_bytes >> 1); 17138c2ecf20Sopenharmony_ci 17148c2ecf20Sopenharmony_ci ctl->extents_thresh = 17158c2ecf20Sopenharmony_ci div_u64(extent_bytes, sizeof(struct btrfs_free_space)); 17168c2ecf20Sopenharmony_ci} 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_cistatic inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, 17198c2ecf20Sopenharmony_ci struct btrfs_free_space *info, 17208c2ecf20Sopenharmony_ci u64 offset, u64 bytes) 17218c2ecf20Sopenharmony_ci{ 17228c2ecf20Sopenharmony_ci unsigned long start, count, end; 17238c2ecf20Sopenharmony_ci int extent_delta = -1; 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_ci start = offset_to_bit(info->offset, ctl->unit, offset); 17268c2ecf20Sopenharmony_ci count = bytes_to_bits(bytes, ctl->unit); 17278c2ecf20Sopenharmony_ci end = start + count; 17288c2ecf20Sopenharmony_ci ASSERT(end <= BITS_PER_BITMAP); 17298c2ecf20Sopenharmony_ci 17308c2ecf20Sopenharmony_ci bitmap_clear(info->bitmap, start, count); 17318c2ecf20Sopenharmony_ci 17328c2ecf20Sopenharmony_ci info->bytes -= bytes; 17338c2ecf20Sopenharmony_ci if (info->max_extent_size > ctl->unit) 17348c2ecf20Sopenharmony_ci info->max_extent_size = 0; 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci if (start && test_bit(start - 1, info->bitmap)) 17378c2ecf20Sopenharmony_ci extent_delta++; 17388c2ecf20Sopenharmony_ci 17398c2ecf20Sopenharmony_ci if (end < BITS_PER_BITMAP && test_bit(end, info->bitmap)) 17408c2ecf20Sopenharmony_ci extent_delta++; 17418c2ecf20Sopenharmony_ci 17428c2ecf20Sopenharmony_ci info->bitmap_extents += extent_delta; 17438c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(info)) { 17448c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] += extent_delta; 17458c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= bytes; 17468c2ecf20Sopenharmony_ci } 17478c2ecf20Sopenharmony_ci} 17488c2ecf20Sopenharmony_ci 17498c2ecf20Sopenharmony_cistatic void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, 17508c2ecf20Sopenharmony_ci struct btrfs_free_space *info, u64 offset, 17518c2ecf20Sopenharmony_ci u64 bytes) 17528c2ecf20Sopenharmony_ci{ 17538c2ecf20Sopenharmony_ci __bitmap_clear_bits(ctl, info, offset, bytes); 17548c2ecf20Sopenharmony_ci ctl->free_space -= bytes; 17558c2ecf20Sopenharmony_ci} 17568c2ecf20Sopenharmony_ci 17578c2ecf20Sopenharmony_cistatic void bitmap_set_bits(struct btrfs_free_space_ctl *ctl, 17588c2ecf20Sopenharmony_ci struct btrfs_free_space *info, u64 offset, 17598c2ecf20Sopenharmony_ci u64 bytes) 17608c2ecf20Sopenharmony_ci{ 17618c2ecf20Sopenharmony_ci unsigned long start, count, end; 17628c2ecf20Sopenharmony_ci int extent_delta = 1; 17638c2ecf20Sopenharmony_ci 17648c2ecf20Sopenharmony_ci start = offset_to_bit(info->offset, ctl->unit, offset); 17658c2ecf20Sopenharmony_ci count = bytes_to_bits(bytes, ctl->unit); 17668c2ecf20Sopenharmony_ci end = start + count; 17678c2ecf20Sopenharmony_ci ASSERT(end <= BITS_PER_BITMAP); 17688c2ecf20Sopenharmony_ci 17698c2ecf20Sopenharmony_ci bitmap_set(info->bitmap, start, count); 17708c2ecf20Sopenharmony_ci 17718c2ecf20Sopenharmony_ci info->bytes += bytes; 17728c2ecf20Sopenharmony_ci ctl->free_space += bytes; 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci if (start && test_bit(start - 1, info->bitmap)) 17758c2ecf20Sopenharmony_ci extent_delta--; 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_ci if (end < BITS_PER_BITMAP && test_bit(end, info->bitmap)) 17788c2ecf20Sopenharmony_ci extent_delta--; 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_ci info->bitmap_extents += extent_delta; 17818c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(info)) { 17828c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] += extent_delta; 17838c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += bytes; 17848c2ecf20Sopenharmony_ci } 17858c2ecf20Sopenharmony_ci} 17868c2ecf20Sopenharmony_ci 17878c2ecf20Sopenharmony_ci/* 17888c2ecf20Sopenharmony_ci * If we can not find suitable extent, we will use bytes to record 17898c2ecf20Sopenharmony_ci * the size of the max extent. 17908c2ecf20Sopenharmony_ci */ 17918c2ecf20Sopenharmony_cistatic int search_bitmap(struct btrfs_free_space_ctl *ctl, 17928c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info, u64 *offset, 17938c2ecf20Sopenharmony_ci u64 *bytes, bool for_alloc) 17948c2ecf20Sopenharmony_ci{ 17958c2ecf20Sopenharmony_ci unsigned long found_bits = 0; 17968c2ecf20Sopenharmony_ci unsigned long max_bits = 0; 17978c2ecf20Sopenharmony_ci unsigned long bits, i; 17988c2ecf20Sopenharmony_ci unsigned long next_zero; 17998c2ecf20Sopenharmony_ci unsigned long extent_bits; 18008c2ecf20Sopenharmony_ci 18018c2ecf20Sopenharmony_ci /* 18028c2ecf20Sopenharmony_ci * Skip searching the bitmap if we don't have a contiguous section that 18038c2ecf20Sopenharmony_ci * is large enough for this allocation. 18048c2ecf20Sopenharmony_ci */ 18058c2ecf20Sopenharmony_ci if (for_alloc && 18068c2ecf20Sopenharmony_ci bitmap_info->max_extent_size && 18078c2ecf20Sopenharmony_ci bitmap_info->max_extent_size < *bytes) { 18088c2ecf20Sopenharmony_ci *bytes = bitmap_info->max_extent_size; 18098c2ecf20Sopenharmony_ci return -1; 18108c2ecf20Sopenharmony_ci } 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci i = offset_to_bit(bitmap_info->offset, ctl->unit, 18138c2ecf20Sopenharmony_ci max_t(u64, *offset, bitmap_info->offset)); 18148c2ecf20Sopenharmony_ci bits = bytes_to_bits(*bytes, ctl->unit); 18158c2ecf20Sopenharmony_ci 18168c2ecf20Sopenharmony_ci for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) { 18178c2ecf20Sopenharmony_ci if (for_alloc && bits == 1) { 18188c2ecf20Sopenharmony_ci found_bits = 1; 18198c2ecf20Sopenharmony_ci break; 18208c2ecf20Sopenharmony_ci } 18218c2ecf20Sopenharmony_ci next_zero = find_next_zero_bit(bitmap_info->bitmap, 18228c2ecf20Sopenharmony_ci BITS_PER_BITMAP, i); 18238c2ecf20Sopenharmony_ci extent_bits = next_zero - i; 18248c2ecf20Sopenharmony_ci if (extent_bits >= bits) { 18258c2ecf20Sopenharmony_ci found_bits = extent_bits; 18268c2ecf20Sopenharmony_ci break; 18278c2ecf20Sopenharmony_ci } else if (extent_bits > max_bits) { 18288c2ecf20Sopenharmony_ci max_bits = extent_bits; 18298c2ecf20Sopenharmony_ci } 18308c2ecf20Sopenharmony_ci i = next_zero; 18318c2ecf20Sopenharmony_ci } 18328c2ecf20Sopenharmony_ci 18338c2ecf20Sopenharmony_ci if (found_bits) { 18348c2ecf20Sopenharmony_ci *offset = (u64)(i * ctl->unit) + bitmap_info->offset; 18358c2ecf20Sopenharmony_ci *bytes = (u64)(found_bits) * ctl->unit; 18368c2ecf20Sopenharmony_ci return 0; 18378c2ecf20Sopenharmony_ci } 18388c2ecf20Sopenharmony_ci 18398c2ecf20Sopenharmony_ci *bytes = (u64)(max_bits) * ctl->unit; 18408c2ecf20Sopenharmony_ci bitmap_info->max_extent_size = *bytes; 18418c2ecf20Sopenharmony_ci return -1; 18428c2ecf20Sopenharmony_ci} 18438c2ecf20Sopenharmony_ci 18448c2ecf20Sopenharmony_cistatic inline u64 get_max_extent_size(struct btrfs_free_space *entry) 18458c2ecf20Sopenharmony_ci{ 18468c2ecf20Sopenharmony_ci if (entry->bitmap) 18478c2ecf20Sopenharmony_ci return entry->max_extent_size; 18488c2ecf20Sopenharmony_ci return entry->bytes; 18498c2ecf20Sopenharmony_ci} 18508c2ecf20Sopenharmony_ci 18518c2ecf20Sopenharmony_ci/* Cache the size of the max extent in bytes */ 18528c2ecf20Sopenharmony_cistatic struct btrfs_free_space * 18538c2ecf20Sopenharmony_cifind_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes, 18548c2ecf20Sopenharmony_ci unsigned long align, u64 *max_extent_size) 18558c2ecf20Sopenharmony_ci{ 18568c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 18578c2ecf20Sopenharmony_ci struct rb_node *node; 18588c2ecf20Sopenharmony_ci u64 tmp; 18598c2ecf20Sopenharmony_ci u64 align_off; 18608c2ecf20Sopenharmony_ci int ret; 18618c2ecf20Sopenharmony_ci 18628c2ecf20Sopenharmony_ci if (!ctl->free_space_offset.rb_node) 18638c2ecf20Sopenharmony_ci goto out; 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, offset_to_bitmap(ctl, *offset), 0, 1); 18668c2ecf20Sopenharmony_ci if (!entry) 18678c2ecf20Sopenharmony_ci goto out; 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci for (node = &entry->offset_index; node; node = rb_next(node)) { 18708c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 18718c2ecf20Sopenharmony_ci if (entry->bytes < *bytes) { 18728c2ecf20Sopenharmony_ci *max_extent_size = max(get_max_extent_size(entry), 18738c2ecf20Sopenharmony_ci *max_extent_size); 18748c2ecf20Sopenharmony_ci continue; 18758c2ecf20Sopenharmony_ci } 18768c2ecf20Sopenharmony_ci 18778c2ecf20Sopenharmony_ci /* make sure the space returned is big enough 18788c2ecf20Sopenharmony_ci * to match our requested alignment 18798c2ecf20Sopenharmony_ci */ 18808c2ecf20Sopenharmony_ci if (*bytes >= align) { 18818c2ecf20Sopenharmony_ci tmp = entry->offset - ctl->start + align - 1; 18828c2ecf20Sopenharmony_ci tmp = div64_u64(tmp, align); 18838c2ecf20Sopenharmony_ci tmp = tmp * align + ctl->start; 18848c2ecf20Sopenharmony_ci align_off = tmp - entry->offset; 18858c2ecf20Sopenharmony_ci } else { 18868c2ecf20Sopenharmony_ci align_off = 0; 18878c2ecf20Sopenharmony_ci tmp = entry->offset; 18888c2ecf20Sopenharmony_ci } 18898c2ecf20Sopenharmony_ci 18908c2ecf20Sopenharmony_ci if (entry->bytes < *bytes + align_off) { 18918c2ecf20Sopenharmony_ci *max_extent_size = max(get_max_extent_size(entry), 18928c2ecf20Sopenharmony_ci *max_extent_size); 18938c2ecf20Sopenharmony_ci continue; 18948c2ecf20Sopenharmony_ci } 18958c2ecf20Sopenharmony_ci 18968c2ecf20Sopenharmony_ci if (entry->bitmap) { 18978c2ecf20Sopenharmony_ci u64 size = *bytes; 18988c2ecf20Sopenharmony_ci 18998c2ecf20Sopenharmony_ci ret = search_bitmap(ctl, entry, &tmp, &size, true); 19008c2ecf20Sopenharmony_ci if (!ret) { 19018c2ecf20Sopenharmony_ci *offset = tmp; 19028c2ecf20Sopenharmony_ci *bytes = size; 19038c2ecf20Sopenharmony_ci return entry; 19048c2ecf20Sopenharmony_ci } else { 19058c2ecf20Sopenharmony_ci *max_extent_size = 19068c2ecf20Sopenharmony_ci max(get_max_extent_size(entry), 19078c2ecf20Sopenharmony_ci *max_extent_size); 19088c2ecf20Sopenharmony_ci } 19098c2ecf20Sopenharmony_ci continue; 19108c2ecf20Sopenharmony_ci } 19118c2ecf20Sopenharmony_ci 19128c2ecf20Sopenharmony_ci *offset = tmp; 19138c2ecf20Sopenharmony_ci *bytes = entry->bytes - align_off; 19148c2ecf20Sopenharmony_ci return entry; 19158c2ecf20Sopenharmony_ci } 19168c2ecf20Sopenharmony_ciout: 19178c2ecf20Sopenharmony_ci return NULL; 19188c2ecf20Sopenharmony_ci} 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_cistatic int count_bitmap_extents(struct btrfs_free_space_ctl *ctl, 19218c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info) 19228c2ecf20Sopenharmony_ci{ 19238c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group = ctl->private; 19248c2ecf20Sopenharmony_ci u64 bytes = bitmap_info->bytes; 19258c2ecf20Sopenharmony_ci unsigned int rs, re; 19268c2ecf20Sopenharmony_ci int count = 0; 19278c2ecf20Sopenharmony_ci 19288c2ecf20Sopenharmony_ci if (!block_group || !bytes) 19298c2ecf20Sopenharmony_ci return count; 19308c2ecf20Sopenharmony_ci 19318c2ecf20Sopenharmony_ci bitmap_for_each_set_region(bitmap_info->bitmap, rs, re, 0, 19328c2ecf20Sopenharmony_ci BITS_PER_BITMAP) { 19338c2ecf20Sopenharmony_ci bytes -= (rs - re) * ctl->unit; 19348c2ecf20Sopenharmony_ci count++; 19358c2ecf20Sopenharmony_ci 19368c2ecf20Sopenharmony_ci if (!bytes) 19378c2ecf20Sopenharmony_ci break; 19388c2ecf20Sopenharmony_ci } 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci return count; 19418c2ecf20Sopenharmony_ci} 19428c2ecf20Sopenharmony_ci 19438c2ecf20Sopenharmony_cistatic void add_new_bitmap(struct btrfs_free_space_ctl *ctl, 19448c2ecf20Sopenharmony_ci struct btrfs_free_space *info, u64 offset) 19458c2ecf20Sopenharmony_ci{ 19468c2ecf20Sopenharmony_ci info->offset = offset_to_bitmap(ctl, offset); 19478c2ecf20Sopenharmony_ci info->bytes = 0; 19488c2ecf20Sopenharmony_ci info->bitmap_extents = 0; 19498c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&info->list); 19508c2ecf20Sopenharmony_ci link_free_space(ctl, info); 19518c2ecf20Sopenharmony_ci ctl->total_bitmaps++; 19528c2ecf20Sopenharmony_ci 19538c2ecf20Sopenharmony_ci ctl->op->recalc_thresholds(ctl); 19548c2ecf20Sopenharmony_ci} 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_cistatic void free_bitmap(struct btrfs_free_space_ctl *ctl, 19578c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info) 19588c2ecf20Sopenharmony_ci{ 19598c2ecf20Sopenharmony_ci /* 19608c2ecf20Sopenharmony_ci * Normally when this is called, the bitmap is completely empty. However, 19618c2ecf20Sopenharmony_ci * if we are blowing up the free space cache for one reason or another 19628c2ecf20Sopenharmony_ci * via __btrfs_remove_free_space_cache(), then it may not be freed and 19638c2ecf20Sopenharmony_ci * we may leave stats on the table. 19648c2ecf20Sopenharmony_ci */ 19658c2ecf20Sopenharmony_ci if (bitmap_info->bytes && !btrfs_free_space_trimmed(bitmap_info)) { 19668c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] -= 19678c2ecf20Sopenharmony_ci bitmap_info->bitmap_extents; 19688c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= bitmap_info->bytes; 19698c2ecf20Sopenharmony_ci 19708c2ecf20Sopenharmony_ci } 19718c2ecf20Sopenharmony_ci unlink_free_space(ctl, bitmap_info); 19728c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_bitmap_cachep, bitmap_info->bitmap); 19738c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, bitmap_info); 19748c2ecf20Sopenharmony_ci ctl->total_bitmaps--; 19758c2ecf20Sopenharmony_ci ctl->op->recalc_thresholds(ctl); 19768c2ecf20Sopenharmony_ci} 19778c2ecf20Sopenharmony_ci 19788c2ecf20Sopenharmony_cistatic noinline int remove_from_bitmap(struct btrfs_free_space_ctl *ctl, 19798c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info, 19808c2ecf20Sopenharmony_ci u64 *offset, u64 *bytes) 19818c2ecf20Sopenharmony_ci{ 19828c2ecf20Sopenharmony_ci u64 end; 19838c2ecf20Sopenharmony_ci u64 search_start, search_bytes; 19848c2ecf20Sopenharmony_ci int ret; 19858c2ecf20Sopenharmony_ci 19868c2ecf20Sopenharmony_ciagain: 19878c2ecf20Sopenharmony_ci end = bitmap_info->offset + (u64)(BITS_PER_BITMAP * ctl->unit) - 1; 19888c2ecf20Sopenharmony_ci 19898c2ecf20Sopenharmony_ci /* 19908c2ecf20Sopenharmony_ci * We need to search for bits in this bitmap. We could only cover some 19918c2ecf20Sopenharmony_ci * of the extent in this bitmap thanks to how we add space, so we need 19928c2ecf20Sopenharmony_ci * to search for as much as it as we can and clear that amount, and then 19938c2ecf20Sopenharmony_ci * go searching for the next bit. 19948c2ecf20Sopenharmony_ci */ 19958c2ecf20Sopenharmony_ci search_start = *offset; 19968c2ecf20Sopenharmony_ci search_bytes = ctl->unit; 19978c2ecf20Sopenharmony_ci search_bytes = min(search_bytes, end - search_start + 1); 19988c2ecf20Sopenharmony_ci ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes, 19998c2ecf20Sopenharmony_ci false); 20008c2ecf20Sopenharmony_ci if (ret < 0 || search_start != *offset) 20018c2ecf20Sopenharmony_ci return -EINVAL; 20028c2ecf20Sopenharmony_ci 20038c2ecf20Sopenharmony_ci /* We may have found more bits than what we need */ 20048c2ecf20Sopenharmony_ci search_bytes = min(search_bytes, *bytes); 20058c2ecf20Sopenharmony_ci 20068c2ecf20Sopenharmony_ci /* Cannot clear past the end of the bitmap */ 20078c2ecf20Sopenharmony_ci search_bytes = min(search_bytes, end - search_start + 1); 20088c2ecf20Sopenharmony_ci 20098c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, bitmap_info, search_start, search_bytes); 20108c2ecf20Sopenharmony_ci *offset += search_bytes; 20118c2ecf20Sopenharmony_ci *bytes -= search_bytes; 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_ci if (*bytes) { 20148c2ecf20Sopenharmony_ci struct rb_node *next = rb_next(&bitmap_info->offset_index); 20158c2ecf20Sopenharmony_ci if (!bitmap_info->bytes) 20168c2ecf20Sopenharmony_ci free_bitmap(ctl, bitmap_info); 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci /* 20198c2ecf20Sopenharmony_ci * no entry after this bitmap, but we still have bytes to 20208c2ecf20Sopenharmony_ci * remove, so something has gone wrong. 20218c2ecf20Sopenharmony_ci */ 20228c2ecf20Sopenharmony_ci if (!next) 20238c2ecf20Sopenharmony_ci return -EINVAL; 20248c2ecf20Sopenharmony_ci 20258c2ecf20Sopenharmony_ci bitmap_info = rb_entry(next, struct btrfs_free_space, 20268c2ecf20Sopenharmony_ci offset_index); 20278c2ecf20Sopenharmony_ci 20288c2ecf20Sopenharmony_ci /* 20298c2ecf20Sopenharmony_ci * if the next entry isn't a bitmap we need to return to let the 20308c2ecf20Sopenharmony_ci * extent stuff do its work. 20318c2ecf20Sopenharmony_ci */ 20328c2ecf20Sopenharmony_ci if (!bitmap_info->bitmap) 20338c2ecf20Sopenharmony_ci return -EAGAIN; 20348c2ecf20Sopenharmony_ci 20358c2ecf20Sopenharmony_ci /* 20368c2ecf20Sopenharmony_ci * Ok the next item is a bitmap, but it may not actually hold 20378c2ecf20Sopenharmony_ci * the information for the rest of this free space stuff, so 20388c2ecf20Sopenharmony_ci * look for it, and if we don't find it return so we can try 20398c2ecf20Sopenharmony_ci * everything over again. 20408c2ecf20Sopenharmony_ci */ 20418c2ecf20Sopenharmony_ci search_start = *offset; 20428c2ecf20Sopenharmony_ci search_bytes = ctl->unit; 20438c2ecf20Sopenharmony_ci ret = search_bitmap(ctl, bitmap_info, &search_start, 20448c2ecf20Sopenharmony_ci &search_bytes, false); 20458c2ecf20Sopenharmony_ci if (ret < 0 || search_start != *offset) 20468c2ecf20Sopenharmony_ci return -EAGAIN; 20478c2ecf20Sopenharmony_ci 20488c2ecf20Sopenharmony_ci goto again; 20498c2ecf20Sopenharmony_ci } else if (!bitmap_info->bytes) 20508c2ecf20Sopenharmony_ci free_bitmap(ctl, bitmap_info); 20518c2ecf20Sopenharmony_ci 20528c2ecf20Sopenharmony_ci return 0; 20538c2ecf20Sopenharmony_ci} 20548c2ecf20Sopenharmony_ci 20558c2ecf20Sopenharmony_cistatic u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl, 20568c2ecf20Sopenharmony_ci struct btrfs_free_space *info, u64 offset, 20578c2ecf20Sopenharmony_ci u64 bytes, enum btrfs_trim_state trim_state) 20588c2ecf20Sopenharmony_ci{ 20598c2ecf20Sopenharmony_ci u64 bytes_to_set = 0; 20608c2ecf20Sopenharmony_ci u64 end; 20618c2ecf20Sopenharmony_ci 20628c2ecf20Sopenharmony_ci /* 20638c2ecf20Sopenharmony_ci * This is a tradeoff to make bitmap trim state minimal. We mark the 20648c2ecf20Sopenharmony_ci * whole bitmap untrimmed if at any point we add untrimmed regions. 20658c2ecf20Sopenharmony_ci */ 20668c2ecf20Sopenharmony_ci if (trim_state == BTRFS_TRIM_STATE_UNTRIMMED) { 20678c2ecf20Sopenharmony_ci if (btrfs_free_space_trimmed(info)) { 20688c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] += 20698c2ecf20Sopenharmony_ci info->bitmap_extents; 20708c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += info->bytes; 20718c2ecf20Sopenharmony_ci } 20728c2ecf20Sopenharmony_ci info->trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 20738c2ecf20Sopenharmony_ci } 20748c2ecf20Sopenharmony_ci 20758c2ecf20Sopenharmony_ci end = info->offset + (u64)(BITS_PER_BITMAP * ctl->unit); 20768c2ecf20Sopenharmony_ci 20778c2ecf20Sopenharmony_ci bytes_to_set = min(end - offset, bytes); 20788c2ecf20Sopenharmony_ci 20798c2ecf20Sopenharmony_ci bitmap_set_bits(ctl, info, offset, bytes_to_set); 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_ci /* 20828c2ecf20Sopenharmony_ci * We set some bytes, we have no idea what the max extent size is 20838c2ecf20Sopenharmony_ci * anymore. 20848c2ecf20Sopenharmony_ci */ 20858c2ecf20Sopenharmony_ci info->max_extent_size = 0; 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci return bytes_to_set; 20888c2ecf20Sopenharmony_ci 20898c2ecf20Sopenharmony_ci} 20908c2ecf20Sopenharmony_ci 20918c2ecf20Sopenharmony_cistatic bool use_bitmap(struct btrfs_free_space_ctl *ctl, 20928c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 20938c2ecf20Sopenharmony_ci{ 20948c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group = ctl->private; 20958c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 20968c2ecf20Sopenharmony_ci bool forced = false; 20978c2ecf20Sopenharmony_ci 20988c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_DEBUG 20998c2ecf20Sopenharmony_ci if (btrfs_should_fragment_free_space(block_group)) 21008c2ecf20Sopenharmony_ci forced = true; 21018c2ecf20Sopenharmony_ci#endif 21028c2ecf20Sopenharmony_ci 21038c2ecf20Sopenharmony_ci /* This is a way to reclaim large regions from the bitmaps. */ 21048c2ecf20Sopenharmony_ci if (!forced && info->bytes >= FORCE_EXTENT_THRESHOLD) 21058c2ecf20Sopenharmony_ci return false; 21068c2ecf20Sopenharmony_ci 21078c2ecf20Sopenharmony_ci /* 21088c2ecf20Sopenharmony_ci * If we are below the extents threshold then we can add this as an 21098c2ecf20Sopenharmony_ci * extent, and don't have to deal with the bitmap 21108c2ecf20Sopenharmony_ci */ 21118c2ecf20Sopenharmony_ci if (!forced && ctl->free_extents < ctl->extents_thresh) { 21128c2ecf20Sopenharmony_ci /* 21138c2ecf20Sopenharmony_ci * If this block group has some small extents we don't want to 21148c2ecf20Sopenharmony_ci * use up all of our free slots in the cache with them, we want 21158c2ecf20Sopenharmony_ci * to reserve them to larger extents, however if we have plenty 21168c2ecf20Sopenharmony_ci * of cache left then go ahead an dadd them, no sense in adding 21178c2ecf20Sopenharmony_ci * the overhead of a bitmap if we don't have to. 21188c2ecf20Sopenharmony_ci */ 21198c2ecf20Sopenharmony_ci if (info->bytes <= fs_info->sectorsize * 8) { 21208c2ecf20Sopenharmony_ci if (ctl->free_extents * 3 <= ctl->extents_thresh) 21218c2ecf20Sopenharmony_ci return false; 21228c2ecf20Sopenharmony_ci } else { 21238c2ecf20Sopenharmony_ci return false; 21248c2ecf20Sopenharmony_ci } 21258c2ecf20Sopenharmony_ci } 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_ci /* 21288c2ecf20Sopenharmony_ci * The original block groups from mkfs can be really small, like 8 21298c2ecf20Sopenharmony_ci * megabytes, so don't bother with a bitmap for those entries. However 21308c2ecf20Sopenharmony_ci * some block groups can be smaller than what a bitmap would cover but 21318c2ecf20Sopenharmony_ci * are still large enough that they could overflow the 32k memory limit, 21328c2ecf20Sopenharmony_ci * so allow those block groups to still be allowed to have a bitmap 21338c2ecf20Sopenharmony_ci * entry. 21348c2ecf20Sopenharmony_ci */ 21358c2ecf20Sopenharmony_ci if (((BITS_PER_BITMAP * ctl->unit) >> 1) > block_group->length) 21368c2ecf20Sopenharmony_ci return false; 21378c2ecf20Sopenharmony_ci 21388c2ecf20Sopenharmony_ci return true; 21398c2ecf20Sopenharmony_ci} 21408c2ecf20Sopenharmony_ci 21418c2ecf20Sopenharmony_cistatic const struct btrfs_free_space_op free_space_op = { 21428c2ecf20Sopenharmony_ci .recalc_thresholds = recalculate_thresholds, 21438c2ecf20Sopenharmony_ci .use_bitmap = use_bitmap, 21448c2ecf20Sopenharmony_ci}; 21458c2ecf20Sopenharmony_ci 21468c2ecf20Sopenharmony_cistatic int insert_into_bitmap(struct btrfs_free_space_ctl *ctl, 21478c2ecf20Sopenharmony_ci struct btrfs_free_space *info) 21488c2ecf20Sopenharmony_ci{ 21498c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap_info; 21508c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group = NULL; 21518c2ecf20Sopenharmony_ci int added = 0; 21528c2ecf20Sopenharmony_ci u64 bytes, offset, bytes_added; 21538c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state; 21548c2ecf20Sopenharmony_ci int ret; 21558c2ecf20Sopenharmony_ci 21568c2ecf20Sopenharmony_ci bytes = info->bytes; 21578c2ecf20Sopenharmony_ci offset = info->offset; 21588c2ecf20Sopenharmony_ci trim_state = info->trim_state; 21598c2ecf20Sopenharmony_ci 21608c2ecf20Sopenharmony_ci if (!ctl->op->use_bitmap(ctl, info)) 21618c2ecf20Sopenharmony_ci return 0; 21628c2ecf20Sopenharmony_ci 21638c2ecf20Sopenharmony_ci if (ctl->op == &free_space_op) 21648c2ecf20Sopenharmony_ci block_group = ctl->private; 21658c2ecf20Sopenharmony_ciagain: 21668c2ecf20Sopenharmony_ci /* 21678c2ecf20Sopenharmony_ci * Since we link bitmaps right into the cluster we need to see if we 21688c2ecf20Sopenharmony_ci * have a cluster here, and if so and it has our bitmap we need to add 21698c2ecf20Sopenharmony_ci * the free space to that bitmap. 21708c2ecf20Sopenharmony_ci */ 21718c2ecf20Sopenharmony_ci if (block_group && !list_empty(&block_group->cluster_list)) { 21728c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster; 21738c2ecf20Sopenharmony_ci struct rb_node *node; 21748c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 21758c2ecf20Sopenharmony_ci 21768c2ecf20Sopenharmony_ci cluster = list_entry(block_group->cluster_list.next, 21778c2ecf20Sopenharmony_ci struct btrfs_free_cluster, 21788c2ecf20Sopenharmony_ci block_group_list); 21798c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 21808c2ecf20Sopenharmony_ci node = rb_first(&cluster->root); 21818c2ecf20Sopenharmony_ci if (!node) { 21828c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 21838c2ecf20Sopenharmony_ci goto no_cluster_bitmap; 21848c2ecf20Sopenharmony_ci } 21858c2ecf20Sopenharmony_ci 21868c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 21878c2ecf20Sopenharmony_ci if (!entry->bitmap) { 21888c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 21898c2ecf20Sopenharmony_ci goto no_cluster_bitmap; 21908c2ecf20Sopenharmony_ci } 21918c2ecf20Sopenharmony_ci 21928c2ecf20Sopenharmony_ci if (entry->offset == offset_to_bitmap(ctl, offset)) { 21938c2ecf20Sopenharmony_ci bytes_added = add_bytes_to_bitmap(ctl, entry, offset, 21948c2ecf20Sopenharmony_ci bytes, trim_state); 21958c2ecf20Sopenharmony_ci bytes -= bytes_added; 21968c2ecf20Sopenharmony_ci offset += bytes_added; 21978c2ecf20Sopenharmony_ci } 21988c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 21998c2ecf20Sopenharmony_ci if (!bytes) { 22008c2ecf20Sopenharmony_ci ret = 1; 22018c2ecf20Sopenharmony_ci goto out; 22028c2ecf20Sopenharmony_ci } 22038c2ecf20Sopenharmony_ci } 22048c2ecf20Sopenharmony_ci 22058c2ecf20Sopenharmony_cino_cluster_bitmap: 22068c2ecf20Sopenharmony_ci bitmap_info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 22078c2ecf20Sopenharmony_ci 1, 0); 22088c2ecf20Sopenharmony_ci if (!bitmap_info) { 22098c2ecf20Sopenharmony_ci ASSERT(added == 0); 22108c2ecf20Sopenharmony_ci goto new_bitmap; 22118c2ecf20Sopenharmony_ci } 22128c2ecf20Sopenharmony_ci 22138c2ecf20Sopenharmony_ci bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes, 22148c2ecf20Sopenharmony_ci trim_state); 22158c2ecf20Sopenharmony_ci bytes -= bytes_added; 22168c2ecf20Sopenharmony_ci offset += bytes_added; 22178c2ecf20Sopenharmony_ci added = 0; 22188c2ecf20Sopenharmony_ci 22198c2ecf20Sopenharmony_ci if (!bytes) { 22208c2ecf20Sopenharmony_ci ret = 1; 22218c2ecf20Sopenharmony_ci goto out; 22228c2ecf20Sopenharmony_ci } else 22238c2ecf20Sopenharmony_ci goto again; 22248c2ecf20Sopenharmony_ci 22258c2ecf20Sopenharmony_cinew_bitmap: 22268c2ecf20Sopenharmony_ci if (info && info->bitmap) { 22278c2ecf20Sopenharmony_ci add_new_bitmap(ctl, info, offset); 22288c2ecf20Sopenharmony_ci added = 1; 22298c2ecf20Sopenharmony_ci info = NULL; 22308c2ecf20Sopenharmony_ci goto again; 22318c2ecf20Sopenharmony_ci } else { 22328c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 22338c2ecf20Sopenharmony_ci 22348c2ecf20Sopenharmony_ci /* no pre-allocated info, allocate a new one */ 22358c2ecf20Sopenharmony_ci if (!info) { 22368c2ecf20Sopenharmony_ci info = kmem_cache_zalloc(btrfs_free_space_cachep, 22378c2ecf20Sopenharmony_ci GFP_NOFS); 22388c2ecf20Sopenharmony_ci if (!info) { 22398c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 22408c2ecf20Sopenharmony_ci ret = -ENOMEM; 22418c2ecf20Sopenharmony_ci goto out; 22428c2ecf20Sopenharmony_ci } 22438c2ecf20Sopenharmony_ci } 22448c2ecf20Sopenharmony_ci 22458c2ecf20Sopenharmony_ci /* allocate the bitmap */ 22468c2ecf20Sopenharmony_ci info->bitmap = kmem_cache_zalloc(btrfs_free_space_bitmap_cachep, 22478c2ecf20Sopenharmony_ci GFP_NOFS); 22488c2ecf20Sopenharmony_ci info->trim_state = BTRFS_TRIM_STATE_TRIMMED; 22498c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 22508c2ecf20Sopenharmony_ci if (!info->bitmap) { 22518c2ecf20Sopenharmony_ci ret = -ENOMEM; 22528c2ecf20Sopenharmony_ci goto out; 22538c2ecf20Sopenharmony_ci } 22548c2ecf20Sopenharmony_ci goto again; 22558c2ecf20Sopenharmony_ci } 22568c2ecf20Sopenharmony_ci 22578c2ecf20Sopenharmony_ciout: 22588c2ecf20Sopenharmony_ci if (info) { 22598c2ecf20Sopenharmony_ci if (info->bitmap) 22608c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_bitmap_cachep, 22618c2ecf20Sopenharmony_ci info->bitmap); 22628c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 22638c2ecf20Sopenharmony_ci } 22648c2ecf20Sopenharmony_ci 22658c2ecf20Sopenharmony_ci return ret; 22668c2ecf20Sopenharmony_ci} 22678c2ecf20Sopenharmony_ci 22688c2ecf20Sopenharmony_ci/* 22698c2ecf20Sopenharmony_ci * Free space merging rules: 22708c2ecf20Sopenharmony_ci * 1) Merge trimmed areas together 22718c2ecf20Sopenharmony_ci * 2) Let untrimmed areas coalesce with trimmed areas 22728c2ecf20Sopenharmony_ci * 3) Always pull neighboring regions from bitmaps 22738c2ecf20Sopenharmony_ci * 22748c2ecf20Sopenharmony_ci * The above rules are for when we merge free space based on btrfs_trim_state. 22758c2ecf20Sopenharmony_ci * Rules 2 and 3 are subtle because they are suboptimal, but are done for the 22768c2ecf20Sopenharmony_ci * same reason: to promote larger extent regions which makes life easier for 22778c2ecf20Sopenharmony_ci * find_free_extent(). Rule 2 enables coalescing based on the common path 22788c2ecf20Sopenharmony_ci * being returning free space from btrfs_finish_extent_commit(). So when free 22798c2ecf20Sopenharmony_ci * space is trimmed, it will prevent aggregating trimmed new region and 22808c2ecf20Sopenharmony_ci * untrimmed regions in the rb_tree. Rule 3 is purely to obtain larger extents 22818c2ecf20Sopenharmony_ci * and provide find_free_extent() with the largest extents possible hoping for 22828c2ecf20Sopenharmony_ci * the reuse path. 22838c2ecf20Sopenharmony_ci */ 22848c2ecf20Sopenharmony_cistatic bool try_merge_free_space(struct btrfs_free_space_ctl *ctl, 22858c2ecf20Sopenharmony_ci struct btrfs_free_space *info, bool update_stat) 22868c2ecf20Sopenharmony_ci{ 22878c2ecf20Sopenharmony_ci struct btrfs_free_space *left_info = NULL; 22888c2ecf20Sopenharmony_ci struct btrfs_free_space *right_info; 22898c2ecf20Sopenharmony_ci bool merged = false; 22908c2ecf20Sopenharmony_ci u64 offset = info->offset; 22918c2ecf20Sopenharmony_ci u64 bytes = info->bytes; 22928c2ecf20Sopenharmony_ci const bool is_trimmed = btrfs_free_space_trimmed(info); 22938c2ecf20Sopenharmony_ci 22948c2ecf20Sopenharmony_ci /* 22958c2ecf20Sopenharmony_ci * first we want to see if there is free space adjacent to the range we 22968c2ecf20Sopenharmony_ci * are adding, if there is remove that struct and add a new one to 22978c2ecf20Sopenharmony_ci * cover the entire range 22988c2ecf20Sopenharmony_ci */ 22998c2ecf20Sopenharmony_ci right_info = tree_search_offset(ctl, offset + bytes, 0, 0); 23008c2ecf20Sopenharmony_ci if (right_info && rb_prev(&right_info->offset_index)) 23018c2ecf20Sopenharmony_ci left_info = rb_entry(rb_prev(&right_info->offset_index), 23028c2ecf20Sopenharmony_ci struct btrfs_free_space, offset_index); 23038c2ecf20Sopenharmony_ci else if (!right_info) 23048c2ecf20Sopenharmony_ci left_info = tree_search_offset(ctl, offset - 1, 0, 0); 23058c2ecf20Sopenharmony_ci 23068c2ecf20Sopenharmony_ci /* See try_merge_free_space() comment. */ 23078c2ecf20Sopenharmony_ci if (right_info && !right_info->bitmap && 23088c2ecf20Sopenharmony_ci (!is_trimmed || btrfs_free_space_trimmed(right_info))) { 23098c2ecf20Sopenharmony_ci if (update_stat) 23108c2ecf20Sopenharmony_ci unlink_free_space(ctl, right_info); 23118c2ecf20Sopenharmony_ci else 23128c2ecf20Sopenharmony_ci __unlink_free_space(ctl, right_info); 23138c2ecf20Sopenharmony_ci info->bytes += right_info->bytes; 23148c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, right_info); 23158c2ecf20Sopenharmony_ci merged = true; 23168c2ecf20Sopenharmony_ci } 23178c2ecf20Sopenharmony_ci 23188c2ecf20Sopenharmony_ci /* See try_merge_free_space() comment. */ 23198c2ecf20Sopenharmony_ci if (left_info && !left_info->bitmap && 23208c2ecf20Sopenharmony_ci left_info->offset + left_info->bytes == offset && 23218c2ecf20Sopenharmony_ci (!is_trimmed || btrfs_free_space_trimmed(left_info))) { 23228c2ecf20Sopenharmony_ci if (update_stat) 23238c2ecf20Sopenharmony_ci unlink_free_space(ctl, left_info); 23248c2ecf20Sopenharmony_ci else 23258c2ecf20Sopenharmony_ci __unlink_free_space(ctl, left_info); 23268c2ecf20Sopenharmony_ci info->offset = left_info->offset; 23278c2ecf20Sopenharmony_ci info->bytes += left_info->bytes; 23288c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, left_info); 23298c2ecf20Sopenharmony_ci merged = true; 23308c2ecf20Sopenharmony_ci } 23318c2ecf20Sopenharmony_ci 23328c2ecf20Sopenharmony_ci return merged; 23338c2ecf20Sopenharmony_ci} 23348c2ecf20Sopenharmony_ci 23358c2ecf20Sopenharmony_cistatic bool steal_from_bitmap_to_end(struct btrfs_free_space_ctl *ctl, 23368c2ecf20Sopenharmony_ci struct btrfs_free_space *info, 23378c2ecf20Sopenharmony_ci bool update_stat) 23388c2ecf20Sopenharmony_ci{ 23398c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap; 23408c2ecf20Sopenharmony_ci unsigned long i; 23418c2ecf20Sopenharmony_ci unsigned long j; 23428c2ecf20Sopenharmony_ci const u64 end = info->offset + info->bytes; 23438c2ecf20Sopenharmony_ci const u64 bitmap_offset = offset_to_bitmap(ctl, end); 23448c2ecf20Sopenharmony_ci u64 bytes; 23458c2ecf20Sopenharmony_ci 23468c2ecf20Sopenharmony_ci bitmap = tree_search_offset(ctl, bitmap_offset, 1, 0); 23478c2ecf20Sopenharmony_ci if (!bitmap) 23488c2ecf20Sopenharmony_ci return false; 23498c2ecf20Sopenharmony_ci 23508c2ecf20Sopenharmony_ci i = offset_to_bit(bitmap->offset, ctl->unit, end); 23518c2ecf20Sopenharmony_ci j = find_next_zero_bit(bitmap->bitmap, BITS_PER_BITMAP, i); 23528c2ecf20Sopenharmony_ci if (j == i) 23538c2ecf20Sopenharmony_ci return false; 23548c2ecf20Sopenharmony_ci bytes = (j - i) * ctl->unit; 23558c2ecf20Sopenharmony_ci info->bytes += bytes; 23568c2ecf20Sopenharmony_ci 23578c2ecf20Sopenharmony_ci /* See try_merge_free_space() comment. */ 23588c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(bitmap)) 23598c2ecf20Sopenharmony_ci info->trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 23608c2ecf20Sopenharmony_ci 23618c2ecf20Sopenharmony_ci if (update_stat) 23628c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, bitmap, end, bytes); 23638c2ecf20Sopenharmony_ci else 23648c2ecf20Sopenharmony_ci __bitmap_clear_bits(ctl, bitmap, end, bytes); 23658c2ecf20Sopenharmony_ci 23668c2ecf20Sopenharmony_ci if (!bitmap->bytes) 23678c2ecf20Sopenharmony_ci free_bitmap(ctl, bitmap); 23688c2ecf20Sopenharmony_ci 23698c2ecf20Sopenharmony_ci return true; 23708c2ecf20Sopenharmony_ci} 23718c2ecf20Sopenharmony_ci 23728c2ecf20Sopenharmony_cistatic bool steal_from_bitmap_to_front(struct btrfs_free_space_ctl *ctl, 23738c2ecf20Sopenharmony_ci struct btrfs_free_space *info, 23748c2ecf20Sopenharmony_ci bool update_stat) 23758c2ecf20Sopenharmony_ci{ 23768c2ecf20Sopenharmony_ci struct btrfs_free_space *bitmap; 23778c2ecf20Sopenharmony_ci u64 bitmap_offset; 23788c2ecf20Sopenharmony_ci unsigned long i; 23798c2ecf20Sopenharmony_ci unsigned long j; 23808c2ecf20Sopenharmony_ci unsigned long prev_j; 23818c2ecf20Sopenharmony_ci u64 bytes; 23828c2ecf20Sopenharmony_ci 23838c2ecf20Sopenharmony_ci bitmap_offset = offset_to_bitmap(ctl, info->offset); 23848c2ecf20Sopenharmony_ci /* If we're on a boundary, try the previous logical bitmap. */ 23858c2ecf20Sopenharmony_ci if (bitmap_offset == info->offset) { 23868c2ecf20Sopenharmony_ci if (info->offset == 0) 23878c2ecf20Sopenharmony_ci return false; 23888c2ecf20Sopenharmony_ci bitmap_offset = offset_to_bitmap(ctl, info->offset - 1); 23898c2ecf20Sopenharmony_ci } 23908c2ecf20Sopenharmony_ci 23918c2ecf20Sopenharmony_ci bitmap = tree_search_offset(ctl, bitmap_offset, 1, 0); 23928c2ecf20Sopenharmony_ci if (!bitmap) 23938c2ecf20Sopenharmony_ci return false; 23948c2ecf20Sopenharmony_ci 23958c2ecf20Sopenharmony_ci i = offset_to_bit(bitmap->offset, ctl->unit, info->offset) - 1; 23968c2ecf20Sopenharmony_ci j = 0; 23978c2ecf20Sopenharmony_ci prev_j = (unsigned long)-1; 23988c2ecf20Sopenharmony_ci for_each_clear_bit_from(j, bitmap->bitmap, BITS_PER_BITMAP) { 23998c2ecf20Sopenharmony_ci if (j > i) 24008c2ecf20Sopenharmony_ci break; 24018c2ecf20Sopenharmony_ci prev_j = j; 24028c2ecf20Sopenharmony_ci } 24038c2ecf20Sopenharmony_ci if (prev_j == i) 24048c2ecf20Sopenharmony_ci return false; 24058c2ecf20Sopenharmony_ci 24068c2ecf20Sopenharmony_ci if (prev_j == (unsigned long)-1) 24078c2ecf20Sopenharmony_ci bytes = (i + 1) * ctl->unit; 24088c2ecf20Sopenharmony_ci else 24098c2ecf20Sopenharmony_ci bytes = (i - prev_j) * ctl->unit; 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci info->offset -= bytes; 24128c2ecf20Sopenharmony_ci info->bytes += bytes; 24138c2ecf20Sopenharmony_ci 24148c2ecf20Sopenharmony_ci /* See try_merge_free_space() comment. */ 24158c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(bitmap)) 24168c2ecf20Sopenharmony_ci info->trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 24178c2ecf20Sopenharmony_ci 24188c2ecf20Sopenharmony_ci if (update_stat) 24198c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, bitmap, info->offset, bytes); 24208c2ecf20Sopenharmony_ci else 24218c2ecf20Sopenharmony_ci __bitmap_clear_bits(ctl, bitmap, info->offset, bytes); 24228c2ecf20Sopenharmony_ci 24238c2ecf20Sopenharmony_ci if (!bitmap->bytes) 24248c2ecf20Sopenharmony_ci free_bitmap(ctl, bitmap); 24258c2ecf20Sopenharmony_ci 24268c2ecf20Sopenharmony_ci return true; 24278c2ecf20Sopenharmony_ci} 24288c2ecf20Sopenharmony_ci 24298c2ecf20Sopenharmony_ci/* 24308c2ecf20Sopenharmony_ci * We prefer always to allocate from extent entries, both for clustered and 24318c2ecf20Sopenharmony_ci * non-clustered allocation requests. So when attempting to add a new extent 24328c2ecf20Sopenharmony_ci * entry, try to see if there's adjacent free space in bitmap entries, and if 24338c2ecf20Sopenharmony_ci * there is, migrate that space from the bitmaps to the extent. 24348c2ecf20Sopenharmony_ci * Like this we get better chances of satisfying space allocation requests 24358c2ecf20Sopenharmony_ci * because we attempt to satisfy them based on a single cache entry, and never 24368c2ecf20Sopenharmony_ci * on 2 or more entries - even if the entries represent a contiguous free space 24378c2ecf20Sopenharmony_ci * region (e.g. 1 extent entry + 1 bitmap entry starting where the extent entry 24388c2ecf20Sopenharmony_ci * ends). 24398c2ecf20Sopenharmony_ci */ 24408c2ecf20Sopenharmony_cistatic void steal_from_bitmap(struct btrfs_free_space_ctl *ctl, 24418c2ecf20Sopenharmony_ci struct btrfs_free_space *info, 24428c2ecf20Sopenharmony_ci bool update_stat) 24438c2ecf20Sopenharmony_ci{ 24448c2ecf20Sopenharmony_ci /* 24458c2ecf20Sopenharmony_ci * Only work with disconnected entries, as we can change their offset, 24468c2ecf20Sopenharmony_ci * and must be extent entries. 24478c2ecf20Sopenharmony_ci */ 24488c2ecf20Sopenharmony_ci ASSERT(!info->bitmap); 24498c2ecf20Sopenharmony_ci ASSERT(RB_EMPTY_NODE(&info->offset_index)); 24508c2ecf20Sopenharmony_ci 24518c2ecf20Sopenharmony_ci if (ctl->total_bitmaps > 0) { 24528c2ecf20Sopenharmony_ci bool stole_end; 24538c2ecf20Sopenharmony_ci bool stole_front = false; 24548c2ecf20Sopenharmony_ci 24558c2ecf20Sopenharmony_ci stole_end = steal_from_bitmap_to_end(ctl, info, update_stat); 24568c2ecf20Sopenharmony_ci if (ctl->total_bitmaps > 0) 24578c2ecf20Sopenharmony_ci stole_front = steal_from_bitmap_to_front(ctl, info, 24588c2ecf20Sopenharmony_ci update_stat); 24598c2ecf20Sopenharmony_ci 24608c2ecf20Sopenharmony_ci if (stole_end || stole_front) 24618c2ecf20Sopenharmony_ci try_merge_free_space(ctl, info, update_stat); 24628c2ecf20Sopenharmony_ci } 24638c2ecf20Sopenharmony_ci} 24648c2ecf20Sopenharmony_ci 24658c2ecf20Sopenharmony_ciint __btrfs_add_free_space(struct btrfs_fs_info *fs_info, 24668c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl, 24678c2ecf20Sopenharmony_ci u64 offset, u64 bytes, 24688c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state) 24698c2ecf20Sopenharmony_ci{ 24708c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group = ctl->private; 24718c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 24728c2ecf20Sopenharmony_ci int ret = 0; 24738c2ecf20Sopenharmony_ci u64 filter_bytes = bytes; 24748c2ecf20Sopenharmony_ci 24758c2ecf20Sopenharmony_ci info = kmem_cache_zalloc(btrfs_free_space_cachep, GFP_NOFS); 24768c2ecf20Sopenharmony_ci if (!info) 24778c2ecf20Sopenharmony_ci return -ENOMEM; 24788c2ecf20Sopenharmony_ci 24798c2ecf20Sopenharmony_ci info->offset = offset; 24808c2ecf20Sopenharmony_ci info->bytes = bytes; 24818c2ecf20Sopenharmony_ci info->trim_state = trim_state; 24828c2ecf20Sopenharmony_ci RB_CLEAR_NODE(&info->offset_index); 24838c2ecf20Sopenharmony_ci 24848c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 24858c2ecf20Sopenharmony_ci 24868c2ecf20Sopenharmony_ci if (try_merge_free_space(ctl, info, true)) 24878c2ecf20Sopenharmony_ci goto link; 24888c2ecf20Sopenharmony_ci 24898c2ecf20Sopenharmony_ci /* 24908c2ecf20Sopenharmony_ci * There was no extent directly to the left or right of this new 24918c2ecf20Sopenharmony_ci * extent then we know we're going to have to allocate a new extent, so 24928c2ecf20Sopenharmony_ci * before we do that see if we need to drop this into a bitmap 24938c2ecf20Sopenharmony_ci */ 24948c2ecf20Sopenharmony_ci ret = insert_into_bitmap(ctl, info); 24958c2ecf20Sopenharmony_ci if (ret < 0) { 24968c2ecf20Sopenharmony_ci goto out; 24978c2ecf20Sopenharmony_ci } else if (ret) { 24988c2ecf20Sopenharmony_ci ret = 0; 24998c2ecf20Sopenharmony_ci goto out; 25008c2ecf20Sopenharmony_ci } 25018c2ecf20Sopenharmony_cilink: 25028c2ecf20Sopenharmony_ci /* 25038c2ecf20Sopenharmony_ci * Only steal free space from adjacent bitmaps if we're sure we're not 25048c2ecf20Sopenharmony_ci * going to add the new free space to existing bitmap entries - because 25058c2ecf20Sopenharmony_ci * that would mean unnecessary work that would be reverted. Therefore 25068c2ecf20Sopenharmony_ci * attempt to steal space from bitmaps if we're adding an extent entry. 25078c2ecf20Sopenharmony_ci */ 25088c2ecf20Sopenharmony_ci steal_from_bitmap(ctl, info, true); 25098c2ecf20Sopenharmony_ci 25108c2ecf20Sopenharmony_ci filter_bytes = max(filter_bytes, info->bytes); 25118c2ecf20Sopenharmony_ci 25128c2ecf20Sopenharmony_ci ret = link_free_space(ctl, info); 25138c2ecf20Sopenharmony_ci if (ret) 25148c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 25158c2ecf20Sopenharmony_ciout: 25168c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(block_group, ctl); 25178c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 25188c2ecf20Sopenharmony_ci 25198c2ecf20Sopenharmony_ci if (ret) { 25208c2ecf20Sopenharmony_ci btrfs_crit(fs_info, "unable to add free space :%d", ret); 25218c2ecf20Sopenharmony_ci ASSERT(ret != -EEXIST); 25228c2ecf20Sopenharmony_ci } 25238c2ecf20Sopenharmony_ci 25248c2ecf20Sopenharmony_ci if (trim_state != BTRFS_TRIM_STATE_TRIMMED) { 25258c2ecf20Sopenharmony_ci btrfs_discard_check_filter(block_group, filter_bytes); 25268c2ecf20Sopenharmony_ci btrfs_discard_queue_work(&fs_info->discard_ctl, block_group); 25278c2ecf20Sopenharmony_ci } 25288c2ecf20Sopenharmony_ci 25298c2ecf20Sopenharmony_ci return ret; 25308c2ecf20Sopenharmony_ci} 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_ciint btrfs_add_free_space(struct btrfs_block_group *block_group, 25338c2ecf20Sopenharmony_ci u64 bytenr, u64 size) 25348c2ecf20Sopenharmony_ci{ 25358c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 25368c2ecf20Sopenharmony_ci 25378c2ecf20Sopenharmony_ci if (btrfs_test_opt(block_group->fs_info, DISCARD_SYNC)) 25388c2ecf20Sopenharmony_ci trim_state = BTRFS_TRIM_STATE_TRIMMED; 25398c2ecf20Sopenharmony_ci 25408c2ecf20Sopenharmony_ci return __btrfs_add_free_space(block_group->fs_info, 25418c2ecf20Sopenharmony_ci block_group->free_space_ctl, 25428c2ecf20Sopenharmony_ci bytenr, size, trim_state); 25438c2ecf20Sopenharmony_ci} 25448c2ecf20Sopenharmony_ci 25458c2ecf20Sopenharmony_ci/* 25468c2ecf20Sopenharmony_ci * This is a subtle distinction because when adding free space back in general, 25478c2ecf20Sopenharmony_ci * we want it to be added as untrimmed for async. But in the case where we add 25488c2ecf20Sopenharmony_ci * it on loading of a block group, we want to consider it trimmed. 25498c2ecf20Sopenharmony_ci */ 25508c2ecf20Sopenharmony_ciint btrfs_add_free_space_async_trimmed(struct btrfs_block_group *block_group, 25518c2ecf20Sopenharmony_ci u64 bytenr, u64 size) 25528c2ecf20Sopenharmony_ci{ 25538c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci if (btrfs_test_opt(block_group->fs_info, DISCARD_SYNC) || 25568c2ecf20Sopenharmony_ci btrfs_test_opt(block_group->fs_info, DISCARD_ASYNC)) 25578c2ecf20Sopenharmony_ci trim_state = BTRFS_TRIM_STATE_TRIMMED; 25588c2ecf20Sopenharmony_ci 25598c2ecf20Sopenharmony_ci return __btrfs_add_free_space(block_group->fs_info, 25608c2ecf20Sopenharmony_ci block_group->free_space_ctl, 25618c2ecf20Sopenharmony_ci bytenr, size, trim_state); 25628c2ecf20Sopenharmony_ci} 25638c2ecf20Sopenharmony_ci 25648c2ecf20Sopenharmony_ciint btrfs_remove_free_space(struct btrfs_block_group *block_group, 25658c2ecf20Sopenharmony_ci u64 offset, u64 bytes) 25668c2ecf20Sopenharmony_ci{ 25678c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 25688c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 25698c2ecf20Sopenharmony_ci int ret; 25708c2ecf20Sopenharmony_ci bool re_search = false; 25718c2ecf20Sopenharmony_ci 25728c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 25738c2ecf20Sopenharmony_ci 25748c2ecf20Sopenharmony_ciagain: 25758c2ecf20Sopenharmony_ci ret = 0; 25768c2ecf20Sopenharmony_ci if (!bytes) 25778c2ecf20Sopenharmony_ci goto out_lock; 25788c2ecf20Sopenharmony_ci 25798c2ecf20Sopenharmony_ci info = tree_search_offset(ctl, offset, 0, 0); 25808c2ecf20Sopenharmony_ci if (!info) { 25818c2ecf20Sopenharmony_ci /* 25828c2ecf20Sopenharmony_ci * oops didn't find an extent that matched the space we wanted 25838c2ecf20Sopenharmony_ci * to remove, look for a bitmap instead 25848c2ecf20Sopenharmony_ci */ 25858c2ecf20Sopenharmony_ci info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 25868c2ecf20Sopenharmony_ci 1, 0); 25878c2ecf20Sopenharmony_ci if (!info) { 25888c2ecf20Sopenharmony_ci /* 25898c2ecf20Sopenharmony_ci * If we found a partial bit of our free space in a 25908c2ecf20Sopenharmony_ci * bitmap but then couldn't find the other part this may 25918c2ecf20Sopenharmony_ci * be a problem, so WARN about it. 25928c2ecf20Sopenharmony_ci */ 25938c2ecf20Sopenharmony_ci WARN_ON(re_search); 25948c2ecf20Sopenharmony_ci goto out_lock; 25958c2ecf20Sopenharmony_ci } 25968c2ecf20Sopenharmony_ci } 25978c2ecf20Sopenharmony_ci 25988c2ecf20Sopenharmony_ci re_search = false; 25998c2ecf20Sopenharmony_ci if (!info->bitmap) { 26008c2ecf20Sopenharmony_ci unlink_free_space(ctl, info); 26018c2ecf20Sopenharmony_ci if (offset == info->offset) { 26028c2ecf20Sopenharmony_ci u64 to_free = min(bytes, info->bytes); 26038c2ecf20Sopenharmony_ci 26048c2ecf20Sopenharmony_ci info->bytes -= to_free; 26058c2ecf20Sopenharmony_ci info->offset += to_free; 26068c2ecf20Sopenharmony_ci if (info->bytes) { 26078c2ecf20Sopenharmony_ci ret = link_free_space(ctl, info); 26088c2ecf20Sopenharmony_ci WARN_ON(ret); 26098c2ecf20Sopenharmony_ci } else { 26108c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 26118c2ecf20Sopenharmony_ci } 26128c2ecf20Sopenharmony_ci 26138c2ecf20Sopenharmony_ci offset += to_free; 26148c2ecf20Sopenharmony_ci bytes -= to_free; 26158c2ecf20Sopenharmony_ci goto again; 26168c2ecf20Sopenharmony_ci } else { 26178c2ecf20Sopenharmony_ci u64 old_end = info->bytes + info->offset; 26188c2ecf20Sopenharmony_ci 26198c2ecf20Sopenharmony_ci info->bytes = offset - info->offset; 26208c2ecf20Sopenharmony_ci ret = link_free_space(ctl, info); 26218c2ecf20Sopenharmony_ci WARN_ON(ret); 26228c2ecf20Sopenharmony_ci if (ret) 26238c2ecf20Sopenharmony_ci goto out_lock; 26248c2ecf20Sopenharmony_ci 26258c2ecf20Sopenharmony_ci /* Not enough bytes in this entry to satisfy us */ 26268c2ecf20Sopenharmony_ci if (old_end < offset + bytes) { 26278c2ecf20Sopenharmony_ci bytes -= old_end - offset; 26288c2ecf20Sopenharmony_ci offset = old_end; 26298c2ecf20Sopenharmony_ci goto again; 26308c2ecf20Sopenharmony_ci } else if (old_end == offset + bytes) { 26318c2ecf20Sopenharmony_ci /* all done */ 26328c2ecf20Sopenharmony_ci goto out_lock; 26338c2ecf20Sopenharmony_ci } 26348c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 26358c2ecf20Sopenharmony_ci 26368c2ecf20Sopenharmony_ci ret = __btrfs_add_free_space(block_group->fs_info, ctl, 26378c2ecf20Sopenharmony_ci offset + bytes, 26388c2ecf20Sopenharmony_ci old_end - (offset + bytes), 26398c2ecf20Sopenharmony_ci info->trim_state); 26408c2ecf20Sopenharmony_ci WARN_ON(ret); 26418c2ecf20Sopenharmony_ci goto out; 26428c2ecf20Sopenharmony_ci } 26438c2ecf20Sopenharmony_ci } 26448c2ecf20Sopenharmony_ci 26458c2ecf20Sopenharmony_ci ret = remove_from_bitmap(ctl, info, &offset, &bytes); 26468c2ecf20Sopenharmony_ci if (ret == -EAGAIN) { 26478c2ecf20Sopenharmony_ci re_search = true; 26488c2ecf20Sopenharmony_ci goto again; 26498c2ecf20Sopenharmony_ci } 26508c2ecf20Sopenharmony_ciout_lock: 26518c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(block_group, ctl); 26528c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 26538c2ecf20Sopenharmony_ciout: 26548c2ecf20Sopenharmony_ci return ret; 26558c2ecf20Sopenharmony_ci} 26568c2ecf20Sopenharmony_ci 26578c2ecf20Sopenharmony_civoid btrfs_dump_free_space(struct btrfs_block_group *block_group, 26588c2ecf20Sopenharmony_ci u64 bytes) 26598c2ecf20Sopenharmony_ci{ 26608c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 26618c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 26628c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 26638c2ecf20Sopenharmony_ci struct rb_node *n; 26648c2ecf20Sopenharmony_ci int count = 0; 26658c2ecf20Sopenharmony_ci 26668c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 26678c2ecf20Sopenharmony_ci for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) { 26688c2ecf20Sopenharmony_ci info = rb_entry(n, struct btrfs_free_space, offset_index); 26698c2ecf20Sopenharmony_ci if (info->bytes >= bytes && !block_group->ro) 26708c2ecf20Sopenharmony_ci count++; 26718c2ecf20Sopenharmony_ci btrfs_crit(fs_info, "entry offset %llu, bytes %llu, bitmap %s", 26728c2ecf20Sopenharmony_ci info->offset, info->bytes, 26738c2ecf20Sopenharmony_ci (info->bitmap) ? "yes" : "no"); 26748c2ecf20Sopenharmony_ci } 26758c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 26768c2ecf20Sopenharmony_ci btrfs_info(fs_info, "block group has cluster?: %s", 26778c2ecf20Sopenharmony_ci list_empty(&block_group->cluster_list) ? "no" : "yes"); 26788c2ecf20Sopenharmony_ci btrfs_info(fs_info, 26798c2ecf20Sopenharmony_ci "%d blocks of free space at or bigger than bytes is", count); 26808c2ecf20Sopenharmony_ci} 26818c2ecf20Sopenharmony_ci 26828c2ecf20Sopenharmony_civoid btrfs_init_free_space_ctl(struct btrfs_block_group *block_group) 26838c2ecf20Sopenharmony_ci{ 26848c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 26858c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 26868c2ecf20Sopenharmony_ci 26878c2ecf20Sopenharmony_ci spin_lock_init(&ctl->tree_lock); 26888c2ecf20Sopenharmony_ci ctl->unit = fs_info->sectorsize; 26898c2ecf20Sopenharmony_ci ctl->start = block_group->start; 26908c2ecf20Sopenharmony_ci ctl->private = block_group; 26918c2ecf20Sopenharmony_ci ctl->op = &free_space_op; 26928c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ctl->trimming_ranges); 26938c2ecf20Sopenharmony_ci mutex_init(&ctl->cache_writeout_mutex); 26948c2ecf20Sopenharmony_ci 26958c2ecf20Sopenharmony_ci /* 26968c2ecf20Sopenharmony_ci * we only want to have 32k of ram per block group for keeping 26978c2ecf20Sopenharmony_ci * track of free space, and if we pass 1/2 of that we want to 26988c2ecf20Sopenharmony_ci * start converting things over to using bitmaps 26998c2ecf20Sopenharmony_ci */ 27008c2ecf20Sopenharmony_ci ctl->extents_thresh = (SZ_32K / 2) / sizeof(struct btrfs_free_space); 27018c2ecf20Sopenharmony_ci} 27028c2ecf20Sopenharmony_ci 27038c2ecf20Sopenharmony_ci/* 27048c2ecf20Sopenharmony_ci * for a given cluster, put all of its extents back into the free 27058c2ecf20Sopenharmony_ci * space cache. If the block group passed doesn't match the block group 27068c2ecf20Sopenharmony_ci * pointed to by the cluster, someone else raced in and freed the 27078c2ecf20Sopenharmony_ci * cluster already. In that case, we just return without changing anything 27088c2ecf20Sopenharmony_ci */ 27098c2ecf20Sopenharmony_cistatic void __btrfs_return_cluster_to_free_space( 27108c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 27118c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster) 27128c2ecf20Sopenharmony_ci{ 27138c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 27148c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 27158c2ecf20Sopenharmony_ci struct rb_node *node; 27168c2ecf20Sopenharmony_ci 27178c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 27188c2ecf20Sopenharmony_ci if (cluster->block_group != block_group) { 27198c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 27208c2ecf20Sopenharmony_ci return; 27218c2ecf20Sopenharmony_ci } 27228c2ecf20Sopenharmony_ci 27238c2ecf20Sopenharmony_ci cluster->block_group = NULL; 27248c2ecf20Sopenharmony_ci cluster->window_start = 0; 27258c2ecf20Sopenharmony_ci list_del_init(&cluster->block_group_list); 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_ci node = rb_first(&cluster->root); 27288c2ecf20Sopenharmony_ci while (node) { 27298c2ecf20Sopenharmony_ci bool bitmap; 27308c2ecf20Sopenharmony_ci 27318c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 27328c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 27338c2ecf20Sopenharmony_ci rb_erase(&entry->offset_index, &cluster->root); 27348c2ecf20Sopenharmony_ci RB_CLEAR_NODE(&entry->offset_index); 27358c2ecf20Sopenharmony_ci 27368c2ecf20Sopenharmony_ci bitmap = (entry->bitmap != NULL); 27378c2ecf20Sopenharmony_ci if (!bitmap) { 27388c2ecf20Sopenharmony_ci /* Merging treats extents as if they were new */ 27398c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(entry)) { 27408c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR]--; 27418c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= 27428c2ecf20Sopenharmony_ci entry->bytes; 27438c2ecf20Sopenharmony_ci } 27448c2ecf20Sopenharmony_ci 27458c2ecf20Sopenharmony_ci try_merge_free_space(ctl, entry, false); 27468c2ecf20Sopenharmony_ci steal_from_bitmap(ctl, entry, false); 27478c2ecf20Sopenharmony_ci 27488c2ecf20Sopenharmony_ci /* As we insert directly, update these statistics */ 27498c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(entry)) { 27508c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR]++; 27518c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += 27528c2ecf20Sopenharmony_ci entry->bytes; 27538c2ecf20Sopenharmony_ci } 27548c2ecf20Sopenharmony_ci } 27558c2ecf20Sopenharmony_ci tree_insert_offset(&ctl->free_space_offset, 27568c2ecf20Sopenharmony_ci entry->offset, &entry->offset_index, bitmap); 27578c2ecf20Sopenharmony_ci } 27588c2ecf20Sopenharmony_ci cluster->root = RB_ROOT; 27598c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 27608c2ecf20Sopenharmony_ci btrfs_put_block_group(block_group); 27618c2ecf20Sopenharmony_ci} 27628c2ecf20Sopenharmony_ci 27638c2ecf20Sopenharmony_cistatic void __btrfs_remove_free_space_cache_locked( 27648c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl) 27658c2ecf20Sopenharmony_ci{ 27668c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 27678c2ecf20Sopenharmony_ci struct rb_node *node; 27688c2ecf20Sopenharmony_ci 27698c2ecf20Sopenharmony_ci while ((node = rb_last(&ctl->free_space_offset)) != NULL) { 27708c2ecf20Sopenharmony_ci info = rb_entry(node, struct btrfs_free_space, offset_index); 27718c2ecf20Sopenharmony_ci if (!info->bitmap) { 27728c2ecf20Sopenharmony_ci unlink_free_space(ctl, info); 27738c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 27748c2ecf20Sopenharmony_ci } else { 27758c2ecf20Sopenharmony_ci free_bitmap(ctl, info); 27768c2ecf20Sopenharmony_ci } 27778c2ecf20Sopenharmony_ci 27788c2ecf20Sopenharmony_ci cond_resched_lock(&ctl->tree_lock); 27798c2ecf20Sopenharmony_ci } 27808c2ecf20Sopenharmony_ci} 27818c2ecf20Sopenharmony_ci 27828c2ecf20Sopenharmony_civoid __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl) 27838c2ecf20Sopenharmony_ci{ 27848c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 27858c2ecf20Sopenharmony_ci __btrfs_remove_free_space_cache_locked(ctl); 27868c2ecf20Sopenharmony_ci if (ctl->private) 27878c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(ctl->private, ctl); 27888c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 27898c2ecf20Sopenharmony_ci} 27908c2ecf20Sopenharmony_ci 27918c2ecf20Sopenharmony_civoid btrfs_remove_free_space_cache(struct btrfs_block_group *block_group) 27928c2ecf20Sopenharmony_ci{ 27938c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 27948c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster; 27958c2ecf20Sopenharmony_ci struct list_head *head; 27968c2ecf20Sopenharmony_ci 27978c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 27988c2ecf20Sopenharmony_ci while ((head = block_group->cluster_list.next) != 27998c2ecf20Sopenharmony_ci &block_group->cluster_list) { 28008c2ecf20Sopenharmony_ci cluster = list_entry(head, struct btrfs_free_cluster, 28018c2ecf20Sopenharmony_ci block_group_list); 28028c2ecf20Sopenharmony_ci 28038c2ecf20Sopenharmony_ci WARN_ON(cluster->block_group != block_group); 28048c2ecf20Sopenharmony_ci __btrfs_return_cluster_to_free_space(block_group, cluster); 28058c2ecf20Sopenharmony_ci 28068c2ecf20Sopenharmony_ci cond_resched_lock(&ctl->tree_lock); 28078c2ecf20Sopenharmony_ci } 28088c2ecf20Sopenharmony_ci __btrfs_remove_free_space_cache_locked(ctl); 28098c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(block_group, ctl); 28108c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 28118c2ecf20Sopenharmony_ci 28128c2ecf20Sopenharmony_ci} 28138c2ecf20Sopenharmony_ci 28148c2ecf20Sopenharmony_ci/** 28158c2ecf20Sopenharmony_ci * btrfs_is_free_space_trimmed - see if everything is trimmed 28168c2ecf20Sopenharmony_ci * @block_group: block_group of interest 28178c2ecf20Sopenharmony_ci * 28188c2ecf20Sopenharmony_ci * Walk @block_group's free space rb_tree to determine if everything is trimmed. 28198c2ecf20Sopenharmony_ci */ 28208c2ecf20Sopenharmony_cibool btrfs_is_free_space_trimmed(struct btrfs_block_group *block_group) 28218c2ecf20Sopenharmony_ci{ 28228c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 28238c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 28248c2ecf20Sopenharmony_ci struct rb_node *node; 28258c2ecf20Sopenharmony_ci bool ret = true; 28268c2ecf20Sopenharmony_ci 28278c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 28288c2ecf20Sopenharmony_ci node = rb_first(&ctl->free_space_offset); 28298c2ecf20Sopenharmony_ci 28308c2ecf20Sopenharmony_ci while (node) { 28318c2ecf20Sopenharmony_ci info = rb_entry(node, struct btrfs_free_space, offset_index); 28328c2ecf20Sopenharmony_ci 28338c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(info)) { 28348c2ecf20Sopenharmony_ci ret = false; 28358c2ecf20Sopenharmony_ci break; 28368c2ecf20Sopenharmony_ci } 28378c2ecf20Sopenharmony_ci 28388c2ecf20Sopenharmony_ci node = rb_next(node); 28398c2ecf20Sopenharmony_ci } 28408c2ecf20Sopenharmony_ci 28418c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 28428c2ecf20Sopenharmony_ci return ret; 28438c2ecf20Sopenharmony_ci} 28448c2ecf20Sopenharmony_ci 28458c2ecf20Sopenharmony_ciu64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group, 28468c2ecf20Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size, 28478c2ecf20Sopenharmony_ci u64 *max_extent_size) 28488c2ecf20Sopenharmony_ci{ 28498c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 28508c2ecf20Sopenharmony_ci struct btrfs_discard_ctl *discard_ctl = 28518c2ecf20Sopenharmony_ci &block_group->fs_info->discard_ctl; 28528c2ecf20Sopenharmony_ci struct btrfs_free_space *entry = NULL; 28538c2ecf20Sopenharmony_ci u64 bytes_search = bytes + empty_size; 28548c2ecf20Sopenharmony_ci u64 ret = 0; 28558c2ecf20Sopenharmony_ci u64 align_gap = 0; 28568c2ecf20Sopenharmony_ci u64 align_gap_len = 0; 28578c2ecf20Sopenharmony_ci enum btrfs_trim_state align_gap_trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 28588c2ecf20Sopenharmony_ci 28598c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 28608c2ecf20Sopenharmony_ci entry = find_free_space(ctl, &offset, &bytes_search, 28618c2ecf20Sopenharmony_ci block_group->full_stripe_len, max_extent_size); 28628c2ecf20Sopenharmony_ci if (!entry) 28638c2ecf20Sopenharmony_ci goto out; 28648c2ecf20Sopenharmony_ci 28658c2ecf20Sopenharmony_ci ret = offset; 28668c2ecf20Sopenharmony_ci if (entry->bitmap) { 28678c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, entry, offset, bytes); 28688c2ecf20Sopenharmony_ci 28698c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(entry)) 28708c2ecf20Sopenharmony_ci atomic64_add(bytes, &discard_ctl->discard_bytes_saved); 28718c2ecf20Sopenharmony_ci 28728c2ecf20Sopenharmony_ci if (!entry->bytes) 28738c2ecf20Sopenharmony_ci free_bitmap(ctl, entry); 28748c2ecf20Sopenharmony_ci } else { 28758c2ecf20Sopenharmony_ci unlink_free_space(ctl, entry); 28768c2ecf20Sopenharmony_ci align_gap_len = offset - entry->offset; 28778c2ecf20Sopenharmony_ci align_gap = entry->offset; 28788c2ecf20Sopenharmony_ci align_gap_trim_state = entry->trim_state; 28798c2ecf20Sopenharmony_ci 28808c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(entry)) 28818c2ecf20Sopenharmony_ci atomic64_add(bytes, &discard_ctl->discard_bytes_saved); 28828c2ecf20Sopenharmony_ci 28838c2ecf20Sopenharmony_ci entry->offset = offset + bytes; 28848c2ecf20Sopenharmony_ci WARN_ON(entry->bytes < bytes + align_gap_len); 28858c2ecf20Sopenharmony_ci 28868c2ecf20Sopenharmony_ci entry->bytes -= bytes + align_gap_len; 28878c2ecf20Sopenharmony_ci if (!entry->bytes) 28888c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, entry); 28898c2ecf20Sopenharmony_ci else 28908c2ecf20Sopenharmony_ci link_free_space(ctl, entry); 28918c2ecf20Sopenharmony_ci } 28928c2ecf20Sopenharmony_ciout: 28938c2ecf20Sopenharmony_ci btrfs_discard_update_discardable(block_group, ctl); 28948c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 28958c2ecf20Sopenharmony_ci 28968c2ecf20Sopenharmony_ci if (align_gap_len) 28978c2ecf20Sopenharmony_ci __btrfs_add_free_space(block_group->fs_info, ctl, 28988c2ecf20Sopenharmony_ci align_gap, align_gap_len, 28998c2ecf20Sopenharmony_ci align_gap_trim_state); 29008c2ecf20Sopenharmony_ci return ret; 29018c2ecf20Sopenharmony_ci} 29028c2ecf20Sopenharmony_ci 29038c2ecf20Sopenharmony_ci/* 29048c2ecf20Sopenharmony_ci * given a cluster, put all of its extents back into the free space 29058c2ecf20Sopenharmony_ci * cache. If a block group is passed, this function will only free 29068c2ecf20Sopenharmony_ci * a cluster that belongs to the passed block group. 29078c2ecf20Sopenharmony_ci * 29088c2ecf20Sopenharmony_ci * Otherwise, it'll get a reference on the block group pointed to by the 29098c2ecf20Sopenharmony_ci * cluster and remove the cluster from it. 29108c2ecf20Sopenharmony_ci */ 29118c2ecf20Sopenharmony_civoid btrfs_return_cluster_to_free_space( 29128c2ecf20Sopenharmony_ci struct btrfs_block_group *block_group, 29138c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster) 29148c2ecf20Sopenharmony_ci{ 29158c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl; 29168c2ecf20Sopenharmony_ci 29178c2ecf20Sopenharmony_ci /* first, get a safe pointer to the block group */ 29188c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 29198c2ecf20Sopenharmony_ci if (!block_group) { 29208c2ecf20Sopenharmony_ci block_group = cluster->block_group; 29218c2ecf20Sopenharmony_ci if (!block_group) { 29228c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 29238c2ecf20Sopenharmony_ci return; 29248c2ecf20Sopenharmony_ci } 29258c2ecf20Sopenharmony_ci } else if (cluster->block_group != block_group) { 29268c2ecf20Sopenharmony_ci /* someone else has already freed it don't redo their work */ 29278c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 29288c2ecf20Sopenharmony_ci return; 29298c2ecf20Sopenharmony_ci } 29308c2ecf20Sopenharmony_ci btrfs_get_block_group(block_group); 29318c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 29328c2ecf20Sopenharmony_ci 29338c2ecf20Sopenharmony_ci ctl = block_group->free_space_ctl; 29348c2ecf20Sopenharmony_ci 29358c2ecf20Sopenharmony_ci /* now return any extents the cluster had on it */ 29368c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 29378c2ecf20Sopenharmony_ci __btrfs_return_cluster_to_free_space(block_group, cluster); 29388c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 29398c2ecf20Sopenharmony_ci 29408c2ecf20Sopenharmony_ci btrfs_discard_queue_work(&block_group->fs_info->discard_ctl, block_group); 29418c2ecf20Sopenharmony_ci 29428c2ecf20Sopenharmony_ci /* finally drop our ref */ 29438c2ecf20Sopenharmony_ci btrfs_put_block_group(block_group); 29448c2ecf20Sopenharmony_ci} 29458c2ecf20Sopenharmony_ci 29468c2ecf20Sopenharmony_cistatic u64 btrfs_alloc_from_bitmap(struct btrfs_block_group *block_group, 29478c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 29488c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, 29498c2ecf20Sopenharmony_ci u64 bytes, u64 min_start, 29508c2ecf20Sopenharmony_ci u64 *max_extent_size) 29518c2ecf20Sopenharmony_ci{ 29528c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 29538c2ecf20Sopenharmony_ci int err; 29548c2ecf20Sopenharmony_ci u64 search_start = cluster->window_start; 29558c2ecf20Sopenharmony_ci u64 search_bytes = bytes; 29568c2ecf20Sopenharmony_ci u64 ret = 0; 29578c2ecf20Sopenharmony_ci 29588c2ecf20Sopenharmony_ci search_start = min_start; 29598c2ecf20Sopenharmony_ci search_bytes = bytes; 29608c2ecf20Sopenharmony_ci 29618c2ecf20Sopenharmony_ci err = search_bitmap(ctl, entry, &search_start, &search_bytes, true); 29628c2ecf20Sopenharmony_ci if (err) { 29638c2ecf20Sopenharmony_ci *max_extent_size = max(get_max_extent_size(entry), 29648c2ecf20Sopenharmony_ci *max_extent_size); 29658c2ecf20Sopenharmony_ci return 0; 29668c2ecf20Sopenharmony_ci } 29678c2ecf20Sopenharmony_ci 29688c2ecf20Sopenharmony_ci ret = search_start; 29698c2ecf20Sopenharmony_ci __bitmap_clear_bits(ctl, entry, ret, bytes); 29708c2ecf20Sopenharmony_ci 29718c2ecf20Sopenharmony_ci return ret; 29728c2ecf20Sopenharmony_ci} 29738c2ecf20Sopenharmony_ci 29748c2ecf20Sopenharmony_ci/* 29758c2ecf20Sopenharmony_ci * given a cluster, try to allocate 'bytes' from it, returns 0 29768c2ecf20Sopenharmony_ci * if it couldn't find anything suitably large, or a logical disk offset 29778c2ecf20Sopenharmony_ci * if things worked out 29788c2ecf20Sopenharmony_ci */ 29798c2ecf20Sopenharmony_ciu64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group, 29808c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, u64 bytes, 29818c2ecf20Sopenharmony_ci u64 min_start, u64 *max_extent_size) 29828c2ecf20Sopenharmony_ci{ 29838c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 29848c2ecf20Sopenharmony_ci struct btrfs_discard_ctl *discard_ctl = 29858c2ecf20Sopenharmony_ci &block_group->fs_info->discard_ctl; 29868c2ecf20Sopenharmony_ci struct btrfs_free_space *entry = NULL; 29878c2ecf20Sopenharmony_ci struct rb_node *node; 29888c2ecf20Sopenharmony_ci u64 ret = 0; 29898c2ecf20Sopenharmony_ci 29908c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 29918c2ecf20Sopenharmony_ci if (bytes > cluster->max_size) 29928c2ecf20Sopenharmony_ci goto out; 29938c2ecf20Sopenharmony_ci 29948c2ecf20Sopenharmony_ci if (cluster->block_group != block_group) 29958c2ecf20Sopenharmony_ci goto out; 29968c2ecf20Sopenharmony_ci 29978c2ecf20Sopenharmony_ci node = rb_first(&cluster->root); 29988c2ecf20Sopenharmony_ci if (!node) 29998c2ecf20Sopenharmony_ci goto out; 30008c2ecf20Sopenharmony_ci 30018c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 30028c2ecf20Sopenharmony_ci while (1) { 30038c2ecf20Sopenharmony_ci if (entry->bytes < bytes) 30048c2ecf20Sopenharmony_ci *max_extent_size = max(get_max_extent_size(entry), 30058c2ecf20Sopenharmony_ci *max_extent_size); 30068c2ecf20Sopenharmony_ci 30078c2ecf20Sopenharmony_ci if (entry->bytes < bytes || 30088c2ecf20Sopenharmony_ci (!entry->bitmap && entry->offset < min_start)) { 30098c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 30108c2ecf20Sopenharmony_ci if (!node) 30118c2ecf20Sopenharmony_ci break; 30128c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, 30138c2ecf20Sopenharmony_ci offset_index); 30148c2ecf20Sopenharmony_ci continue; 30158c2ecf20Sopenharmony_ci } 30168c2ecf20Sopenharmony_ci 30178c2ecf20Sopenharmony_ci if (entry->bitmap) { 30188c2ecf20Sopenharmony_ci ret = btrfs_alloc_from_bitmap(block_group, 30198c2ecf20Sopenharmony_ci cluster, entry, bytes, 30208c2ecf20Sopenharmony_ci cluster->window_start, 30218c2ecf20Sopenharmony_ci max_extent_size); 30228c2ecf20Sopenharmony_ci if (ret == 0) { 30238c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 30248c2ecf20Sopenharmony_ci if (!node) 30258c2ecf20Sopenharmony_ci break; 30268c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, 30278c2ecf20Sopenharmony_ci offset_index); 30288c2ecf20Sopenharmony_ci continue; 30298c2ecf20Sopenharmony_ci } 30308c2ecf20Sopenharmony_ci cluster->window_start += bytes; 30318c2ecf20Sopenharmony_ci } else { 30328c2ecf20Sopenharmony_ci ret = entry->offset; 30338c2ecf20Sopenharmony_ci 30348c2ecf20Sopenharmony_ci entry->offset += bytes; 30358c2ecf20Sopenharmony_ci entry->bytes -= bytes; 30368c2ecf20Sopenharmony_ci } 30378c2ecf20Sopenharmony_ci 30388c2ecf20Sopenharmony_ci break; 30398c2ecf20Sopenharmony_ci } 30408c2ecf20Sopenharmony_ciout: 30418c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 30428c2ecf20Sopenharmony_ci 30438c2ecf20Sopenharmony_ci if (!ret) 30448c2ecf20Sopenharmony_ci return 0; 30458c2ecf20Sopenharmony_ci 30468c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 30478c2ecf20Sopenharmony_ci 30488c2ecf20Sopenharmony_ci if (!btrfs_free_space_trimmed(entry)) 30498c2ecf20Sopenharmony_ci atomic64_add(bytes, &discard_ctl->discard_bytes_saved); 30508c2ecf20Sopenharmony_ci 30518c2ecf20Sopenharmony_ci ctl->free_space -= bytes; 30528c2ecf20Sopenharmony_ci if (!entry->bitmap && !btrfs_free_space_trimmed(entry)) 30538c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= bytes; 30548c2ecf20Sopenharmony_ci 30558c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 30568c2ecf20Sopenharmony_ci if (entry->bytes == 0) { 30578c2ecf20Sopenharmony_ci rb_erase(&entry->offset_index, &cluster->root); 30588c2ecf20Sopenharmony_ci ctl->free_extents--; 30598c2ecf20Sopenharmony_ci if (entry->bitmap) { 30608c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_bitmap_cachep, 30618c2ecf20Sopenharmony_ci entry->bitmap); 30628c2ecf20Sopenharmony_ci ctl->total_bitmaps--; 30638c2ecf20Sopenharmony_ci ctl->op->recalc_thresholds(ctl); 30648c2ecf20Sopenharmony_ci } else if (!btrfs_free_space_trimmed(entry)) { 30658c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR]--; 30668c2ecf20Sopenharmony_ci } 30678c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, entry); 30688c2ecf20Sopenharmony_ci } 30698c2ecf20Sopenharmony_ci 30708c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 30718c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 30728c2ecf20Sopenharmony_ci 30738c2ecf20Sopenharmony_ci return ret; 30748c2ecf20Sopenharmony_ci} 30758c2ecf20Sopenharmony_ci 30768c2ecf20Sopenharmony_cistatic int btrfs_bitmap_cluster(struct btrfs_block_group *block_group, 30778c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, 30788c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 30798c2ecf20Sopenharmony_ci u64 offset, u64 bytes, 30808c2ecf20Sopenharmony_ci u64 cont1_bytes, u64 min_bytes) 30818c2ecf20Sopenharmony_ci{ 30828c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 30838c2ecf20Sopenharmony_ci unsigned long next_zero; 30848c2ecf20Sopenharmony_ci unsigned long i; 30858c2ecf20Sopenharmony_ci unsigned long want_bits; 30868c2ecf20Sopenharmony_ci unsigned long min_bits; 30878c2ecf20Sopenharmony_ci unsigned long found_bits; 30888c2ecf20Sopenharmony_ci unsigned long max_bits = 0; 30898c2ecf20Sopenharmony_ci unsigned long start = 0; 30908c2ecf20Sopenharmony_ci unsigned long total_found = 0; 30918c2ecf20Sopenharmony_ci int ret; 30928c2ecf20Sopenharmony_ci 30938c2ecf20Sopenharmony_ci i = offset_to_bit(entry->offset, ctl->unit, 30948c2ecf20Sopenharmony_ci max_t(u64, offset, entry->offset)); 30958c2ecf20Sopenharmony_ci want_bits = bytes_to_bits(bytes, ctl->unit); 30968c2ecf20Sopenharmony_ci min_bits = bytes_to_bits(min_bytes, ctl->unit); 30978c2ecf20Sopenharmony_ci 30988c2ecf20Sopenharmony_ci /* 30998c2ecf20Sopenharmony_ci * Don't bother looking for a cluster in this bitmap if it's heavily 31008c2ecf20Sopenharmony_ci * fragmented. 31018c2ecf20Sopenharmony_ci */ 31028c2ecf20Sopenharmony_ci if (entry->max_extent_size && 31038c2ecf20Sopenharmony_ci entry->max_extent_size < cont1_bytes) 31048c2ecf20Sopenharmony_ci return -ENOSPC; 31058c2ecf20Sopenharmony_ciagain: 31068c2ecf20Sopenharmony_ci found_bits = 0; 31078c2ecf20Sopenharmony_ci for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) { 31088c2ecf20Sopenharmony_ci next_zero = find_next_zero_bit(entry->bitmap, 31098c2ecf20Sopenharmony_ci BITS_PER_BITMAP, i); 31108c2ecf20Sopenharmony_ci if (next_zero - i >= min_bits) { 31118c2ecf20Sopenharmony_ci found_bits = next_zero - i; 31128c2ecf20Sopenharmony_ci if (found_bits > max_bits) 31138c2ecf20Sopenharmony_ci max_bits = found_bits; 31148c2ecf20Sopenharmony_ci break; 31158c2ecf20Sopenharmony_ci } 31168c2ecf20Sopenharmony_ci if (next_zero - i > max_bits) 31178c2ecf20Sopenharmony_ci max_bits = next_zero - i; 31188c2ecf20Sopenharmony_ci i = next_zero; 31198c2ecf20Sopenharmony_ci } 31208c2ecf20Sopenharmony_ci 31218c2ecf20Sopenharmony_ci if (!found_bits) { 31228c2ecf20Sopenharmony_ci entry->max_extent_size = (u64)max_bits * ctl->unit; 31238c2ecf20Sopenharmony_ci return -ENOSPC; 31248c2ecf20Sopenharmony_ci } 31258c2ecf20Sopenharmony_ci 31268c2ecf20Sopenharmony_ci if (!total_found) { 31278c2ecf20Sopenharmony_ci start = i; 31288c2ecf20Sopenharmony_ci cluster->max_size = 0; 31298c2ecf20Sopenharmony_ci } 31308c2ecf20Sopenharmony_ci 31318c2ecf20Sopenharmony_ci total_found += found_bits; 31328c2ecf20Sopenharmony_ci 31338c2ecf20Sopenharmony_ci if (cluster->max_size < found_bits * ctl->unit) 31348c2ecf20Sopenharmony_ci cluster->max_size = found_bits * ctl->unit; 31358c2ecf20Sopenharmony_ci 31368c2ecf20Sopenharmony_ci if (total_found < want_bits || cluster->max_size < cont1_bytes) { 31378c2ecf20Sopenharmony_ci i = next_zero + 1; 31388c2ecf20Sopenharmony_ci goto again; 31398c2ecf20Sopenharmony_ci } 31408c2ecf20Sopenharmony_ci 31418c2ecf20Sopenharmony_ci cluster->window_start = start * ctl->unit + entry->offset; 31428c2ecf20Sopenharmony_ci rb_erase(&entry->offset_index, &ctl->free_space_offset); 31438c2ecf20Sopenharmony_ci ret = tree_insert_offset(&cluster->root, entry->offset, 31448c2ecf20Sopenharmony_ci &entry->offset_index, 1); 31458c2ecf20Sopenharmony_ci ASSERT(!ret); /* -EEXIST; Logic error */ 31468c2ecf20Sopenharmony_ci 31478c2ecf20Sopenharmony_ci trace_btrfs_setup_cluster(block_group, cluster, 31488c2ecf20Sopenharmony_ci total_found * ctl->unit, 1); 31498c2ecf20Sopenharmony_ci return 0; 31508c2ecf20Sopenharmony_ci} 31518c2ecf20Sopenharmony_ci 31528c2ecf20Sopenharmony_ci/* 31538c2ecf20Sopenharmony_ci * This searches the block group for just extents to fill the cluster with. 31548c2ecf20Sopenharmony_ci * Try to find a cluster with at least bytes total bytes, at least one 31558c2ecf20Sopenharmony_ci * extent of cont1_bytes, and other clusters of at least min_bytes. 31568c2ecf20Sopenharmony_ci */ 31578c2ecf20Sopenharmony_cistatic noinline int 31588c2ecf20Sopenharmony_cisetup_cluster_no_bitmap(struct btrfs_block_group *block_group, 31598c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 31608c2ecf20Sopenharmony_ci struct list_head *bitmaps, u64 offset, u64 bytes, 31618c2ecf20Sopenharmony_ci u64 cont1_bytes, u64 min_bytes) 31628c2ecf20Sopenharmony_ci{ 31638c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 31648c2ecf20Sopenharmony_ci struct btrfs_free_space *first = NULL; 31658c2ecf20Sopenharmony_ci struct btrfs_free_space *entry = NULL; 31668c2ecf20Sopenharmony_ci struct btrfs_free_space *last; 31678c2ecf20Sopenharmony_ci struct rb_node *node; 31688c2ecf20Sopenharmony_ci u64 window_free; 31698c2ecf20Sopenharmony_ci u64 max_extent; 31708c2ecf20Sopenharmony_ci u64 total_size = 0; 31718c2ecf20Sopenharmony_ci 31728c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, offset, 0, 1); 31738c2ecf20Sopenharmony_ci if (!entry) 31748c2ecf20Sopenharmony_ci return -ENOSPC; 31758c2ecf20Sopenharmony_ci 31768c2ecf20Sopenharmony_ci /* 31778c2ecf20Sopenharmony_ci * We don't want bitmaps, so just move along until we find a normal 31788c2ecf20Sopenharmony_ci * extent entry. 31798c2ecf20Sopenharmony_ci */ 31808c2ecf20Sopenharmony_ci while (entry->bitmap || entry->bytes < min_bytes) { 31818c2ecf20Sopenharmony_ci if (entry->bitmap && list_empty(&entry->list)) 31828c2ecf20Sopenharmony_ci list_add_tail(&entry->list, bitmaps); 31838c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 31848c2ecf20Sopenharmony_ci if (!node) 31858c2ecf20Sopenharmony_ci return -ENOSPC; 31868c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 31878c2ecf20Sopenharmony_ci } 31888c2ecf20Sopenharmony_ci 31898c2ecf20Sopenharmony_ci window_free = entry->bytes; 31908c2ecf20Sopenharmony_ci max_extent = entry->bytes; 31918c2ecf20Sopenharmony_ci first = entry; 31928c2ecf20Sopenharmony_ci last = entry; 31938c2ecf20Sopenharmony_ci 31948c2ecf20Sopenharmony_ci for (node = rb_next(&entry->offset_index); node; 31958c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index)) { 31968c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 31978c2ecf20Sopenharmony_ci 31988c2ecf20Sopenharmony_ci if (entry->bitmap) { 31998c2ecf20Sopenharmony_ci if (list_empty(&entry->list)) 32008c2ecf20Sopenharmony_ci list_add_tail(&entry->list, bitmaps); 32018c2ecf20Sopenharmony_ci continue; 32028c2ecf20Sopenharmony_ci } 32038c2ecf20Sopenharmony_ci 32048c2ecf20Sopenharmony_ci if (entry->bytes < min_bytes) 32058c2ecf20Sopenharmony_ci continue; 32068c2ecf20Sopenharmony_ci 32078c2ecf20Sopenharmony_ci last = entry; 32088c2ecf20Sopenharmony_ci window_free += entry->bytes; 32098c2ecf20Sopenharmony_ci if (entry->bytes > max_extent) 32108c2ecf20Sopenharmony_ci max_extent = entry->bytes; 32118c2ecf20Sopenharmony_ci } 32128c2ecf20Sopenharmony_ci 32138c2ecf20Sopenharmony_ci if (window_free < bytes || max_extent < cont1_bytes) 32148c2ecf20Sopenharmony_ci return -ENOSPC; 32158c2ecf20Sopenharmony_ci 32168c2ecf20Sopenharmony_ci cluster->window_start = first->offset; 32178c2ecf20Sopenharmony_ci 32188c2ecf20Sopenharmony_ci node = &first->offset_index; 32198c2ecf20Sopenharmony_ci 32208c2ecf20Sopenharmony_ci /* 32218c2ecf20Sopenharmony_ci * now we've found our entries, pull them out of the free space 32228c2ecf20Sopenharmony_ci * cache and put them into the cluster rbtree 32238c2ecf20Sopenharmony_ci */ 32248c2ecf20Sopenharmony_ci do { 32258c2ecf20Sopenharmony_ci int ret; 32268c2ecf20Sopenharmony_ci 32278c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, offset_index); 32288c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 32298c2ecf20Sopenharmony_ci if (entry->bitmap || entry->bytes < min_bytes) 32308c2ecf20Sopenharmony_ci continue; 32318c2ecf20Sopenharmony_ci 32328c2ecf20Sopenharmony_ci rb_erase(&entry->offset_index, &ctl->free_space_offset); 32338c2ecf20Sopenharmony_ci ret = tree_insert_offset(&cluster->root, entry->offset, 32348c2ecf20Sopenharmony_ci &entry->offset_index, 0); 32358c2ecf20Sopenharmony_ci total_size += entry->bytes; 32368c2ecf20Sopenharmony_ci ASSERT(!ret); /* -EEXIST; Logic error */ 32378c2ecf20Sopenharmony_ci } while (node && entry != last); 32388c2ecf20Sopenharmony_ci 32398c2ecf20Sopenharmony_ci cluster->max_size = max_extent; 32408c2ecf20Sopenharmony_ci trace_btrfs_setup_cluster(block_group, cluster, total_size, 0); 32418c2ecf20Sopenharmony_ci return 0; 32428c2ecf20Sopenharmony_ci} 32438c2ecf20Sopenharmony_ci 32448c2ecf20Sopenharmony_ci/* 32458c2ecf20Sopenharmony_ci * This specifically looks for bitmaps that may work in the cluster, we assume 32468c2ecf20Sopenharmony_ci * that we have already failed to find extents that will work. 32478c2ecf20Sopenharmony_ci */ 32488c2ecf20Sopenharmony_cistatic noinline int 32498c2ecf20Sopenharmony_cisetup_cluster_bitmap(struct btrfs_block_group *block_group, 32508c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 32518c2ecf20Sopenharmony_ci struct list_head *bitmaps, u64 offset, u64 bytes, 32528c2ecf20Sopenharmony_ci u64 cont1_bytes, u64 min_bytes) 32538c2ecf20Sopenharmony_ci{ 32548c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 32558c2ecf20Sopenharmony_ci struct btrfs_free_space *entry = NULL; 32568c2ecf20Sopenharmony_ci int ret = -ENOSPC; 32578c2ecf20Sopenharmony_ci u64 bitmap_offset = offset_to_bitmap(ctl, offset); 32588c2ecf20Sopenharmony_ci 32598c2ecf20Sopenharmony_ci if (ctl->total_bitmaps == 0) 32608c2ecf20Sopenharmony_ci return -ENOSPC; 32618c2ecf20Sopenharmony_ci 32628c2ecf20Sopenharmony_ci /* 32638c2ecf20Sopenharmony_ci * The bitmap that covers offset won't be in the list unless offset 32648c2ecf20Sopenharmony_ci * is just its start offset. 32658c2ecf20Sopenharmony_ci */ 32668c2ecf20Sopenharmony_ci if (!list_empty(bitmaps)) 32678c2ecf20Sopenharmony_ci entry = list_first_entry(bitmaps, struct btrfs_free_space, list); 32688c2ecf20Sopenharmony_ci 32698c2ecf20Sopenharmony_ci if (!entry || entry->offset != bitmap_offset) { 32708c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, bitmap_offset, 1, 0); 32718c2ecf20Sopenharmony_ci if (entry && list_empty(&entry->list)) 32728c2ecf20Sopenharmony_ci list_add(&entry->list, bitmaps); 32738c2ecf20Sopenharmony_ci } 32748c2ecf20Sopenharmony_ci 32758c2ecf20Sopenharmony_ci list_for_each_entry(entry, bitmaps, list) { 32768c2ecf20Sopenharmony_ci if (entry->bytes < bytes) 32778c2ecf20Sopenharmony_ci continue; 32788c2ecf20Sopenharmony_ci ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, 32798c2ecf20Sopenharmony_ci bytes, cont1_bytes, min_bytes); 32808c2ecf20Sopenharmony_ci if (!ret) 32818c2ecf20Sopenharmony_ci return 0; 32828c2ecf20Sopenharmony_ci } 32838c2ecf20Sopenharmony_ci 32848c2ecf20Sopenharmony_ci /* 32858c2ecf20Sopenharmony_ci * The bitmaps list has all the bitmaps that record free space 32868c2ecf20Sopenharmony_ci * starting after offset, so no more search is required. 32878c2ecf20Sopenharmony_ci */ 32888c2ecf20Sopenharmony_ci return -ENOSPC; 32898c2ecf20Sopenharmony_ci} 32908c2ecf20Sopenharmony_ci 32918c2ecf20Sopenharmony_ci/* 32928c2ecf20Sopenharmony_ci * here we try to find a cluster of blocks in a block group. The goal 32938c2ecf20Sopenharmony_ci * is to find at least bytes+empty_size. 32948c2ecf20Sopenharmony_ci * We might not find them all in one contiguous area. 32958c2ecf20Sopenharmony_ci * 32968c2ecf20Sopenharmony_ci * returns zero and sets up cluster if things worked out, otherwise 32978c2ecf20Sopenharmony_ci * it returns -enospc 32988c2ecf20Sopenharmony_ci */ 32998c2ecf20Sopenharmony_ciint btrfs_find_space_cluster(struct btrfs_block_group *block_group, 33008c2ecf20Sopenharmony_ci struct btrfs_free_cluster *cluster, 33018c2ecf20Sopenharmony_ci u64 offset, u64 bytes, u64 empty_size) 33028c2ecf20Sopenharmony_ci{ 33038c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 33048c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 33058c2ecf20Sopenharmony_ci struct btrfs_free_space *entry, *tmp; 33068c2ecf20Sopenharmony_ci LIST_HEAD(bitmaps); 33078c2ecf20Sopenharmony_ci u64 min_bytes; 33088c2ecf20Sopenharmony_ci u64 cont1_bytes; 33098c2ecf20Sopenharmony_ci int ret; 33108c2ecf20Sopenharmony_ci 33118c2ecf20Sopenharmony_ci /* 33128c2ecf20Sopenharmony_ci * Choose the minimum extent size we'll require for this 33138c2ecf20Sopenharmony_ci * cluster. For SSD_SPREAD, don't allow any fragmentation. 33148c2ecf20Sopenharmony_ci * For metadata, allow allocates with smaller extents. For 33158c2ecf20Sopenharmony_ci * data, keep it dense. 33168c2ecf20Sopenharmony_ci */ 33178c2ecf20Sopenharmony_ci if (btrfs_test_opt(fs_info, SSD_SPREAD)) { 33188c2ecf20Sopenharmony_ci cont1_bytes = min_bytes = bytes + empty_size; 33198c2ecf20Sopenharmony_ci } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) { 33208c2ecf20Sopenharmony_ci cont1_bytes = bytes; 33218c2ecf20Sopenharmony_ci min_bytes = fs_info->sectorsize; 33228c2ecf20Sopenharmony_ci } else { 33238c2ecf20Sopenharmony_ci cont1_bytes = max(bytes, (bytes + empty_size) >> 2); 33248c2ecf20Sopenharmony_ci min_bytes = fs_info->sectorsize; 33258c2ecf20Sopenharmony_ci } 33268c2ecf20Sopenharmony_ci 33278c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 33288c2ecf20Sopenharmony_ci 33298c2ecf20Sopenharmony_ci /* 33308c2ecf20Sopenharmony_ci * If we know we don't have enough space to make a cluster don't even 33318c2ecf20Sopenharmony_ci * bother doing all the work to try and find one. 33328c2ecf20Sopenharmony_ci */ 33338c2ecf20Sopenharmony_ci if (ctl->free_space < bytes) { 33348c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 33358c2ecf20Sopenharmony_ci return -ENOSPC; 33368c2ecf20Sopenharmony_ci } 33378c2ecf20Sopenharmony_ci 33388c2ecf20Sopenharmony_ci spin_lock(&cluster->lock); 33398c2ecf20Sopenharmony_ci 33408c2ecf20Sopenharmony_ci /* someone already found a cluster, hooray */ 33418c2ecf20Sopenharmony_ci if (cluster->block_group) { 33428c2ecf20Sopenharmony_ci ret = 0; 33438c2ecf20Sopenharmony_ci goto out; 33448c2ecf20Sopenharmony_ci } 33458c2ecf20Sopenharmony_ci 33468c2ecf20Sopenharmony_ci trace_btrfs_find_cluster(block_group, offset, bytes, empty_size, 33478c2ecf20Sopenharmony_ci min_bytes); 33488c2ecf20Sopenharmony_ci 33498c2ecf20Sopenharmony_ci ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset, 33508c2ecf20Sopenharmony_ci bytes + empty_size, 33518c2ecf20Sopenharmony_ci cont1_bytes, min_bytes); 33528c2ecf20Sopenharmony_ci if (ret) 33538c2ecf20Sopenharmony_ci ret = setup_cluster_bitmap(block_group, cluster, &bitmaps, 33548c2ecf20Sopenharmony_ci offset, bytes + empty_size, 33558c2ecf20Sopenharmony_ci cont1_bytes, min_bytes); 33568c2ecf20Sopenharmony_ci 33578c2ecf20Sopenharmony_ci /* Clear our temporary list */ 33588c2ecf20Sopenharmony_ci list_for_each_entry_safe(entry, tmp, &bitmaps, list) 33598c2ecf20Sopenharmony_ci list_del_init(&entry->list); 33608c2ecf20Sopenharmony_ci 33618c2ecf20Sopenharmony_ci if (!ret) { 33628c2ecf20Sopenharmony_ci btrfs_get_block_group(block_group); 33638c2ecf20Sopenharmony_ci list_add_tail(&cluster->block_group_list, 33648c2ecf20Sopenharmony_ci &block_group->cluster_list); 33658c2ecf20Sopenharmony_ci cluster->block_group = block_group; 33668c2ecf20Sopenharmony_ci } else { 33678c2ecf20Sopenharmony_ci trace_btrfs_failed_cluster_setup(block_group); 33688c2ecf20Sopenharmony_ci } 33698c2ecf20Sopenharmony_ciout: 33708c2ecf20Sopenharmony_ci spin_unlock(&cluster->lock); 33718c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 33728c2ecf20Sopenharmony_ci 33738c2ecf20Sopenharmony_ci return ret; 33748c2ecf20Sopenharmony_ci} 33758c2ecf20Sopenharmony_ci 33768c2ecf20Sopenharmony_ci/* 33778c2ecf20Sopenharmony_ci * simple code to zero out a cluster 33788c2ecf20Sopenharmony_ci */ 33798c2ecf20Sopenharmony_civoid btrfs_init_free_cluster(struct btrfs_free_cluster *cluster) 33808c2ecf20Sopenharmony_ci{ 33818c2ecf20Sopenharmony_ci spin_lock_init(&cluster->lock); 33828c2ecf20Sopenharmony_ci spin_lock_init(&cluster->refill_lock); 33838c2ecf20Sopenharmony_ci cluster->root = RB_ROOT; 33848c2ecf20Sopenharmony_ci cluster->max_size = 0; 33858c2ecf20Sopenharmony_ci cluster->fragmented = false; 33868c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&cluster->block_group_list); 33878c2ecf20Sopenharmony_ci cluster->block_group = NULL; 33888c2ecf20Sopenharmony_ci} 33898c2ecf20Sopenharmony_ci 33908c2ecf20Sopenharmony_cistatic int do_trimming(struct btrfs_block_group *block_group, 33918c2ecf20Sopenharmony_ci u64 *total_trimmed, u64 start, u64 bytes, 33928c2ecf20Sopenharmony_ci u64 reserved_start, u64 reserved_bytes, 33938c2ecf20Sopenharmony_ci enum btrfs_trim_state reserved_trim_state, 33948c2ecf20Sopenharmony_ci struct btrfs_trim_range *trim_entry) 33958c2ecf20Sopenharmony_ci{ 33968c2ecf20Sopenharmony_ci struct btrfs_space_info *space_info = block_group->space_info; 33978c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = block_group->fs_info; 33988c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 33998c2ecf20Sopenharmony_ci int ret; 34008c2ecf20Sopenharmony_ci int update = 0; 34018c2ecf20Sopenharmony_ci const u64 end = start + bytes; 34028c2ecf20Sopenharmony_ci const u64 reserved_end = reserved_start + reserved_bytes; 34038c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 34048c2ecf20Sopenharmony_ci u64 trimmed = 0; 34058c2ecf20Sopenharmony_ci 34068c2ecf20Sopenharmony_ci spin_lock(&space_info->lock); 34078c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 34088c2ecf20Sopenharmony_ci if (!block_group->ro) { 34098c2ecf20Sopenharmony_ci block_group->reserved += reserved_bytes; 34108c2ecf20Sopenharmony_ci space_info->bytes_reserved += reserved_bytes; 34118c2ecf20Sopenharmony_ci update = 1; 34128c2ecf20Sopenharmony_ci } 34138c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 34148c2ecf20Sopenharmony_ci spin_unlock(&space_info->lock); 34158c2ecf20Sopenharmony_ci 34168c2ecf20Sopenharmony_ci ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed); 34178c2ecf20Sopenharmony_ci if (!ret) { 34188c2ecf20Sopenharmony_ci *total_trimmed += trimmed; 34198c2ecf20Sopenharmony_ci trim_state = BTRFS_TRIM_STATE_TRIMMED; 34208c2ecf20Sopenharmony_ci } 34218c2ecf20Sopenharmony_ci 34228c2ecf20Sopenharmony_ci mutex_lock(&ctl->cache_writeout_mutex); 34238c2ecf20Sopenharmony_ci if (reserved_start < start) 34248c2ecf20Sopenharmony_ci __btrfs_add_free_space(fs_info, ctl, reserved_start, 34258c2ecf20Sopenharmony_ci start - reserved_start, 34268c2ecf20Sopenharmony_ci reserved_trim_state); 34278c2ecf20Sopenharmony_ci if (start + bytes < reserved_start + reserved_bytes) 34288c2ecf20Sopenharmony_ci __btrfs_add_free_space(fs_info, ctl, end, reserved_end - end, 34298c2ecf20Sopenharmony_ci reserved_trim_state); 34308c2ecf20Sopenharmony_ci __btrfs_add_free_space(fs_info, ctl, start, bytes, trim_state); 34318c2ecf20Sopenharmony_ci list_del(&trim_entry->list); 34328c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 34338c2ecf20Sopenharmony_ci 34348c2ecf20Sopenharmony_ci if (update) { 34358c2ecf20Sopenharmony_ci spin_lock(&space_info->lock); 34368c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 34378c2ecf20Sopenharmony_ci if (block_group->ro) 34388c2ecf20Sopenharmony_ci space_info->bytes_readonly += reserved_bytes; 34398c2ecf20Sopenharmony_ci block_group->reserved -= reserved_bytes; 34408c2ecf20Sopenharmony_ci space_info->bytes_reserved -= reserved_bytes; 34418c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 34428c2ecf20Sopenharmony_ci spin_unlock(&space_info->lock); 34438c2ecf20Sopenharmony_ci } 34448c2ecf20Sopenharmony_ci 34458c2ecf20Sopenharmony_ci return ret; 34468c2ecf20Sopenharmony_ci} 34478c2ecf20Sopenharmony_ci 34488c2ecf20Sopenharmony_ci/* 34498c2ecf20Sopenharmony_ci * If @async is set, then we will trim 1 region and return. 34508c2ecf20Sopenharmony_ci */ 34518c2ecf20Sopenharmony_cistatic int trim_no_bitmap(struct btrfs_block_group *block_group, 34528c2ecf20Sopenharmony_ci u64 *total_trimmed, u64 start, u64 end, u64 minlen, 34538c2ecf20Sopenharmony_ci bool async) 34548c2ecf20Sopenharmony_ci{ 34558c2ecf20Sopenharmony_ci struct btrfs_discard_ctl *discard_ctl = 34568c2ecf20Sopenharmony_ci &block_group->fs_info->discard_ctl; 34578c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 34588c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 34598c2ecf20Sopenharmony_ci struct rb_node *node; 34608c2ecf20Sopenharmony_ci int ret = 0; 34618c2ecf20Sopenharmony_ci u64 extent_start; 34628c2ecf20Sopenharmony_ci u64 extent_bytes; 34638c2ecf20Sopenharmony_ci enum btrfs_trim_state extent_trim_state; 34648c2ecf20Sopenharmony_ci u64 bytes; 34658c2ecf20Sopenharmony_ci const u64 max_discard_size = READ_ONCE(discard_ctl->max_discard_size); 34668c2ecf20Sopenharmony_ci 34678c2ecf20Sopenharmony_ci while (start < end) { 34688c2ecf20Sopenharmony_ci struct btrfs_trim_range trim_entry; 34698c2ecf20Sopenharmony_ci 34708c2ecf20Sopenharmony_ci mutex_lock(&ctl->cache_writeout_mutex); 34718c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 34728c2ecf20Sopenharmony_ci 34738c2ecf20Sopenharmony_ci if (ctl->free_space < minlen) 34748c2ecf20Sopenharmony_ci goto out_unlock; 34758c2ecf20Sopenharmony_ci 34768c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, start, 0, 1); 34778c2ecf20Sopenharmony_ci if (!entry) 34788c2ecf20Sopenharmony_ci goto out_unlock; 34798c2ecf20Sopenharmony_ci 34808c2ecf20Sopenharmony_ci /* Skip bitmaps and if async, already trimmed entries */ 34818c2ecf20Sopenharmony_ci while (entry->bitmap || 34828c2ecf20Sopenharmony_ci (async && btrfs_free_space_trimmed(entry))) { 34838c2ecf20Sopenharmony_ci node = rb_next(&entry->offset_index); 34848c2ecf20Sopenharmony_ci if (!node) 34858c2ecf20Sopenharmony_ci goto out_unlock; 34868c2ecf20Sopenharmony_ci entry = rb_entry(node, struct btrfs_free_space, 34878c2ecf20Sopenharmony_ci offset_index); 34888c2ecf20Sopenharmony_ci } 34898c2ecf20Sopenharmony_ci 34908c2ecf20Sopenharmony_ci if (entry->offset >= end) 34918c2ecf20Sopenharmony_ci goto out_unlock; 34928c2ecf20Sopenharmony_ci 34938c2ecf20Sopenharmony_ci extent_start = entry->offset; 34948c2ecf20Sopenharmony_ci extent_bytes = entry->bytes; 34958c2ecf20Sopenharmony_ci extent_trim_state = entry->trim_state; 34968c2ecf20Sopenharmony_ci if (async) { 34978c2ecf20Sopenharmony_ci start = entry->offset; 34988c2ecf20Sopenharmony_ci bytes = entry->bytes; 34998c2ecf20Sopenharmony_ci if (bytes < minlen) { 35008c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 35018c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 35028c2ecf20Sopenharmony_ci goto next; 35038c2ecf20Sopenharmony_ci } 35048c2ecf20Sopenharmony_ci unlink_free_space(ctl, entry); 35058c2ecf20Sopenharmony_ci /* 35068c2ecf20Sopenharmony_ci * Let bytes = BTRFS_MAX_DISCARD_SIZE + X. 35078c2ecf20Sopenharmony_ci * If X < BTRFS_ASYNC_DISCARD_MIN_FILTER, we won't trim 35088c2ecf20Sopenharmony_ci * X when we come back around. So trim it now. 35098c2ecf20Sopenharmony_ci */ 35108c2ecf20Sopenharmony_ci if (max_discard_size && 35118c2ecf20Sopenharmony_ci bytes >= (max_discard_size + 35128c2ecf20Sopenharmony_ci BTRFS_ASYNC_DISCARD_MIN_FILTER)) { 35138c2ecf20Sopenharmony_ci bytes = max_discard_size; 35148c2ecf20Sopenharmony_ci extent_bytes = max_discard_size; 35158c2ecf20Sopenharmony_ci entry->offset += max_discard_size; 35168c2ecf20Sopenharmony_ci entry->bytes -= max_discard_size; 35178c2ecf20Sopenharmony_ci link_free_space(ctl, entry); 35188c2ecf20Sopenharmony_ci } else { 35198c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, entry); 35208c2ecf20Sopenharmony_ci } 35218c2ecf20Sopenharmony_ci } else { 35228c2ecf20Sopenharmony_ci start = max(start, extent_start); 35238c2ecf20Sopenharmony_ci bytes = min(extent_start + extent_bytes, end) - start; 35248c2ecf20Sopenharmony_ci if (bytes < minlen) { 35258c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 35268c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 35278c2ecf20Sopenharmony_ci goto next; 35288c2ecf20Sopenharmony_ci } 35298c2ecf20Sopenharmony_ci 35308c2ecf20Sopenharmony_ci unlink_free_space(ctl, entry); 35318c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, entry); 35328c2ecf20Sopenharmony_ci } 35338c2ecf20Sopenharmony_ci 35348c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 35358c2ecf20Sopenharmony_ci trim_entry.start = extent_start; 35368c2ecf20Sopenharmony_ci trim_entry.bytes = extent_bytes; 35378c2ecf20Sopenharmony_ci list_add_tail(&trim_entry.list, &ctl->trimming_ranges); 35388c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 35398c2ecf20Sopenharmony_ci 35408c2ecf20Sopenharmony_ci ret = do_trimming(block_group, total_trimmed, start, bytes, 35418c2ecf20Sopenharmony_ci extent_start, extent_bytes, extent_trim_state, 35428c2ecf20Sopenharmony_ci &trim_entry); 35438c2ecf20Sopenharmony_ci if (ret) { 35448c2ecf20Sopenharmony_ci block_group->discard_cursor = start + bytes; 35458c2ecf20Sopenharmony_ci break; 35468c2ecf20Sopenharmony_ci } 35478c2ecf20Sopenharmony_cinext: 35488c2ecf20Sopenharmony_ci start += bytes; 35498c2ecf20Sopenharmony_ci block_group->discard_cursor = start; 35508c2ecf20Sopenharmony_ci if (async && *total_trimmed) 35518c2ecf20Sopenharmony_ci break; 35528c2ecf20Sopenharmony_ci 35538c2ecf20Sopenharmony_ci if (fatal_signal_pending(current)) { 35548c2ecf20Sopenharmony_ci ret = -ERESTARTSYS; 35558c2ecf20Sopenharmony_ci break; 35568c2ecf20Sopenharmony_ci } 35578c2ecf20Sopenharmony_ci 35588c2ecf20Sopenharmony_ci cond_resched(); 35598c2ecf20Sopenharmony_ci } 35608c2ecf20Sopenharmony_ci 35618c2ecf20Sopenharmony_ci return ret; 35628c2ecf20Sopenharmony_ci 35638c2ecf20Sopenharmony_ciout_unlock: 35648c2ecf20Sopenharmony_ci block_group->discard_cursor = btrfs_block_group_end(block_group); 35658c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 35668c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 35678c2ecf20Sopenharmony_ci 35688c2ecf20Sopenharmony_ci return ret; 35698c2ecf20Sopenharmony_ci} 35708c2ecf20Sopenharmony_ci 35718c2ecf20Sopenharmony_ci/* 35728c2ecf20Sopenharmony_ci * If we break out of trimming a bitmap prematurely, we should reset the 35738c2ecf20Sopenharmony_ci * trimming bit. In a rather contrieved case, it's possible to race here so 35748c2ecf20Sopenharmony_ci * reset the state to BTRFS_TRIM_STATE_UNTRIMMED. 35758c2ecf20Sopenharmony_ci * 35768c2ecf20Sopenharmony_ci * start = start of bitmap 35778c2ecf20Sopenharmony_ci * end = near end of bitmap 35788c2ecf20Sopenharmony_ci * 35798c2ecf20Sopenharmony_ci * Thread 1: Thread 2: 35808c2ecf20Sopenharmony_ci * trim_bitmaps(start) 35818c2ecf20Sopenharmony_ci * trim_bitmaps(end) 35828c2ecf20Sopenharmony_ci * end_trimming_bitmap() 35838c2ecf20Sopenharmony_ci * reset_trimming_bitmap() 35848c2ecf20Sopenharmony_ci */ 35858c2ecf20Sopenharmony_cistatic void reset_trimming_bitmap(struct btrfs_free_space_ctl *ctl, u64 offset) 35868c2ecf20Sopenharmony_ci{ 35878c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 35888c2ecf20Sopenharmony_ci 35898c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 35908c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, offset, 1, 0); 35918c2ecf20Sopenharmony_ci if (entry) { 35928c2ecf20Sopenharmony_ci if (btrfs_free_space_trimmed(entry)) { 35938c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] += 35948c2ecf20Sopenharmony_ci entry->bitmap_extents; 35958c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] += entry->bytes; 35968c2ecf20Sopenharmony_ci } 35978c2ecf20Sopenharmony_ci entry->trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 35988c2ecf20Sopenharmony_ci } 35998c2ecf20Sopenharmony_ci 36008c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 36018c2ecf20Sopenharmony_ci} 36028c2ecf20Sopenharmony_ci 36038c2ecf20Sopenharmony_cistatic void end_trimming_bitmap(struct btrfs_free_space_ctl *ctl, 36048c2ecf20Sopenharmony_ci struct btrfs_free_space *entry) 36058c2ecf20Sopenharmony_ci{ 36068c2ecf20Sopenharmony_ci if (btrfs_free_space_trimming_bitmap(entry)) { 36078c2ecf20Sopenharmony_ci entry->trim_state = BTRFS_TRIM_STATE_TRIMMED; 36088c2ecf20Sopenharmony_ci ctl->discardable_extents[BTRFS_STAT_CURR] -= 36098c2ecf20Sopenharmony_ci entry->bitmap_extents; 36108c2ecf20Sopenharmony_ci ctl->discardable_bytes[BTRFS_STAT_CURR] -= entry->bytes; 36118c2ecf20Sopenharmony_ci } 36128c2ecf20Sopenharmony_ci} 36138c2ecf20Sopenharmony_ci 36148c2ecf20Sopenharmony_ci/* 36158c2ecf20Sopenharmony_ci * If @async is set, then we will trim 1 region and return. 36168c2ecf20Sopenharmony_ci */ 36178c2ecf20Sopenharmony_cistatic int trim_bitmaps(struct btrfs_block_group *block_group, 36188c2ecf20Sopenharmony_ci u64 *total_trimmed, u64 start, u64 end, u64 minlen, 36198c2ecf20Sopenharmony_ci u64 maxlen, bool async) 36208c2ecf20Sopenharmony_ci{ 36218c2ecf20Sopenharmony_ci struct btrfs_discard_ctl *discard_ctl = 36228c2ecf20Sopenharmony_ci &block_group->fs_info->discard_ctl; 36238c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 36248c2ecf20Sopenharmony_ci struct btrfs_free_space *entry; 36258c2ecf20Sopenharmony_ci int ret = 0; 36268c2ecf20Sopenharmony_ci int ret2; 36278c2ecf20Sopenharmony_ci u64 bytes; 36288c2ecf20Sopenharmony_ci u64 offset = offset_to_bitmap(ctl, start); 36298c2ecf20Sopenharmony_ci const u64 max_discard_size = READ_ONCE(discard_ctl->max_discard_size); 36308c2ecf20Sopenharmony_ci 36318c2ecf20Sopenharmony_ci while (offset < end) { 36328c2ecf20Sopenharmony_ci bool next_bitmap = false; 36338c2ecf20Sopenharmony_ci struct btrfs_trim_range trim_entry; 36348c2ecf20Sopenharmony_ci 36358c2ecf20Sopenharmony_ci mutex_lock(&ctl->cache_writeout_mutex); 36368c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 36378c2ecf20Sopenharmony_ci 36388c2ecf20Sopenharmony_ci if (ctl->free_space < minlen) { 36398c2ecf20Sopenharmony_ci block_group->discard_cursor = 36408c2ecf20Sopenharmony_ci btrfs_block_group_end(block_group); 36418c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 36428c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 36438c2ecf20Sopenharmony_ci break; 36448c2ecf20Sopenharmony_ci } 36458c2ecf20Sopenharmony_ci 36468c2ecf20Sopenharmony_ci entry = tree_search_offset(ctl, offset, 1, 0); 36478c2ecf20Sopenharmony_ci /* 36488c2ecf20Sopenharmony_ci * Bitmaps are marked trimmed lossily now to prevent constant 36498c2ecf20Sopenharmony_ci * discarding of the same bitmap (the reason why we are bound 36508c2ecf20Sopenharmony_ci * by the filters). So, retrim the block group bitmaps when we 36518c2ecf20Sopenharmony_ci * are preparing to punt to the unused_bgs list. This uses 36528c2ecf20Sopenharmony_ci * @minlen to determine if we are in BTRFS_DISCARD_INDEX_UNUSED 36538c2ecf20Sopenharmony_ci * which is the only discard index which sets minlen to 0. 36548c2ecf20Sopenharmony_ci */ 36558c2ecf20Sopenharmony_ci if (!entry || (async && minlen && start == offset && 36568c2ecf20Sopenharmony_ci btrfs_free_space_trimmed(entry))) { 36578c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 36588c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 36598c2ecf20Sopenharmony_ci next_bitmap = true; 36608c2ecf20Sopenharmony_ci goto next; 36618c2ecf20Sopenharmony_ci } 36628c2ecf20Sopenharmony_ci 36638c2ecf20Sopenharmony_ci /* 36648c2ecf20Sopenharmony_ci * Async discard bitmap trimming begins at by setting the start 36658c2ecf20Sopenharmony_ci * to be key.objectid and the offset_to_bitmap() aligns to the 36668c2ecf20Sopenharmony_ci * start of the bitmap. This lets us know we are fully 36678c2ecf20Sopenharmony_ci * scanning the bitmap rather than only some portion of it. 36688c2ecf20Sopenharmony_ci */ 36698c2ecf20Sopenharmony_ci if (start == offset) 36708c2ecf20Sopenharmony_ci entry->trim_state = BTRFS_TRIM_STATE_TRIMMING; 36718c2ecf20Sopenharmony_ci 36728c2ecf20Sopenharmony_ci bytes = minlen; 36738c2ecf20Sopenharmony_ci ret2 = search_bitmap(ctl, entry, &start, &bytes, false); 36748c2ecf20Sopenharmony_ci if (ret2 || start >= end) { 36758c2ecf20Sopenharmony_ci /* 36768c2ecf20Sopenharmony_ci * We lossily consider a bitmap trimmed if we only skip 36778c2ecf20Sopenharmony_ci * over regions <= BTRFS_ASYNC_DISCARD_MIN_FILTER. 36788c2ecf20Sopenharmony_ci */ 36798c2ecf20Sopenharmony_ci if (ret2 && minlen <= BTRFS_ASYNC_DISCARD_MIN_FILTER) 36808c2ecf20Sopenharmony_ci end_trimming_bitmap(ctl, entry); 36818c2ecf20Sopenharmony_ci else 36828c2ecf20Sopenharmony_ci entry->trim_state = BTRFS_TRIM_STATE_UNTRIMMED; 36838c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 36848c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 36858c2ecf20Sopenharmony_ci next_bitmap = true; 36868c2ecf20Sopenharmony_ci goto next; 36878c2ecf20Sopenharmony_ci } 36888c2ecf20Sopenharmony_ci 36898c2ecf20Sopenharmony_ci /* 36908c2ecf20Sopenharmony_ci * We already trimmed a region, but are using the locking above 36918c2ecf20Sopenharmony_ci * to reset the trim_state. 36928c2ecf20Sopenharmony_ci */ 36938c2ecf20Sopenharmony_ci if (async && *total_trimmed) { 36948c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 36958c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 36968c2ecf20Sopenharmony_ci goto out; 36978c2ecf20Sopenharmony_ci } 36988c2ecf20Sopenharmony_ci 36998c2ecf20Sopenharmony_ci bytes = min(bytes, end - start); 37008c2ecf20Sopenharmony_ci if (bytes < minlen || (async && maxlen && bytes > maxlen)) { 37018c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 37028c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 37038c2ecf20Sopenharmony_ci goto next; 37048c2ecf20Sopenharmony_ci } 37058c2ecf20Sopenharmony_ci 37068c2ecf20Sopenharmony_ci /* 37078c2ecf20Sopenharmony_ci * Let bytes = BTRFS_MAX_DISCARD_SIZE + X. 37088c2ecf20Sopenharmony_ci * If X < @minlen, we won't trim X when we come back around. 37098c2ecf20Sopenharmony_ci * So trim it now. We differ here from trimming extents as we 37108c2ecf20Sopenharmony_ci * don't keep individual state per bit. 37118c2ecf20Sopenharmony_ci */ 37128c2ecf20Sopenharmony_ci if (async && 37138c2ecf20Sopenharmony_ci max_discard_size && 37148c2ecf20Sopenharmony_ci bytes > (max_discard_size + minlen)) 37158c2ecf20Sopenharmony_ci bytes = max_discard_size; 37168c2ecf20Sopenharmony_ci 37178c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, entry, start, bytes); 37188c2ecf20Sopenharmony_ci if (entry->bytes == 0) 37198c2ecf20Sopenharmony_ci free_bitmap(ctl, entry); 37208c2ecf20Sopenharmony_ci 37218c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 37228c2ecf20Sopenharmony_ci trim_entry.start = start; 37238c2ecf20Sopenharmony_ci trim_entry.bytes = bytes; 37248c2ecf20Sopenharmony_ci list_add_tail(&trim_entry.list, &ctl->trimming_ranges); 37258c2ecf20Sopenharmony_ci mutex_unlock(&ctl->cache_writeout_mutex); 37268c2ecf20Sopenharmony_ci 37278c2ecf20Sopenharmony_ci ret = do_trimming(block_group, total_trimmed, start, bytes, 37288c2ecf20Sopenharmony_ci start, bytes, 0, &trim_entry); 37298c2ecf20Sopenharmony_ci if (ret) { 37308c2ecf20Sopenharmony_ci reset_trimming_bitmap(ctl, offset); 37318c2ecf20Sopenharmony_ci block_group->discard_cursor = 37328c2ecf20Sopenharmony_ci btrfs_block_group_end(block_group); 37338c2ecf20Sopenharmony_ci break; 37348c2ecf20Sopenharmony_ci } 37358c2ecf20Sopenharmony_cinext: 37368c2ecf20Sopenharmony_ci if (next_bitmap) { 37378c2ecf20Sopenharmony_ci offset += BITS_PER_BITMAP * ctl->unit; 37388c2ecf20Sopenharmony_ci start = offset; 37398c2ecf20Sopenharmony_ci } else { 37408c2ecf20Sopenharmony_ci start += bytes; 37418c2ecf20Sopenharmony_ci } 37428c2ecf20Sopenharmony_ci block_group->discard_cursor = start; 37438c2ecf20Sopenharmony_ci 37448c2ecf20Sopenharmony_ci if (fatal_signal_pending(current)) { 37458c2ecf20Sopenharmony_ci if (start != offset) 37468c2ecf20Sopenharmony_ci reset_trimming_bitmap(ctl, offset); 37478c2ecf20Sopenharmony_ci ret = -ERESTARTSYS; 37488c2ecf20Sopenharmony_ci break; 37498c2ecf20Sopenharmony_ci } 37508c2ecf20Sopenharmony_ci 37518c2ecf20Sopenharmony_ci cond_resched(); 37528c2ecf20Sopenharmony_ci } 37538c2ecf20Sopenharmony_ci 37548c2ecf20Sopenharmony_ci if (offset >= end) 37558c2ecf20Sopenharmony_ci block_group->discard_cursor = end; 37568c2ecf20Sopenharmony_ci 37578c2ecf20Sopenharmony_ciout: 37588c2ecf20Sopenharmony_ci return ret; 37598c2ecf20Sopenharmony_ci} 37608c2ecf20Sopenharmony_ci 37618c2ecf20Sopenharmony_ciint btrfs_trim_block_group(struct btrfs_block_group *block_group, 37628c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen) 37638c2ecf20Sopenharmony_ci{ 37648c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 37658c2ecf20Sopenharmony_ci int ret; 37668c2ecf20Sopenharmony_ci u64 rem = 0; 37678c2ecf20Sopenharmony_ci 37688c2ecf20Sopenharmony_ci *trimmed = 0; 37698c2ecf20Sopenharmony_ci 37708c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 37718c2ecf20Sopenharmony_ci if (block_group->removed) { 37728c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 37738c2ecf20Sopenharmony_ci return 0; 37748c2ecf20Sopenharmony_ci } 37758c2ecf20Sopenharmony_ci btrfs_freeze_block_group(block_group); 37768c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 37778c2ecf20Sopenharmony_ci 37788c2ecf20Sopenharmony_ci ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, false); 37798c2ecf20Sopenharmony_ci if (ret) 37808c2ecf20Sopenharmony_ci goto out; 37818c2ecf20Sopenharmony_ci 37828c2ecf20Sopenharmony_ci ret = trim_bitmaps(block_group, trimmed, start, end, minlen, 0, false); 37838c2ecf20Sopenharmony_ci div64_u64_rem(end, BITS_PER_BITMAP * ctl->unit, &rem); 37848c2ecf20Sopenharmony_ci /* If we ended in the middle of a bitmap, reset the trimming flag */ 37858c2ecf20Sopenharmony_ci if (rem) 37868c2ecf20Sopenharmony_ci reset_trimming_bitmap(ctl, offset_to_bitmap(ctl, end)); 37878c2ecf20Sopenharmony_ciout: 37888c2ecf20Sopenharmony_ci btrfs_unfreeze_block_group(block_group); 37898c2ecf20Sopenharmony_ci return ret; 37908c2ecf20Sopenharmony_ci} 37918c2ecf20Sopenharmony_ci 37928c2ecf20Sopenharmony_ciint btrfs_trim_block_group_extents(struct btrfs_block_group *block_group, 37938c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 37948c2ecf20Sopenharmony_ci bool async) 37958c2ecf20Sopenharmony_ci{ 37968c2ecf20Sopenharmony_ci int ret; 37978c2ecf20Sopenharmony_ci 37988c2ecf20Sopenharmony_ci *trimmed = 0; 37998c2ecf20Sopenharmony_ci 38008c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 38018c2ecf20Sopenharmony_ci if (block_group->removed) { 38028c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 38038c2ecf20Sopenharmony_ci return 0; 38048c2ecf20Sopenharmony_ci } 38058c2ecf20Sopenharmony_ci btrfs_freeze_block_group(block_group); 38068c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 38078c2ecf20Sopenharmony_ci 38088c2ecf20Sopenharmony_ci ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, async); 38098c2ecf20Sopenharmony_ci btrfs_unfreeze_block_group(block_group); 38108c2ecf20Sopenharmony_ci 38118c2ecf20Sopenharmony_ci return ret; 38128c2ecf20Sopenharmony_ci} 38138c2ecf20Sopenharmony_ci 38148c2ecf20Sopenharmony_ciint btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group, 38158c2ecf20Sopenharmony_ci u64 *trimmed, u64 start, u64 end, u64 minlen, 38168c2ecf20Sopenharmony_ci u64 maxlen, bool async) 38178c2ecf20Sopenharmony_ci{ 38188c2ecf20Sopenharmony_ci int ret; 38198c2ecf20Sopenharmony_ci 38208c2ecf20Sopenharmony_ci *trimmed = 0; 38218c2ecf20Sopenharmony_ci 38228c2ecf20Sopenharmony_ci spin_lock(&block_group->lock); 38238c2ecf20Sopenharmony_ci if (block_group->removed) { 38248c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 38258c2ecf20Sopenharmony_ci return 0; 38268c2ecf20Sopenharmony_ci } 38278c2ecf20Sopenharmony_ci btrfs_freeze_block_group(block_group); 38288c2ecf20Sopenharmony_ci spin_unlock(&block_group->lock); 38298c2ecf20Sopenharmony_ci 38308c2ecf20Sopenharmony_ci ret = trim_bitmaps(block_group, trimmed, start, end, minlen, maxlen, 38318c2ecf20Sopenharmony_ci async); 38328c2ecf20Sopenharmony_ci 38338c2ecf20Sopenharmony_ci btrfs_unfreeze_block_group(block_group); 38348c2ecf20Sopenharmony_ci 38358c2ecf20Sopenharmony_ci return ret; 38368c2ecf20Sopenharmony_ci} 38378c2ecf20Sopenharmony_ci 38388c2ecf20Sopenharmony_ci/* 38398c2ecf20Sopenharmony_ci * Find the left-most item in the cache tree, and then return the 38408c2ecf20Sopenharmony_ci * smallest inode number in the item. 38418c2ecf20Sopenharmony_ci * 38428c2ecf20Sopenharmony_ci * Note: the returned inode number may not be the smallest one in 38438c2ecf20Sopenharmony_ci * the tree, if the left-most item is a bitmap. 38448c2ecf20Sopenharmony_ci */ 38458c2ecf20Sopenharmony_ciu64 btrfs_find_ino_for_alloc(struct btrfs_root *fs_root) 38468c2ecf20Sopenharmony_ci{ 38478c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = fs_root->free_ino_ctl; 38488c2ecf20Sopenharmony_ci struct btrfs_free_space *entry = NULL; 38498c2ecf20Sopenharmony_ci u64 ino = 0; 38508c2ecf20Sopenharmony_ci 38518c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 38528c2ecf20Sopenharmony_ci 38538c2ecf20Sopenharmony_ci if (RB_EMPTY_ROOT(&ctl->free_space_offset)) 38548c2ecf20Sopenharmony_ci goto out; 38558c2ecf20Sopenharmony_ci 38568c2ecf20Sopenharmony_ci entry = rb_entry(rb_first(&ctl->free_space_offset), 38578c2ecf20Sopenharmony_ci struct btrfs_free_space, offset_index); 38588c2ecf20Sopenharmony_ci 38598c2ecf20Sopenharmony_ci if (!entry->bitmap) { 38608c2ecf20Sopenharmony_ci ino = entry->offset; 38618c2ecf20Sopenharmony_ci 38628c2ecf20Sopenharmony_ci unlink_free_space(ctl, entry); 38638c2ecf20Sopenharmony_ci entry->offset++; 38648c2ecf20Sopenharmony_ci entry->bytes--; 38658c2ecf20Sopenharmony_ci if (!entry->bytes) 38668c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, entry); 38678c2ecf20Sopenharmony_ci else 38688c2ecf20Sopenharmony_ci link_free_space(ctl, entry); 38698c2ecf20Sopenharmony_ci } else { 38708c2ecf20Sopenharmony_ci u64 offset = 0; 38718c2ecf20Sopenharmony_ci u64 count = 1; 38728c2ecf20Sopenharmony_ci int ret; 38738c2ecf20Sopenharmony_ci 38748c2ecf20Sopenharmony_ci ret = search_bitmap(ctl, entry, &offset, &count, true); 38758c2ecf20Sopenharmony_ci /* Logic error; Should be empty if it can't find anything */ 38768c2ecf20Sopenharmony_ci ASSERT(!ret); 38778c2ecf20Sopenharmony_ci 38788c2ecf20Sopenharmony_ci ino = offset; 38798c2ecf20Sopenharmony_ci bitmap_clear_bits(ctl, entry, offset, 1); 38808c2ecf20Sopenharmony_ci if (entry->bytes == 0) 38818c2ecf20Sopenharmony_ci free_bitmap(ctl, entry); 38828c2ecf20Sopenharmony_ci } 38838c2ecf20Sopenharmony_ciout: 38848c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 38858c2ecf20Sopenharmony_ci 38868c2ecf20Sopenharmony_ci return ino; 38878c2ecf20Sopenharmony_ci} 38888c2ecf20Sopenharmony_ci 38898c2ecf20Sopenharmony_cistruct inode *lookup_free_ino_inode(struct btrfs_root *root, 38908c2ecf20Sopenharmony_ci struct btrfs_path *path) 38918c2ecf20Sopenharmony_ci{ 38928c2ecf20Sopenharmony_ci struct inode *inode = NULL; 38938c2ecf20Sopenharmony_ci 38948c2ecf20Sopenharmony_ci spin_lock(&root->ino_cache_lock); 38958c2ecf20Sopenharmony_ci if (root->ino_cache_inode) 38968c2ecf20Sopenharmony_ci inode = igrab(root->ino_cache_inode); 38978c2ecf20Sopenharmony_ci spin_unlock(&root->ino_cache_lock); 38988c2ecf20Sopenharmony_ci if (inode) 38998c2ecf20Sopenharmony_ci return inode; 39008c2ecf20Sopenharmony_ci 39018c2ecf20Sopenharmony_ci inode = __lookup_free_space_inode(root, path, 0); 39028c2ecf20Sopenharmony_ci if (IS_ERR(inode)) 39038c2ecf20Sopenharmony_ci return inode; 39048c2ecf20Sopenharmony_ci 39058c2ecf20Sopenharmony_ci spin_lock(&root->ino_cache_lock); 39068c2ecf20Sopenharmony_ci if (!btrfs_fs_closing(root->fs_info)) 39078c2ecf20Sopenharmony_ci root->ino_cache_inode = igrab(inode); 39088c2ecf20Sopenharmony_ci spin_unlock(&root->ino_cache_lock); 39098c2ecf20Sopenharmony_ci 39108c2ecf20Sopenharmony_ci return inode; 39118c2ecf20Sopenharmony_ci} 39128c2ecf20Sopenharmony_ci 39138c2ecf20Sopenharmony_ciint create_free_ino_inode(struct btrfs_root *root, 39148c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 39158c2ecf20Sopenharmony_ci struct btrfs_path *path) 39168c2ecf20Sopenharmony_ci{ 39178c2ecf20Sopenharmony_ci return __create_free_space_inode(root, trans, path, 39188c2ecf20Sopenharmony_ci BTRFS_FREE_INO_OBJECTID, 0); 39198c2ecf20Sopenharmony_ci} 39208c2ecf20Sopenharmony_ci 39218c2ecf20Sopenharmony_ciint load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root) 39228c2ecf20Sopenharmony_ci{ 39238c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; 39248c2ecf20Sopenharmony_ci struct btrfs_path *path; 39258c2ecf20Sopenharmony_ci struct inode *inode; 39268c2ecf20Sopenharmony_ci int ret = 0; 39278c2ecf20Sopenharmony_ci u64 root_gen = btrfs_root_generation(&root->root_item); 39288c2ecf20Sopenharmony_ci 39298c2ecf20Sopenharmony_ci if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) 39308c2ecf20Sopenharmony_ci return 0; 39318c2ecf20Sopenharmony_ci 39328c2ecf20Sopenharmony_ci /* 39338c2ecf20Sopenharmony_ci * If we're unmounting then just return, since this does a search on the 39348c2ecf20Sopenharmony_ci * normal root and not the commit root and we could deadlock. 39358c2ecf20Sopenharmony_ci */ 39368c2ecf20Sopenharmony_ci if (btrfs_fs_closing(fs_info)) 39378c2ecf20Sopenharmony_ci return 0; 39388c2ecf20Sopenharmony_ci 39398c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 39408c2ecf20Sopenharmony_ci if (!path) 39418c2ecf20Sopenharmony_ci return 0; 39428c2ecf20Sopenharmony_ci 39438c2ecf20Sopenharmony_ci inode = lookup_free_ino_inode(root, path); 39448c2ecf20Sopenharmony_ci if (IS_ERR(inode)) 39458c2ecf20Sopenharmony_ci goto out; 39468c2ecf20Sopenharmony_ci 39478c2ecf20Sopenharmony_ci if (root_gen != BTRFS_I(inode)->generation) 39488c2ecf20Sopenharmony_ci goto out_put; 39498c2ecf20Sopenharmony_ci 39508c2ecf20Sopenharmony_ci ret = __load_free_space_cache(root, inode, ctl, path, 0); 39518c2ecf20Sopenharmony_ci 39528c2ecf20Sopenharmony_ci if (ret < 0) 39538c2ecf20Sopenharmony_ci btrfs_err(fs_info, 39548c2ecf20Sopenharmony_ci "failed to load free ino cache for root %llu", 39558c2ecf20Sopenharmony_ci root->root_key.objectid); 39568c2ecf20Sopenharmony_ciout_put: 39578c2ecf20Sopenharmony_ci iput(inode); 39588c2ecf20Sopenharmony_ciout: 39598c2ecf20Sopenharmony_ci btrfs_free_path(path); 39608c2ecf20Sopenharmony_ci return ret; 39618c2ecf20Sopenharmony_ci} 39628c2ecf20Sopenharmony_ci 39638c2ecf20Sopenharmony_ciint btrfs_write_out_ino_cache(struct btrfs_root *root, 39648c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 39658c2ecf20Sopenharmony_ci struct btrfs_path *path, 39668c2ecf20Sopenharmony_ci struct inode *inode) 39678c2ecf20Sopenharmony_ci{ 39688c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 39698c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; 39708c2ecf20Sopenharmony_ci int ret; 39718c2ecf20Sopenharmony_ci struct btrfs_io_ctl io_ctl; 39728c2ecf20Sopenharmony_ci bool release_metadata = true; 39738c2ecf20Sopenharmony_ci 39748c2ecf20Sopenharmony_ci if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) 39758c2ecf20Sopenharmony_ci return 0; 39768c2ecf20Sopenharmony_ci 39778c2ecf20Sopenharmony_ci memset(&io_ctl, 0, sizeof(io_ctl)); 39788c2ecf20Sopenharmony_ci ret = __btrfs_write_out_cache(root, inode, ctl, NULL, &io_ctl, trans); 39798c2ecf20Sopenharmony_ci if (!ret) { 39808c2ecf20Sopenharmony_ci /* 39818c2ecf20Sopenharmony_ci * At this point writepages() didn't error out, so our metadata 39828c2ecf20Sopenharmony_ci * reservation is released when the writeback finishes, at 39838c2ecf20Sopenharmony_ci * inode.c:btrfs_finish_ordered_io(), regardless of it finishing 39848c2ecf20Sopenharmony_ci * with or without an error. 39858c2ecf20Sopenharmony_ci */ 39868c2ecf20Sopenharmony_ci release_metadata = false; 39878c2ecf20Sopenharmony_ci ret = btrfs_wait_cache_io_root(root, trans, &io_ctl, path); 39888c2ecf20Sopenharmony_ci } 39898c2ecf20Sopenharmony_ci 39908c2ecf20Sopenharmony_ci if (ret) { 39918c2ecf20Sopenharmony_ci if (release_metadata) 39928c2ecf20Sopenharmony_ci btrfs_delalloc_release_metadata(BTRFS_I(inode), 39938c2ecf20Sopenharmony_ci inode->i_size, true); 39948c2ecf20Sopenharmony_ci btrfs_debug(fs_info, 39958c2ecf20Sopenharmony_ci "failed to write free ino cache for root %llu error %d", 39968c2ecf20Sopenharmony_ci root->root_key.objectid, ret); 39978c2ecf20Sopenharmony_ci } 39988c2ecf20Sopenharmony_ci 39998c2ecf20Sopenharmony_ci return ret; 40008c2ecf20Sopenharmony_ci} 40018c2ecf20Sopenharmony_ci 40028c2ecf20Sopenharmony_ci#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS 40038c2ecf20Sopenharmony_ci/* 40048c2ecf20Sopenharmony_ci * Use this if you need to make a bitmap or extent entry specifically, it 40058c2ecf20Sopenharmony_ci * doesn't do any of the merging that add_free_space does, this acts a lot like 40068c2ecf20Sopenharmony_ci * how the free space cache loading stuff works, so you can get really weird 40078c2ecf20Sopenharmony_ci * configurations. 40088c2ecf20Sopenharmony_ci */ 40098c2ecf20Sopenharmony_ciint test_add_free_space_entry(struct btrfs_block_group *cache, 40108c2ecf20Sopenharmony_ci u64 offset, u64 bytes, bool bitmap) 40118c2ecf20Sopenharmony_ci{ 40128c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = cache->free_space_ctl; 40138c2ecf20Sopenharmony_ci struct btrfs_free_space *info = NULL, *bitmap_info; 40148c2ecf20Sopenharmony_ci void *map = NULL; 40158c2ecf20Sopenharmony_ci enum btrfs_trim_state trim_state = BTRFS_TRIM_STATE_TRIMMED; 40168c2ecf20Sopenharmony_ci u64 bytes_added; 40178c2ecf20Sopenharmony_ci int ret; 40188c2ecf20Sopenharmony_ci 40198c2ecf20Sopenharmony_ciagain: 40208c2ecf20Sopenharmony_ci if (!info) { 40218c2ecf20Sopenharmony_ci info = kmem_cache_zalloc(btrfs_free_space_cachep, GFP_NOFS); 40228c2ecf20Sopenharmony_ci if (!info) 40238c2ecf20Sopenharmony_ci return -ENOMEM; 40248c2ecf20Sopenharmony_ci } 40258c2ecf20Sopenharmony_ci 40268c2ecf20Sopenharmony_ci if (!bitmap) { 40278c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 40288c2ecf20Sopenharmony_ci info->offset = offset; 40298c2ecf20Sopenharmony_ci info->bytes = bytes; 40308c2ecf20Sopenharmony_ci info->max_extent_size = 0; 40318c2ecf20Sopenharmony_ci ret = link_free_space(ctl, info); 40328c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 40338c2ecf20Sopenharmony_ci if (ret) 40348c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 40358c2ecf20Sopenharmony_ci return ret; 40368c2ecf20Sopenharmony_ci } 40378c2ecf20Sopenharmony_ci 40388c2ecf20Sopenharmony_ci if (!map) { 40398c2ecf20Sopenharmony_ci map = kmem_cache_zalloc(btrfs_free_space_bitmap_cachep, GFP_NOFS); 40408c2ecf20Sopenharmony_ci if (!map) { 40418c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 40428c2ecf20Sopenharmony_ci return -ENOMEM; 40438c2ecf20Sopenharmony_ci } 40448c2ecf20Sopenharmony_ci } 40458c2ecf20Sopenharmony_ci 40468c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 40478c2ecf20Sopenharmony_ci bitmap_info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 40488c2ecf20Sopenharmony_ci 1, 0); 40498c2ecf20Sopenharmony_ci if (!bitmap_info) { 40508c2ecf20Sopenharmony_ci info->bitmap = map; 40518c2ecf20Sopenharmony_ci map = NULL; 40528c2ecf20Sopenharmony_ci add_new_bitmap(ctl, info, offset); 40538c2ecf20Sopenharmony_ci bitmap_info = info; 40548c2ecf20Sopenharmony_ci info = NULL; 40558c2ecf20Sopenharmony_ci } 40568c2ecf20Sopenharmony_ci 40578c2ecf20Sopenharmony_ci bytes_added = add_bytes_to_bitmap(ctl, bitmap_info, offset, bytes, 40588c2ecf20Sopenharmony_ci trim_state); 40598c2ecf20Sopenharmony_ci 40608c2ecf20Sopenharmony_ci bytes -= bytes_added; 40618c2ecf20Sopenharmony_ci offset += bytes_added; 40628c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 40638c2ecf20Sopenharmony_ci 40648c2ecf20Sopenharmony_ci if (bytes) 40658c2ecf20Sopenharmony_ci goto again; 40668c2ecf20Sopenharmony_ci 40678c2ecf20Sopenharmony_ci if (info) 40688c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_cachep, info); 40698c2ecf20Sopenharmony_ci if (map) 40708c2ecf20Sopenharmony_ci kmem_cache_free(btrfs_free_space_bitmap_cachep, map); 40718c2ecf20Sopenharmony_ci return 0; 40728c2ecf20Sopenharmony_ci} 40738c2ecf20Sopenharmony_ci 40748c2ecf20Sopenharmony_ci/* 40758c2ecf20Sopenharmony_ci * Checks to see if the given range is in the free space cache. This is really 40768c2ecf20Sopenharmony_ci * just used to check the absence of space, so if there is free space in the 40778c2ecf20Sopenharmony_ci * range at all we will return 1. 40788c2ecf20Sopenharmony_ci */ 40798c2ecf20Sopenharmony_ciint test_check_exists(struct btrfs_block_group *cache, 40808c2ecf20Sopenharmony_ci u64 offset, u64 bytes) 40818c2ecf20Sopenharmony_ci{ 40828c2ecf20Sopenharmony_ci struct btrfs_free_space_ctl *ctl = cache->free_space_ctl; 40838c2ecf20Sopenharmony_ci struct btrfs_free_space *info; 40848c2ecf20Sopenharmony_ci int ret = 0; 40858c2ecf20Sopenharmony_ci 40868c2ecf20Sopenharmony_ci spin_lock(&ctl->tree_lock); 40878c2ecf20Sopenharmony_ci info = tree_search_offset(ctl, offset, 0, 0); 40888c2ecf20Sopenharmony_ci if (!info) { 40898c2ecf20Sopenharmony_ci info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 40908c2ecf20Sopenharmony_ci 1, 0); 40918c2ecf20Sopenharmony_ci if (!info) 40928c2ecf20Sopenharmony_ci goto out; 40938c2ecf20Sopenharmony_ci } 40948c2ecf20Sopenharmony_ci 40958c2ecf20Sopenharmony_cihave_info: 40968c2ecf20Sopenharmony_ci if (info->bitmap) { 40978c2ecf20Sopenharmony_ci u64 bit_off, bit_bytes; 40988c2ecf20Sopenharmony_ci struct rb_node *n; 40998c2ecf20Sopenharmony_ci struct btrfs_free_space *tmp; 41008c2ecf20Sopenharmony_ci 41018c2ecf20Sopenharmony_ci bit_off = offset; 41028c2ecf20Sopenharmony_ci bit_bytes = ctl->unit; 41038c2ecf20Sopenharmony_ci ret = search_bitmap(ctl, info, &bit_off, &bit_bytes, false); 41048c2ecf20Sopenharmony_ci if (!ret) { 41058c2ecf20Sopenharmony_ci if (bit_off == offset) { 41068c2ecf20Sopenharmony_ci ret = 1; 41078c2ecf20Sopenharmony_ci goto out; 41088c2ecf20Sopenharmony_ci } else if (bit_off > offset && 41098c2ecf20Sopenharmony_ci offset + bytes > bit_off) { 41108c2ecf20Sopenharmony_ci ret = 1; 41118c2ecf20Sopenharmony_ci goto out; 41128c2ecf20Sopenharmony_ci } 41138c2ecf20Sopenharmony_ci } 41148c2ecf20Sopenharmony_ci 41158c2ecf20Sopenharmony_ci n = rb_prev(&info->offset_index); 41168c2ecf20Sopenharmony_ci while (n) { 41178c2ecf20Sopenharmony_ci tmp = rb_entry(n, struct btrfs_free_space, 41188c2ecf20Sopenharmony_ci offset_index); 41198c2ecf20Sopenharmony_ci if (tmp->offset + tmp->bytes < offset) 41208c2ecf20Sopenharmony_ci break; 41218c2ecf20Sopenharmony_ci if (offset + bytes < tmp->offset) { 41228c2ecf20Sopenharmony_ci n = rb_prev(&tmp->offset_index); 41238c2ecf20Sopenharmony_ci continue; 41248c2ecf20Sopenharmony_ci } 41258c2ecf20Sopenharmony_ci info = tmp; 41268c2ecf20Sopenharmony_ci goto have_info; 41278c2ecf20Sopenharmony_ci } 41288c2ecf20Sopenharmony_ci 41298c2ecf20Sopenharmony_ci n = rb_next(&info->offset_index); 41308c2ecf20Sopenharmony_ci while (n) { 41318c2ecf20Sopenharmony_ci tmp = rb_entry(n, struct btrfs_free_space, 41328c2ecf20Sopenharmony_ci offset_index); 41338c2ecf20Sopenharmony_ci if (offset + bytes < tmp->offset) 41348c2ecf20Sopenharmony_ci break; 41358c2ecf20Sopenharmony_ci if (tmp->offset + tmp->bytes < offset) { 41368c2ecf20Sopenharmony_ci n = rb_next(&tmp->offset_index); 41378c2ecf20Sopenharmony_ci continue; 41388c2ecf20Sopenharmony_ci } 41398c2ecf20Sopenharmony_ci info = tmp; 41408c2ecf20Sopenharmony_ci goto have_info; 41418c2ecf20Sopenharmony_ci } 41428c2ecf20Sopenharmony_ci 41438c2ecf20Sopenharmony_ci ret = 0; 41448c2ecf20Sopenharmony_ci goto out; 41458c2ecf20Sopenharmony_ci } 41468c2ecf20Sopenharmony_ci 41478c2ecf20Sopenharmony_ci if (info->offset == offset) { 41488c2ecf20Sopenharmony_ci ret = 1; 41498c2ecf20Sopenharmony_ci goto out; 41508c2ecf20Sopenharmony_ci } 41518c2ecf20Sopenharmony_ci 41528c2ecf20Sopenharmony_ci if (offset > info->offset && offset < info->offset + info->bytes) 41538c2ecf20Sopenharmony_ci ret = 1; 41548c2ecf20Sopenharmony_ciout: 41558c2ecf20Sopenharmony_ci spin_unlock(&ctl->tree_lock); 41568c2ecf20Sopenharmony_ci return ret; 41578c2ecf20Sopenharmony_ci} 41588c2ecf20Sopenharmony_ci#endif /* CONFIG_BTRFS_FS_RUN_SANITY_TESTS */ 4159