Loading fs/btrfs/ctree.h +13 −2 Original line number Diff line number Diff line Loading @@ -439,6 +439,8 @@ struct btrfs_space_info { struct list_head list; /* Protected by the spinlock 'lock'. */ struct list_head ro_bgs; struct list_head priority_tickets; struct list_head tickets; struct rw_semaphore groups_sem; /* for block groups in our same type */ Loading Loading @@ -2624,6 +2626,15 @@ enum btrfs_reserve_flush_enum { BTRFS_RESERVE_FLUSH_ALL, }; enum btrfs_flush_state { FLUSH_DELAYED_ITEMS_NR = 1, FLUSH_DELAYED_ITEMS = 2, FLUSH_DELALLOC = 3, FLUSH_DELALLOC_WAIT = 4, ALLOC_CHUNK = 5, COMMIT_TRANS = 6, }; int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len); int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes); void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len); Loading Loading @@ -2661,8 +2672,8 @@ int btrfs_block_rsv_refill(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, u64 min_reserved, enum btrfs_reserve_flush_enum flush); int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, struct btrfs_block_rsv *dst_rsv, u64 num_bytes); struct btrfs_block_rsv *dst_rsv, u64 num_bytes, int update_size); int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *dest, u64 num_bytes, int min_factor); Loading fs/btrfs/delayed-inode.c +25 −43 Original line number Diff line number Diff line Loading @@ -553,7 +553,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, dst_rsv = &root->fs_info->delayed_block_rsv; num_bytes = btrfs_calc_trans_metadata_size(root, 1); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); if (!ret) { trace_btrfs_space_reservation(root->fs_info, "delayed_item", item->key.objectid, Loading Loading @@ -597,6 +597,29 @@ static int btrfs_delayed_inode_reserve_metadata( num_bytes = btrfs_calc_trans_metadata_size(root, 1); /* * If our block_rsv is the delalloc block reserve then check and see if * we have our extra reservation for updating the inode. If not fall * through and try to reserve space quickly. * * We used to try and steal from the delalloc block rsv or the global * reserve, but we'd steal a full reservation, which isn't kind. We are * here through delalloc which means we've likely just cowed down close * to the leaf that contains the inode, so we would steal less just * doing the fallback inode update, so if we do end up having to steal * from the global block rsv we hopefully only steal one or two blocks * worth which is less likely to hurt us. */ if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { spin_lock(&BTRFS_I(inode)->lock); if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, &BTRFS_I(inode)->runtime_flags)) release = true; else src_rsv = NULL; spin_unlock(&BTRFS_I(inode)->lock); } /* * btrfs_dirty_inode will update the inode under btrfs_join_transaction * which doesn't reserve space for speed. This is a problem since we Loading Loading @@ -626,51 +649,10 @@ static int btrfs_delayed_inode_reserve_metadata( num_bytes, 1); } return ret; } else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { spin_lock(&BTRFS_I(inode)->lock); if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, &BTRFS_I(inode)->runtime_flags)) { spin_unlock(&BTRFS_I(inode)->lock); release = true; goto migrate; } spin_unlock(&BTRFS_I(inode)->lock); /* Ok we didn't have space pre-reserved. This shouldn't happen * too often but it can happen if we do delalloc to an existing * inode which gets dirtied because of the time update, and then * isn't touched again until after the transaction commits and * then we try to write out the data. First try to be nice and * reserve something strictly for us. If not be a pain and try * to steal from the delalloc block rsv. */ ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, BTRFS_RESERVE_NO_FLUSH); if (!ret) goto out; ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); if (!ret) goto out; if (btrfs_test_opt(root, ENOSPC_DEBUG)) { btrfs_debug(root->fs_info, "block rsv migrate returned %d", ret); WARN_ON(1); } /* * Ok this is a problem, let's just steal from the global rsv * since this really shouldn't happen that often. */ ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, dst_rsv, num_bytes); goto out; } migrate: ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); out: /* * Migrate only takes a reservation, it doesn't touch the size of the * block_rsv. This is to simplify people who don't normally have things Loading fs/btrfs/extent-tree.c +464 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes fs/btrfs/file.c +2 −2 Original line number Diff line number Diff line Loading @@ -2479,7 +2479,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); min_size, 0); BUG_ON(ret); trans->block_rsv = rsv; Loading Loading @@ -2522,7 +2522,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); rsv, min_size, 0); BUG_ON(ret); /* shouldn't happen */ trans->block_rsv = rsv; Loading fs/btrfs/inode.c +3 −4 Original line number Diff line number Diff line Loading @@ -5264,7 +5264,7 @@ void btrfs_evict_inode(struct inode *inode) if (steal_from_global) { if (!btrfs_check_space_for_delayed_refs(trans, root)) ret = btrfs_block_rsv_migrate(global_rsv, rsv, min_size); min_size, 0); else ret = -ENOSPC; } Loading Loading @@ -9116,7 +9116,7 @@ static int btrfs_truncate(struct inode *inode) /* Migrate the slack space for the truncate to our reserve */ ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); min_size, 0); BUG_ON(ret); /* Loading Loading @@ -9156,7 +9156,7 @@ static int btrfs_truncate(struct inode *inode) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); rsv, min_size, 0); BUG_ON(ret); /* shouldn't happen */ trans->block_rsv = rsv; } Loading @@ -9177,7 +9177,6 @@ static int btrfs_truncate(struct inode *inode) ret = btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root); } out: btrfs_free_block_rsv(root, rsv); Loading Loading
fs/btrfs/ctree.h +13 −2 Original line number Diff line number Diff line Loading @@ -439,6 +439,8 @@ struct btrfs_space_info { struct list_head list; /* Protected by the spinlock 'lock'. */ struct list_head ro_bgs; struct list_head priority_tickets; struct list_head tickets; struct rw_semaphore groups_sem; /* for block groups in our same type */ Loading Loading @@ -2624,6 +2626,15 @@ enum btrfs_reserve_flush_enum { BTRFS_RESERVE_FLUSH_ALL, }; enum btrfs_flush_state { FLUSH_DELAYED_ITEMS_NR = 1, FLUSH_DELAYED_ITEMS = 2, FLUSH_DELALLOC = 3, FLUSH_DELALLOC_WAIT = 4, ALLOC_CHUNK = 5, COMMIT_TRANS = 6, }; int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len); int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes); void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len); Loading Loading @@ -2661,8 +2672,8 @@ int btrfs_block_rsv_refill(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, u64 min_reserved, enum btrfs_reserve_flush_enum flush); int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, struct btrfs_block_rsv *dst_rsv, u64 num_bytes); struct btrfs_block_rsv *dst_rsv, u64 num_bytes, int update_size); int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *dest, u64 num_bytes, int min_factor); Loading
fs/btrfs/delayed-inode.c +25 −43 Original line number Diff line number Diff line Loading @@ -553,7 +553,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, dst_rsv = &root->fs_info->delayed_block_rsv; num_bytes = btrfs_calc_trans_metadata_size(root, 1); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); if (!ret) { trace_btrfs_space_reservation(root->fs_info, "delayed_item", item->key.objectid, Loading Loading @@ -597,6 +597,29 @@ static int btrfs_delayed_inode_reserve_metadata( num_bytes = btrfs_calc_trans_metadata_size(root, 1); /* * If our block_rsv is the delalloc block reserve then check and see if * we have our extra reservation for updating the inode. If not fall * through and try to reserve space quickly. * * We used to try and steal from the delalloc block rsv or the global * reserve, but we'd steal a full reservation, which isn't kind. We are * here through delalloc which means we've likely just cowed down close * to the leaf that contains the inode, so we would steal less just * doing the fallback inode update, so if we do end up having to steal * from the global block rsv we hopefully only steal one or two blocks * worth which is less likely to hurt us. */ if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { spin_lock(&BTRFS_I(inode)->lock); if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, &BTRFS_I(inode)->runtime_flags)) release = true; else src_rsv = NULL; spin_unlock(&BTRFS_I(inode)->lock); } /* * btrfs_dirty_inode will update the inode under btrfs_join_transaction * which doesn't reserve space for speed. This is a problem since we Loading Loading @@ -626,51 +649,10 @@ static int btrfs_delayed_inode_reserve_metadata( num_bytes, 1); } return ret; } else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) { spin_lock(&BTRFS_I(inode)->lock); if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED, &BTRFS_I(inode)->runtime_flags)) { spin_unlock(&BTRFS_I(inode)->lock); release = true; goto migrate; } spin_unlock(&BTRFS_I(inode)->lock); /* Ok we didn't have space pre-reserved. This shouldn't happen * too often but it can happen if we do delalloc to an existing * inode which gets dirtied because of the time update, and then * isn't touched again until after the transaction commits and * then we try to write out the data. First try to be nice and * reserve something strictly for us. If not be a pain and try * to steal from the delalloc block rsv. */ ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, BTRFS_RESERVE_NO_FLUSH); if (!ret) goto out; ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); if (!ret) goto out; if (btrfs_test_opt(root, ENOSPC_DEBUG)) { btrfs_debug(root->fs_info, "block rsv migrate returned %d", ret); WARN_ON(1); } /* * Ok this is a problem, let's just steal from the global rsv * since this really shouldn't happen that often. */ ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, dst_rsv, num_bytes); goto out; } migrate: ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); out: /* * Migrate only takes a reservation, it doesn't touch the size of the * block_rsv. This is to simplify people who don't normally have things Loading
fs/btrfs/extent-tree.c +464 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes
fs/btrfs/file.c +2 −2 Original line number Diff line number Diff line Loading @@ -2479,7 +2479,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); min_size, 0); BUG_ON(ret); trans->block_rsv = rsv; Loading Loading @@ -2522,7 +2522,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); rsv, min_size, 0); BUG_ON(ret); /* shouldn't happen */ trans->block_rsv = rsv; Loading
fs/btrfs/inode.c +3 −4 Original line number Diff line number Diff line Loading @@ -5264,7 +5264,7 @@ void btrfs_evict_inode(struct inode *inode) if (steal_from_global) { if (!btrfs_check_space_for_delayed_refs(trans, root)) ret = btrfs_block_rsv_migrate(global_rsv, rsv, min_size); min_size, 0); else ret = -ENOSPC; } Loading Loading @@ -9116,7 +9116,7 @@ static int btrfs_truncate(struct inode *inode) /* Migrate the slack space for the truncate to our reserve */ ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); min_size, 0); BUG_ON(ret); /* Loading Loading @@ -9156,7 +9156,7 @@ static int btrfs_truncate(struct inode *inode) } ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv, min_size); rsv, min_size, 0); BUG_ON(ret); /* shouldn't happen */ trans->block_rsv = rsv; } Loading @@ -9177,7 +9177,6 @@ static int btrfs_truncate(struct inode *inode) ret = btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root); } out: btrfs_free_block_rsv(root, rsv); Loading