Add a new function gfs2_ordered_shrink() that is called when syncfs is run. This function runs through the ordered list of inodes and removes the ones that don't have any pages in need of writing.
Signed-off-by: Abhi Das <a...@redhat.com> --- fs/gfs2/log.c | 16 ++++++++++++++++ fs/gfs2/log.h | 1 + fs/gfs2/super.c | 4 +++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 0257704..6d618a1 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -537,6 +537,22 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) spin_unlock(&sdp->sd_ordered_lock); } +void gfs2_ordered_shrink(struct gfs2_sbd *sdp, int whence) +{ + struct gfs2_inode *ip, *tmp; + + spin_lock(&sdp->sd_ordered_lock); + list_for_each_entry_safe(ip, tmp, &sdp->sd_log_le_ordered, i_ordered) { + if (ip->i_inode.i_mapping->nrpages != 0) + continue; + if (test_and_clear_bit(GIF_ORDERED, &ip->i_flags)) { + list_del(&ip->i_ordered); + ord_stats_adjust(sdp, -1, whence); + } + } + spin_unlock(&sdp->sd_ordered_lock); +} + void gfs2_ordered_del_inode(struct gfs2_inode *ip, int whence) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index bf7729c..80c8861 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h @@ -90,6 +90,7 @@ static inline void gfs2_ordered_add_inode(struct gfs2_inode *ip) } } +extern void gfs2_ordered_shrink(struct gfs2_sbd *sdp, int whence); extern void gfs2_ordered_del_inode(struct gfs2_inode *ip, int whence); extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, unsigned int ssize); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ee15a50..773e98d 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -948,8 +948,10 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) struct gfs2_sbd *sdp = sb->s_fs_info; gfs2_quota_sync(sb, -1); - if (wait && sdp) + if (wait && sdp) { gfs2_log_flush(sdp, NULL); + gfs2_ordered_shrink(sdp, ORD_WHENCE_SYNCFS); + } return sdp->sd_log_error; } -- 2.4.11