GFS2: Speed up gfs2_rbm_from_block
PATCH 1/1 GFS2: Speed up gfs2_rbm_from_block
Hi,
This patch is a rewrite of function gfs2_rbm_from_block. Rather than looping to find the right bitmap, the code now does a few simple math calculations. This speeds up the function significantly.
Regards,
Bob Peterson
Red Hat File Systems
---
fs/gfs2/incore.h +1 -0
@@ -621,6 +621,7 @@ struct gfs2_sbd {u32 sd_hash_bsize_shift;u32 sd_hash_ptrs;/* Number of pointers in a hash block */ u32 sd_qc_per_block; +u32 sd_blocks_per_bitmap;u32 sd_max_dirres;/* Max blocks needed to add a directory entry */ u32 sd_max_height;/* Max height of a file's metadata tree */ u64 sd_heightsize[GFS2_MAX_META_HEIGHT +1 ];
fs/gfs2/ops_fstype.c +3 -0
@@ -278,6 +278,9 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -sizeof (struct gfs2_meta_header )) /sizeof (struct gfs2_quota_change ); + sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize - +sizeof (struct gfs2_meta_header )) + *GFS2_NBBY ;/* not the rgrp bitmap, subsequent bitmaps only */ /* Compute maximum reservation required to add a entry to a directory */
fs/gfs2/rgrp.c +12 -12
@@ -250,23 +250,23 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,static int gfs2_rbm_from_block (struct gfs2_rbm *rbm,u64 block) { -u64 rblock = block - rbm->rgd->rd_data0; -u32 goal = (u32 )rblock; -int x; +u32 x; -if (WARN_ON_ONCE (rblock >UINT_MAX )) -return -EINVAL ;if (block >= rbm->rgd->rd_data0 + rbm->rgd->rd_data)return -E2BIG ; -for (x =0 ; x < rbm->rgd->rd_length; x++) { - rbm->bi = rbm->rgd->rd_bits + x; -if (goal < (rbm->bi->bi_start + rbm->bi->bi_len) *GFS2_NBBY ) { - rbm->offset = goal - (rbm->bi->bi_start *GFS2_NBBY ); -break ; - } - } + rbm->bi = rbm->rgd->rd_bits; + rbm->offset = (u32)(block - rbm->rgd->rd_data0); +/* Check if the block is within the first block */ +if (rbm->offset < (rbm->bi->bi_start + rbm->bi->bi_len) *GFS2_NBBY ) +return 0 ; +/* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */ + rbm->offset += (sizeof (struct gfs2_rgrp ) - +sizeof (struct gfs2_meta_header )) *GFS2_NBBY ; + x = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap; + rbm->offset -= x * rbm->rgd->rd_sbd->sd_blocks_per_bitmap; + rbm->bi += x;return 0 ; }
PATCH 1/1 GFS2: Speed up gfs2_rbm_from_block
Hi,
Quoted 6 lines · Bob Peterson
Hi,
This patch is a rewrite of function
gfs2_rbm_from_block. Rather than looping to find the right bitmap, the code now does a few simple math calculations. This speeds up the function significantly.
It would be a good plan to include the timings that you showed me yesterday in the patch description to show the improvement this gives.
Quoted 38 lines
Regards,
Bob Peterson
Red Hat File SystemsSigned-off-by Bob Peterson <[email protected]>---
fs/gfs2/incore.h +1
-0@@ -621,6 +621,7 @@ struct gfs2_sbd {u32 sd_hash_bsize_shift;u32 sd_hash_ptrs;/* Number of pointers in a hash block */ u32 sd_qc_per_block; +u32 sd_blocks_per_bitmap;u32 sd_max_dirres;/* Max blocks needed to add a directory entry */ u32 sd_max_height;/* Max height of a file's metadata tree */ u64 sd_heightsize[GFS2_MAX_META_HEIGHT +1 ];fs/gfs2/ops_fstype.c +3
-0@@ -278,6 +278,9 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize -sizeof (struct gfs2_meta_header )) /sizeof (struct gfs2_quota_change ); + sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize - +sizeof (struct gfs2_meta_header )) + *GFS2_NBBY ;/* not the rgrp bitmap, subsequent bitmaps only */ /* Compute maximum reservation required to add a entry to a directory */ fs/gfs2/rgrp.c +0
-0
fs/gfs2/rgrp.c static u32 gfs2_bitfit(const u8 *buf, const unsigned int len, · line 258
Quoted 10 lines
fs/gfs2/rgrp.c +1
-5@@ -250,23 +250,23 @@ static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,static int gfs2_rbm_from_block (struct gfs2_rbm *rbm,u64 block) { -u64 rblock = block - rbm->rgd->rd_data0; -u32 goal = (u32 )rblock; -int x; +u32 x; -if (WARN_ON_ONCE (rblock >UINT_MAX )) -return -EINVAL ;
This test was intended to check for underflow, i.e. that the block number was less than rd_data0. I think it would be a good plan to retain such a test even though we should not see any blocks outside of the current bitmap.
Otherwise, it looks good,
Steve.
Quoted 26 lines
fs/gfs2/rgrp.c +11
-7if (block >= rbm->rgd->rd_data0 + rbm->rgd->rd_data)return -E2BIG ; -for (x =0 ; x < rbm->rgd->rd_length; x++) { - rbm->bi = rbm->rgd->rd_bits + x; -if (goal < (rbm->bi->bi_start + rbm->bi->bi_len) *GFS2_NBBY ) { - rbm->offset = goal - (rbm->bi->bi_start *GFS2_NBBY ); -break ; - } - } + rbm->bi = rbm->rgd->rd_bits; + rbm->offset = (u32)(block - rbm->rgd->rd_data0); +/* Check if the block is within the first block */ +if (rbm->offset < (rbm->bi->bi_start + rbm->bi->bi_len) *GFS2_NBBY ) +return 0 ; +/* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */ + rbm->offset += (sizeof (struct gfs2_rgrp ) - +sizeof (struct gfs2_meta_header )) *GFS2_NBBY ; + x = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap; + rbm->offset -= x * rbm->rgd->rd_sbd->sd_blocks_per_bitmap; + rbm->bi += x;return 0 ; }