[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Cluster-devel] [GFS2 PATCH] GFS2: unlink performance patch



Hi,

This looks like a really nice speed up. Many thanks for sorting this
out. I've applied it to the -nmw tree,

Steve.

On Wed, 2011-02-23 at 16:11 -0500, Bob Peterson wrote:
> Hi,
> 
> This patch is a performance improvement to GFS2's unlink code.
> Rather than update the quota file and statfs file for every
> single block that's stripped off in unlink function do_strip,
> this patch keeps track and updates them once for every layer
> that's stripped.  This is done entirely inside the existing
> transaction, so there should be no risk of corruption.
> The other functions that deallocate blocks will be unaffected
> because they are using wrapper functions that do the same
> thing that they do today.
> 
> I tested this code on my roth cluster by creating 200
> files in a directory, each of which is 100MB, then on
> four nodes, I simultaneously deleted the files, thus competing
> for GFS2 resources (but different files).  The commands
> I used were:
> 
> [root roth-01]# time for i in `seq 1 4 200` ; do rm /mnt/gfs2/bigdir/gfs2.$i; done
> [root roth-02]# time for i in `seq 2 4 200` ; do rm /mnt/gfs2/bigdir/gfs2.$i; done
> [root roth-03]# time for i in `seq 3 4 200` ; do rm /mnt/gfs2/bigdir/gfs2.$i; done
> [root roth-05]# time for i in `seq 4 4 200` ; do rm /mnt/gfs2/bigdir/gfs2.$i; done
> 
> The performance increase was significant:
> 
>              roth-01     roth-02     roth-03     roth-05
>              ---------   ---------   ---------   ---------
> old: real    0m34.027    0m25.021s   0m23.906s   0m35.646s
> new: real    0m22.379s   0m24.362s   0m24.133s   0m18.562s
> 
> Total time spent deleting:
> old: 118.6s
> new:  89.4
> 
> For this particular case, this showed a 25% performance increase for
> GFS2 unlinks.
> 
> Regards,
> 
> Bob Peterson
> Red Hat File Systems
> 
> Signed-off-by: Bob Peterson <rpeterso redhat com> 
> 
> --
>  fs/gfs2/bmap.c |   20 +++++++++++++++-----
>  fs/gfs2/rgrp.c |   34 +++++++++++++++++++++++++++++++---
>  fs/gfs2/rgrp.h |    2 ++
>  3 files changed, 48 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
> index 3c4039d..ef3dc4b 100644
> --- a/fs/gfs2/bmap.c
> +++ b/fs/gfs2/bmap.c
> @@ -21,6 +21,7 @@
>  #include "meta_io.h"
>  #include "quota.h"
>  #include "rgrp.h"
> +#include "super.h"
>  #include "trans.h"
>  #include "dir.h"
>  #include "util.h"
> @@ -757,7 +758,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
>  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
>  	struct gfs2_rgrp_list rlist;
>  	u64 bn, bstart;
> -	u32 blen;
> +	u32 blen, btotal;
>  	__be64 *p;
>  	unsigned int rg_blocks = 0;
>  	int metadata;
> @@ -839,6 +840,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
>  
>  	bstart = 0;
>  	blen = 0;
> +	btotal = 0;
>  
>  	for (p = top; p < bottom; p++) {
>  		if (!*p)
> @@ -851,9 +853,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
>  		else {
>  			if (bstart) {
>  				if (metadata)
> -					gfs2_free_meta(ip, bstart, blen);
> +					__gfs2_free_meta(ip, bstart, blen);
>  				else
> -					gfs2_free_data(ip, bstart, blen);
> +					__gfs2_free_data(ip, bstart, blen);
> +
> +				btotal += blen;
>  			}
>  
>  			bstart = bn;
> @@ -865,11 +869,17 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
>  	}
>  	if (bstart) {
>  		if (metadata)
> -			gfs2_free_meta(ip, bstart, blen);
> +			__gfs2_free_meta(ip, bstart, blen);
>  		else
> -			gfs2_free_data(ip, bstart, blen);
> +			__gfs2_free_data(ip, bstart, blen);
> +
> +		btotal += blen;
>  	}
>  
> +	gfs2_statfs_change(sdp, 0, +btotal, 0);
> +	gfs2_quota_change(ip, -(s64)btotal, ip->i_inode.i_uid,
> +			  ip->i_inode.i_gid);
> +
>  	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
>  
>  	gfs2_dinode_out(ip, dibh->b_data);
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index 7293ea2..cf930cd 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -1602,7 +1602,7 @@ rgrp_error:
>   *
>   */
>  
> -void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen)
> +void __gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen)
>  {
>  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
>  	struct gfs2_rgrpd *rgd;
> @@ -1617,7 +1617,21 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen)
>  	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
>  
>  	gfs2_trans_add_rg(rgd);
> +}
>  
> +/**
> + * gfs2_free_data - free a contiguous run of data block(s)
> + * @ip: the inode these blocks are being freed from
> + * @bstart: first block of a run of contiguous blocks
> + * @blen: the length of the block run
> + *
> + */
> +
> +void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen)
> +{
> +	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> +
> +	__gfs2_free_data(ip, bstart, blen);
>  	gfs2_statfs_change(sdp, 0, +blen, 0);
>  	gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid);
>  }
> @@ -1630,7 +1644,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen)
>   *
>   */
>  
> -void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen)
> +void __gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen)
>  {
>  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
>  	struct gfs2_rgrpd *rgd;
> @@ -1645,10 +1659,24 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen)
>  	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
>  
>  	gfs2_trans_add_rg(rgd);
> +	gfs2_meta_wipe(ip, bstart, blen);
> +}
>  
> +/**
> + * gfs2_free_meta - free a contiguous run of data block(s)
> + * @ip: the inode these blocks are being freed from
> + * @bstart: first block of a run of contiguous blocks
> + * @blen: the length of the block run
> + *
> + */
> +
> +void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen)
> +{
> +	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> +
> +	__gfs2_free_meta(ip, bstart, blen);
>  	gfs2_statfs_change(sdp, 0, +blen, 0);
>  	gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid);
> -	gfs2_meta_wipe(ip, bstart, blen);
>  }
>  
>  void gfs2_unlink_di(struct inode *inode)
> diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
> index 50c2bb0..a80e303 100644
> --- a/fs/gfs2/rgrp.h
> +++ b/fs/gfs2/rgrp.h
> @@ -52,7 +52,9 @@ extern int gfs2_ri_update(struct gfs2_inode *ip);
>  extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n);
>  extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation);
>  
> +extern void __gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen);
>  extern void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen);
> +extern void __gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
>  extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
>  extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
>  extern void gfs2_unlink_di(struct inode *inode);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]