On 30 June 2017 at 18:40, Bob Peterson <[email protected]> wrote:
> Hi,
>
> Before this patch, GFS2 remembered the last rgrp it used by way of
> a variable i_rgd. However, block allocations are made by way of a
> reservations structure, ip->i_res, which also has a rgrp pointers.
> These two values are at best redundant, and at worse, confuse the
> logic and make GFS2 maintain and use two possibly opposing values.
> The proper solution is to only use a single value. Since new block
> allocations should be kept close to the last reservation, it makes
> sense to only use the value in the reservations structure.
> Therefore, this patch removes i_rgd.
>
> Signed-off-by: Bob Peterson <[email protected]>
> ---
> diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
> index de42384..2ad003b 100644
> --- a/fs/gfs2/incore.h
> +++ b/fs/gfs2/incore.h
> @@ -400,7 +400,6 @@ struct gfs2_inode {
> struct gfs2_holder i_gh; /* for prepare/commit_write only */
> struct gfs2_qadata *i_qadata; /* quota allocation data */
> struct gfs2_blkreserv i_res; /* rgrp multi-block reservation */
> - struct gfs2_rgrpd *i_rgd;
> u64 i_goal; /* goal block for allocations */
> struct rw_semaphore i_rw_mutex;
> struct list_head i_ordered;
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index 7c9b6d2..ad62bfb 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -1971,8 +1971,9 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct
> gfs2_alloc_parms *ap)
> return -EINVAL;
> if (gfs2_rs_active(rs)) {
> begin = rs->rs_rbm.rgd;
> - } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) {
> - rs->rs_rbm.rgd = begin = ip->i_rgd;
> + } else if (rs->rs_rbm.rgd &&
> + rgrp_contains_block(rs->rs_rbm.rgd, ip->i_goal)) {
> + begin = rs->rs_rbm.rgd;
> } else {
> check_and_update_goal(ip);
> rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
> @@ -2033,8 +2034,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct
> gfs2_alloc_parms *ap)
> if (rs->rs_rbm.rgd->rd_free_clone >= ap->target ||
> (loops == 2 && ap->min_target &&
> rs->rs_rbm.rgd->rd_free_clone >= ap->min_target)) {
> - ip->i_rgd = rs->rs_rbm.rgd;
> - ap->allowed = ip->i_rgd->rd_free_clone;
> + ap->allowed = rs->rs_rbm.rgd->rd_free_clone;
> return 0;
> }
> check_rgrp:
> @@ -2311,7 +2311,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn,
> unsigned int *nblocks,
> {
> struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> struct buffer_head *dibh;
> - struct gfs2_rbm rbm = { .rgd = ip->i_rgd, };
> + struct gfs2_rbm rbm = { .rgd = ip->i_res.rs_rbm.rgd, };
> unsigned int ndata;
> u64 block; /* block, within the file system scope */
> int error;
> @@ -2540,15 +2540,16 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct
> gfs2_rgrp_list *rlist,
> if (gfs2_assert_warn(sdp, !rlist->rl_ghs))
> return;
>
> - if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, block))
> - rgd = ip->i_rgd;
> + if (ip->i_res.rs_rbm.rgd && rgrp_contains_block(ip->i_res.rs_rbm.rgd,
> + block))
> + rgd = ip->i_res.rs_rbm.rgd;
> else
> rgd = gfs2_blk2rgrpd(sdp, block, 1);
> if (!rgd) {
> fs_err(sdp, "rlist_add: no rgrp for block %llu\n", (unsigned
> long long)block);
> return;
> }
> - ip->i_rgd = rgd;
> + ip->i_res.rs_rbm.rgd = rgd;
>
> for (x = 0; x < rlist->rl_rgrps; x++)
> if (rlist->rl_rgd[x] == rgd)
> diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
> index fdedec3..c83fd9c 100644
> --- a/fs/gfs2/super.c
> +++ b/fs/gfs2/super.c
> @@ -1660,7 +1660,6 @@ static struct inode *gfs2_alloc_inode(struct
> super_block *sb)
> if (ip) {
> ip->i_flags = 0;
> ip->i_gl = NULL;
> - ip->i_rgd = NULL;
Oops, we want to initialize ip->i_res.rs_rbm.rgd here:
+ ip->i_res.rs_rbm.rgd = NULL;
> memset(&ip->i_res, 0, sizeof(ip->i_res));
> RB_CLEAR_NODE(&ip->i_res.rs_node);
> ip->i_rahead = 0;
> diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
> index 1e6e7da..ec0a68d 100644
> --- a/fs/gfs2/trans.h
> +++ b/fs/gfs2/trans.h
> @@ -30,9 +30,9 @@ struct gfs2_glock;
> * block, or all of the blocks in the rg, whichever is smaller */
> static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip,
> unsigned requested)
> {
> - if (requested < ip->i_rgd->rd_length)
> + if (requested < ip->i_res.rs_rbm.rgd->rd_length)
> return requested + 1;
> - return ip->i_rgd->rd_length;
> + return ip->i_res.rs_rbm.rgd->rd_length;
> }
>
> extern int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
Andreas