[Cluster-devel] [GFS2 PATCH] GFS2: Fix gfs2_log_write and eliminate gfs2_log_bmap
Steven Whitehouse
swhiteho at redhat.com
Mon Dec 4 12:22:49 UTC 2017
On 01/12/17 17:34, Bob Peterson wrote:
> Hi,
>
> Before this patch, tiny function gfs2_log_write called small function
> gfs2_log_bmap to determine which journal block to write. If function
> gfs2_log_bmap encountered a problem in its block mapping calculations,
> it would return a block number of -1 to indicate an error. This error
> was immediately ignored and forgotten: the caller went ahead and
> tried to write to the log anyway. This patch fixes the problem
> by checking the results of the block map calculations and doing
> an assert withdraw if an error occurs. It also eliminates function
> gfs2_log_bmap in favor of inlining the code to make the code more
> readable.
>
> This should improve overall journal integrity, as a precursor to
> log writing improvements we are planning.
>
> Signed-off-by: Bob Peterson <rpeterso at redhat.com>
> ---
> fs/gfs2/lops.c | 32 ++++++++++++++------------------
> 1 file changed, 14 insertions(+), 18 deletions(-)
>
> diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
> index 438933eb5a25..bac73cdaace8 100644
> --- a/fs/gfs2/lops.c
> +++ b/fs/gfs2/lops.c
> @@ -138,23 +138,6 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp)
> sdp->sd_log_flush_head = 0;
> }
>
> -static u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
> -{
> - unsigned int lbn = sdp->sd_log_flush_head;
> - struct gfs2_journal_extent *je;
> - u64 block;
> -
> - list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) {
> - if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) {
> - block = je->dblock + lbn - je->lblock;
> - gfs2_log_incr_head(sdp);
> - return block;
> - }
> - }
> -
> - return -1;
> -}
> -
> /**
> * gfs2_end_log_write_bh - end log write of pagecache data with buffers
> * @sdp: The superblock
> @@ -322,10 +305,23 @@ static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno)
> static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page,
> unsigned size, unsigned offset)
> {
> - u64 blkno = gfs2_log_bmap(sdp);
> struct bio *bio;
> + unsigned int lbn = sdp->sd_log_flush_head;
> + struct gfs2_journal_extent *je;
> + u64 blkno = 0;
> int ret;
>
> + /* determine the next block location in the log to be written */
> + list_for_each_entry(je, &sdp->sd_jdesc->extent_list, list) {
> + if ((lbn >= je->lblock) && (lbn < (je->lblock + je->blocks))) {
> + blkno = je->dblock + lbn - je->lblock;
> + gfs2_log_incr_head(sdp);
> + break;
> + }
> + }
> + if (gfs2_assert_withdraw(sdp, blkno != 0))
> + return;
> +
> bio = gfs2_log_get_bio(sdp, blkno);
> ret = bio_add_page(bio, page, size, offset);
> if (ret == 0) {
>
Again, I'm not sure that there is anything to be gained in readability
by inlining gfs2_log_bmap(). Why not just add the new error check in
that function?
Steve.
More information about the Cluster-devel
mailing list