mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 05:44:11 +00:00
ext4: add a new helper to check if es must be kept
In the extent status tree, we have extents which we can just drop without issues and extents we must not drop - this depends on the extent's status - currently ext4_es_is_delayed() extents must stay, others may be dropped. A helper function is added to help determine if the current extent can be dropped, although only ext4_es_is_delayed() extents cannot be dropped currently. Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20230424033846.4732-3-libaokun1@huawei.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
de25d6e961
commit
9649eb18c6
1 changed files with 21 additions and 13 deletions
|
@ -446,6 +446,19 @@ static void ext4_es_list_del(struct inode *inode)
|
|||
spin_unlock(&sbi->s_es_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if we cannot fail to allocate memory for this extent_status
|
||||
* entry and cannot reclaim it until its status changes.
|
||||
*/
|
||||
static inline bool ext4_es_must_keep(struct extent_status *es)
|
||||
{
|
||||
/* fiemap, bigalloc, and seek_data/hole need to use it. */
|
||||
if (ext4_es_is_delayed(es))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct extent_status *
|
||||
ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len,
|
||||
ext4_fsblk_t pblk)
|
||||
|
@ -458,10 +471,8 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len,
|
|||
es->es_len = len;
|
||||
es->es_pblk = pblk;
|
||||
|
||||
/*
|
||||
* We don't count delayed extent because we never try to reclaim them
|
||||
*/
|
||||
if (!ext4_es_is_delayed(es)) {
|
||||
/* We never try to reclaim a must kept extent, so we don't count it. */
|
||||
if (!ext4_es_must_keep(es)) {
|
||||
if (!EXT4_I(inode)->i_es_shk_nr++)
|
||||
ext4_es_list_add(inode);
|
||||
percpu_counter_inc(&EXT4_SB(inode->i_sb)->
|
||||
|
@ -479,8 +490,8 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es)
|
|||
EXT4_I(inode)->i_es_all_nr--;
|
||||
percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_es_stats.es_stats_all_cnt);
|
||||
|
||||
/* Decrease the shrink counter when this es is not delayed */
|
||||
if (!ext4_es_is_delayed(es)) {
|
||||
/* Decrease the shrink counter when we can reclaim the extent. */
|
||||
if (!ext4_es_must_keep(es)) {
|
||||
BUG_ON(EXT4_I(inode)->i_es_shk_nr == 0);
|
||||
if (!--EXT4_I(inode)->i_es_shk_nr)
|
||||
ext4_es_list_del(inode);
|
||||
|
@ -851,7 +862,7 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
|
|||
if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb),
|
||||
128, EXT4_I(inode)))
|
||||
goto retry;
|
||||
if (err == -ENOMEM && !ext4_es_is_delayed(&newes))
|
||||
if (err == -ENOMEM && !ext4_es_must_keep(&newes))
|
||||
err = 0;
|
||||
|
||||
if (sbi->s_cluster_ratio > 1 && test_opt(inode->i_sb, DELALLOC) &&
|
||||
|
@ -1702,11 +1713,8 @@ static int es_do_reclaim_extents(struct ext4_inode_info *ei, ext4_lblk_t end,
|
|||
|
||||
(*nr_to_scan)--;
|
||||
node = rb_next(&es->rb_node);
|
||||
/*
|
||||
* We can't reclaim delayed extent from status tree because
|
||||
* fiemap, bigallic, and seek_data/hole need to use it.
|
||||
*/
|
||||
if (ext4_es_is_delayed(es))
|
||||
|
||||
if (ext4_es_must_keep(es))
|
||||
goto next;
|
||||
if (ext4_es_is_referenced(es)) {
|
||||
ext4_es_clear_referenced(es);
|
||||
|
@ -1770,7 +1778,7 @@ void ext4_clear_inode_es(struct inode *inode)
|
|||
while (node) {
|
||||
es = rb_entry(node, struct extent_status, rb_node);
|
||||
node = rb_next(node);
|
||||
if (!ext4_es_is_delayed(es)) {
|
||||
if (!ext4_es_must_keep(es)) {
|
||||
rb_erase(&es->rb_node, &tree->root);
|
||||
ext4_es_free_extent(inode, es);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue