When the erofs cache decompression is disabled (EROFS_ZIP_CACHE_DISABLED), all pages in pcluster are freed right after decompression. There is no need to cache the pcluster as well and it can be freed.
Signed-off-by: Chunhai Guo <guochun...@vivo.com> --- fs/erofs/internal.h | 3 ++- fs/erofs/zdata.c | 4 ++-- fs/erofs/zutil.c | 32 +++++++++++++++++++------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index e768990bf20f..cc6a61a422d8 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -449,7 +449,8 @@ static inline void erofs_pagepool_add(struct page **pagepool, struct page *page) void erofs_release_pages(struct page **pagepool); #ifdef CONFIG_EROFS_FS_ZIP -void erofs_workgroup_put(struct erofs_workgroup *grp); +void erofs_workgroup_put(struct erofs_sb_info *sbi, + struct erofs_workgroup *grp); struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, pgoff_t index); struct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb, diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index 428ab617e0e4..03b939dc2943 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -924,7 +924,7 @@ static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe) * any longer if the pcluster isn't hosted by ourselves. */ if (fe->mode < Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE) - erofs_workgroup_put(&pcl->obj); + erofs_workgroup_put(EROFS_I_SB(fe->inode), &pcl->obj); fe->pcl = NULL; } @@ -1355,7 +1355,7 @@ static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, if (z_erofs_is_inline_pcluster(be.pcl)) z_erofs_free_pcluster(be.pcl); else - erofs_workgroup_put(&be.pcl->obj); + erofs_workgroup_put(EROFS_SB(io->sb), &be.pcl->obj); } } diff --git a/fs/erofs/zutil.c b/fs/erofs/zutil.c index 9b53883e5caf..4f5783cca5c6 100644 --- a/fs/erofs/zutil.c +++ b/fs/erofs/zutil.c @@ -284,18 +284,6 @@ static void __erofs_workgroup_free(struct erofs_workgroup *grp) erofs_workgroup_free_rcu(grp); } -void erofs_workgroup_put(struct erofs_workgroup *grp) -{ - if (lockref_put_or_lock(&grp->lockref)) - return; - - DBG_BUGON(__lockref_is_dead(&grp->lockref)); - if (grp->lockref.count == 1) - atomic_long_inc(&erofs_global_shrink_cnt); - --grp->lockref.count; - spin_unlock(&grp->lockref.lock); -} - static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, struct erofs_workgroup *grp) { @@ -310,7 +298,8 @@ static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, * the XArray. Otherwise some cached pages could be still attached to * the orphan old workgroup when the new one is available in the tree. */ - if (erofs_try_to_free_all_cached_folios(sbi, grp)) + if (!erofs_is_cache_disabled(sbi) + && erofs_try_to_free_all_cached_folios(sbi, grp)) goto out; /* @@ -329,6 +318,23 @@ static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi, return free; } +void erofs_workgroup_put(struct erofs_sb_info *sbi, struct erofs_workgroup *grp) +{ + if (lockref_put_or_lock(&grp->lockref)) + return; + + DBG_BUGON(__lockref_is_dead(&grp->lockref)); + if (--grp->lockref.count == 0) + atomic_long_inc(&erofs_global_shrink_cnt); + spin_unlock(&grp->lockref.lock); + + if (erofs_is_cache_disabled(sbi)) { + xa_lock(&sbi->managed_pslots); + erofs_try_to_release_workgroup(sbi, grp); + xa_unlock(&sbi->managed_pslots); + } +} + static unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi, unsigned long nr_shrink) { -- 2.25.1