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

Reply via email to