[Cluster-devel] [RFC RHEL7 GFS2 PATCH 2/3] gfs2: try to free empty mapping inodes from ordered list

Steven Whitehouse swhiteho at redhat.com
Wed Dec 13 11:25:07 UTC 2017



On 12/12/17 17:22, Abhi Das wrote:
> 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 <adas at 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);
> +}
> +
So it is removing inodes with no pages at all.... we should also be able 
to remove inodes which have pages where all the pages are clean too. 
That is more tricky to test for though as there will be a race between 
that test and (re)dirtying the pages. This is a good start however.

Is it possible to add this in to one of the existing loops over the 
ordered inode list? If so then we can get the benefit without needing a 
separate pass over the list... maybe merged into the loop in 
gfs2_ordered_write() for example, so we simply remove items from the 
list at that point when nrpages == 0 ?

Steve.

>   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;
>   }
>   




More information about the Cluster-devel mailing list