FAILED: patch "[PATCH] btrfs: convert count_max_extents() to use" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7d7672bc5d1038c745716c397d892d21e29de71c Mon Sep 17 00:00:00 2001
From: Naohiro Aota <[email protected]>
Date: Sat, 9 Jul 2022 08:18:41 +0900
Subject: [PATCH] btrfs: convert count_max_extents() to use
fs_info->max_extent_size
If count_max_extents() uses BTRFS_MAX_EXTENT_SIZE to calculate the number of extents needed, btrfs release the metadata reservation too much on its way to write out the data.
Now that BTRFS_MAX_EXTENT_SIZE is replaced with fs_info->max_extent_size, convert count_max_extents() to use it instead, and fix the calculation of the metadata reservation.
fs/btrfs/ctree.h +13 -8
@@ -107,14 +107,6 @@ struct btrfs_ioctl_encoded_io_args;#define BTRFS_STAT_CURR 0#define BTRFS_STAT_PREV 1 -/* -* Count how many BTRFS_MAX_EXTENT_SIZE cover the @size -*/ -static inline u32 count_max_extents (u64 size) -{ -return div_u64 (size +BTRFS_MAX_EXTENT_SIZE -1 ,BTRFS_MAX_EXTENT_SIZE ); -} -static inline unsigned long btrfs_chunk_item_size (int num_stripes) {BUG_ON (num_stripes ==0 );
@@ -4058,6 +4050,19 @@ static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)return fs_info->zone_size >0 ; } +/* +* Count how many fs_info->max_extent_size cover the @size +*/ +static inline u32 count_max_extents (struct btrfs_fs_info *fs_info,u64 size) +{ +#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS +if (!fs_info) +return div_u64 (size +BTRFS_MAX_EXTENT_SIZE -1 ,BTRFS_MAX_EXTENT_SIZE ); +#endif + +return div_u64 (size + fs_info->max_extent_size -1 , fs_info->max_extent_size); +} +static inline bool btrfs_is_data_reloc_root (const struct btrfs_root *root) {return root->root_key.objectid ==BTRFS_DATA_RELOC_TREE_OBJECTID ;
fs/btrfs/delalloc-space.c +3 -3
@@ -273,7 +273,7 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info, u64 num_bytes, u64 disk_num_bytes, u64 *meta_reserve, u64 *qgroup_reserve) { - u64 nr_extents = count_max_extents(num_bytes); + u64 nr_extents = count_max_extents(fs_info, num_bytes);u64 csum_leaves =btrfs_csum_bytes_to_leaves (fs_info, disk_num_bytes);u64 inode_update =btrfs_calc_metadata_size (fs_info,1 );
@@ -350,7 +350,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,* needs to free the reservation we just made. */ spin_lock (&inode->lock); - nr_extents =count_max_extents (num_bytes); + nr_extents =count_max_extents (fs_info, num_bytes);btrfs_mod_outstanding_extents (inode, nr_extents); inode->csum_bytes += disk_num_bytes;btrfs_calculate_inode_block_rsv_size (fs_info, inode);
@@ -413,7 +413,7 @@ void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes)unsigned num_extents;spin_lock (&inode->lock); - num_extents =count_max_extents (num_bytes); + num_extents =count_max_extents (fs_info, num_bytes);btrfs_mod_outstanding_extents (inode, -num_extents);btrfs_calculate_inode_block_rsv_size (fs_info, inode);spin_unlock (&inode->lock);
fs/btrfs/inode.c +8 -8
@@ -2218,10 +2218,10 @@ void btrfs_split_delalloc_extent(struct inode *inode,* applies here, just in reverse. */ new_size = orig->end - split +1 ; - num_extents =count_max_extents (new_size); + num_extents =count_max_extents (fs_info, new_size); new_size = split - orig->start; - num_extents +=count_max_extents (new_size); -if (count_max_extents (size) >= num_extents) + num_extents +=count_max_extents (fs_info, new_size); +if (count_max_extents (fs_info, size) >= num_extents)return ; }
@@ -2278,10 +2278,10 @@ void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,* this case. */ old_size = other->end - other->start +1 ; - num_extents =count_max_extents (old_size); + num_extents =count_max_extents (fs_info, old_size); old_size = new->end - new->start +1 ; - num_extents +=count_max_extents (old_size); -if (count_max_extents (new_size) >= num_extents) + num_extents +=count_max_extents (fs_info, old_size); +if (count_max_extents (fs_info, new_size) >= num_extents)return ;spin_lock (&BTRFS_I (inode)->lock);
@@ -2360,7 +2360,7 @@ void btrfs_set_delalloc_extent(struct inode *inode, struct extent_state *state,if (!(state->state &EXTENT_DELALLOC ) && (bits &EXTENT_DELALLOC )) {struct btrfs_root *root =BTRFS_I (inode)->root;u64 len = state->end +1 - state->start; -u32 num_extents =count_max_extents (len); +u32 num_extents =count_max_extents (fs_info, len);bool do_list = !btrfs_is_free_space_inode (BTRFS_I (inode));spin_lock (&BTRFS_I (inode)->lock);
@@ -2402,7 +2402,7 @@ void btrfs_clear_delalloc_extent(struct inode *vfs_inode,struct btrfs_inode *inode =BTRFS_I (vfs_inode);struct btrfs_fs_info *fs_info =btrfs_sb (vfs_inode->i_sb);u64 len = state->end +1 - state->start; -u32 num_extents =count_max_extents (len); +u32 num_extents =count_max_extents (fs_info, len);if ((state->state &EXTENT_DEFRAG ) && (bits &EXTENT_DEFRAG )) {spin_lock (&inode->lock);