Prepare for removing the buffer head from struct gfs2_bitmap by adding a buffer head to struct gfs2_rgrpd for the resource group header.
Signed-off-by: Andreas Gruenbacher <agrue...@redhat.com> --- fs/gfs2/incore.h | 1 + fs/gfs2/rgrp.c | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 1dad2c54e7d8a..51eb41484e9af 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -99,6 +99,7 @@ struct gfs2_bitmap { struct gfs2_rgrpd { struct rb_node rd_node; /* Link with superblock */ struct gfs2_glock *rd_gl; /* Glock for this rgrp */ + struct buffer_head *rd_bh; u64 rd_addr; /* grp block disk address */ u64 rd_data0; /* first data location */ u32 rd_length; /* length of rgrp header in fs blocks */ diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index a86358afb33e7..339d6b064f1fc 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1139,7 +1139,7 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd) { struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; - struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data; + struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bh->b_data; int valid = 1; if (rgl->rl_flags != str->rg_flags) { @@ -1212,12 +1212,20 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) struct gfs2_glock *gl = rgd->rd_gl; unsigned int length = rgd->rd_length; struct gfs2_bitmap *bi; - unsigned int x, y; + unsigned int x = 0, y; int error; - if (rgd->rd_bits[0].bi_bh != NULL) + if (rgd->rd_bh != NULL) return 0; + error = gfs2_meta_read(gl, rgd->rd_addr, DIO_WAIT, 0, &rgd->rd_bh); + if (error) + return error; + if (gfs2_metatype_check(sdp, rgd->rd_bh, GFS2_METATYPE_RG)) { + error = -EIO; + goto fail; + } + for (x = 0; x < length; x++) { bi = rgd->rd_bits + x; error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, 0, &bi->bi_bh); @@ -1240,7 +1248,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { for (x = 0; x < length; x++) clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); - gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); + gfs2_rgrp_in(rgd, rgd->rd_bh->b_data); rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); rgd->rd_free_clone = rgd->rd_free; /* max out the rgrp allocation failure point */ @@ -1248,8 +1256,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) } if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) { rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd)); - gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, - rgd->rd_bits[0].bi_bh->b_data); + gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bh->b_data); } else if (sdp->sd_args.ar_rgrplvb) { if (!gfs2_rgrp_lvb_valid(rgd)){ @@ -1269,6 +1276,8 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) bi->bi_bh = NULL; gfs2_assert_warn(sdp, !bi->bi_clone); } + brelse(rgd->rd_bh); + rgd->rd_bh = NULL; return error; } @@ -1323,7 +1332,8 @@ void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd) bi->bi_bh = NULL; } } - + brelse(rgd->rd_bh); + rgd->rd_bh = NULL; } /** @@ -1423,7 +1433,6 @@ int gfs2_fitrim(struct file *filp, void __user *argp) struct inode *inode = file_inode(filp); struct gfs2_sbd *sdp = GFS2_SB(inode); struct request_queue *q = bdev_get_queue(sdp->sd_vfs->s_bdev); - struct buffer_head *bh; struct gfs2_rgrpd *rgd; struct gfs2_rgrpd *rgd_end; struct gfs2_holder gh; @@ -1485,10 +1494,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp) /* Mark rgrp as having been trimmed */ ret = gfs2_trans_begin(sdp, RES_RG_HDR, 0); if (ret == 0) { - bh = rgd->rd_bits[0].bi_bh; rgd->rd_flags |= GFS2_RGF_TRIMMED; - gfs2_trans_add_meta(rgd->rd_gl, bh); - gfs2_rgrp_out(rgd, bh->b_data); + gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bh); + gfs2_rgrp_out(rgd, rgd->rd_bh->b_data); gfs2_trans_end(sdp); } } @@ -2459,8 +2467,8 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, *generation = rbm.rgd->rd_igeneration++; } - gfs2_trans_add_meta(rbm.rgd->rd_gl, rbm.rgd->rd_bits[0].bi_bh); - gfs2_rgrp_out(rbm.rgd, rbm.rgd->rd_bits[0].bi_bh->b_data); + gfs2_trans_add_meta(rbm.rgd->rd_gl, rbm.rgd->rd_bh); + gfs2_rgrp_out(rbm.rgd, rbm.rgd->rd_bh->b_data); gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); if (dinode) @@ -2498,8 +2506,8 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd, trace_gfs2_block_alloc(ip, rgd, bstart, blen, GFS2_BLKST_FREE); rgd->rd_free += blen; rgd->rd_flags &= ~GFS2_RGF_TRIMMED; - gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh); - gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bh); + gfs2_rgrp_out(rgd, rgd->rd_bh->b_data); /* Directories keep their data in the metadata address space */ if (meta || ip->i_depth) @@ -2537,8 +2545,8 @@ void gfs2_unlink_di(struct inode *inode) return; rgblk_free(sdp, rgd, blkno, 1, GFS2_BLKST_UNLINKED); trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED); - gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh); - gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bh); + gfs2_rgrp_out(rgd, rgd->rd_bh->b_data); be32_add_cpu(&rgd->rd_rgl->rl_unlinked, 1); } @@ -2552,8 +2560,8 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) rgd->rd_dinodes--; rgd->rd_free++; - gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh); - gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); + gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bh); + gfs2_rgrp_out(rgd, rgd->rd_bh->b_data); be32_add_cpu(&rgd->rd_rgl->rl_unlinked, -1); gfs2_statfs_change(sdp, 0, +1, -1); -- 2.20.1