[Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
Steven Whitehouse
swhiteho at redhat.com
Tue Apr 17 15:01:47 UTC 2007
Hi,
Looks good & applied to the -nmw git tree. Thanks,
Steve.
On Mon, 2007-04-16 at 10:37 -0500, Robert Peterson wrote:
> This patch addresses Bugzilla Bug 235430: GFS2: kernel changes needed
> to support new gfs2_grow command. This is against the -nmw git tree.
> This is what it does, in patch order:
>
> 1. First, in gfs2_statfs, it calls function check_rindex_version, which
> has been broken out of gfs2_rindex_hold. Without this, the "df"
> always gives the old statfs information until gfs2_rindex_hold is
> called next, which can happen, for instance, when a new file is
> created.
> 2. Function ri_update now keeps a total of the file system allocation
> information (Why not, as long as it's going through them all).
> 3. There's a new function, resync_statfs that checks for the statfs
> data being incorrect and adjusts it as a "local statfs change".
> This ensures it will get processed the next time the daemon goes
> to resync the statfs data.
> 4. As I said in point 1, the check_rindex_version has been broken
> out of gfs2_rindex_hold so it may be called from gfs2_statfs as
> well as gfs2_rindex_hold.
>
> The patch seems to work properly, at least on the few tests I did.
>
> Signed-off-by: Bob Peterson (rpeterso at redhat.com)
> ------
> fs/gfs2/ops_super.c | 3 ++
> fs/gfs2/rgrp.c | 80 ++++++++++++++++++++++++++++++++++++++++++---------
> fs/gfs2/rgrp.h | 1 +
> 3 files changed, 70 insertions(+), 14 deletions(-)
>
> diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
> index 485ce3d..8861ae0 100644
> --- a/fs/gfs2/ops_super.c
> +++ b/fs/gfs2/ops_super.c
> @@ -222,6 +222,9 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
> struct gfs2_statfs_change_host sc;
> int error;
>
> + error = check_rindex_version(sdp);
> + if (error)
> + return error;
> if (gfs2_tune_get(sdp, gt_statfs_slow))
> error = gfs2_statfs_slow(sdp, &sc);
> else
> diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
> index 1727f50..b4c33a5 100644
> --- a/fs/gfs2/rgrp.c
> +++ b/fs/gfs2/rgrp.c
> @@ -437,7 +437,8 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
> * Returns: 0 on successful update, error code otherwise
> */
>
> -static int gfs2_ri_update(struct gfs2_inode *ip)
> +static int gfs2_ri_update(struct gfs2_inode *ip,
> + struct gfs2_statfs_change_host *sc)
> {
> struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
> struct inode *inode = &ip->i_inode;
> @@ -454,6 +455,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
>
> clear_rgrpdi(sdp);
>
> + memset(sc, 0, sizeof(struct gfs2_statfs_change_host));
> file_ra_state_init(&ra_state, inode->i_mapping);
> for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
> loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
> @@ -491,6 +493,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
>
> rgd->rd_gl->gl_object = rgd;
> rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
> +
> + sc->sc_total += rgd->rd_ri.ri_data;
> + sc->sc_free += rgd->rd_rg.rg_free;
> + sc->sc_dinodes += rgd->rd_rg.rg_dinodes;
> }
>
> sdp->sd_rindex_vn = ip->i_gl->gl_vn;
> @@ -502,6 +508,61 @@ fail:
> }
>
> /**
> + * resync_statfs - Check if the statfs file has bad info and if so, adjust it
> + * based on what was totalled from the rindex,
> + * then let the daemon fix the file when it's scheduled next.
> + */
> +static void resync_statfs(struct gfs2_sbd *sdp,
> + struct gfs2_statfs_change_host *sc)
> +{
> + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
> + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
> +
> + if (sc->sc_total != m_sc->sc_total + l_sc->sc_total ||
> + sc->sc_free != m_sc->sc_free + l_sc->sc_free ||
> + sc->sc_dinodes != m_sc->sc_dinodes + l_sc->sc_dinodes) {
> + spin_lock(&sdp->sd_statfs_spin);
> + l_sc->sc_total = sc->sc_total - m_sc->sc_total;
> + l_sc->sc_free = sc->sc_free - m_sc->sc_free;
> + l_sc->sc_dinodes = sc->sc_dinodes - m_sc->sc_dinodes;
> + spin_unlock(&sdp->sd_statfs_spin);
> + }
> +}
> +
> +/**
> + * check_rindex_version - Check the rindex version number and resync
> + * if necessary.
> + * @sdp: The GFS2 superblock
> + *
> + * This makes sure that we're using the latest copy of the resource index
> + * special file, which might have been updated if someone expanded the
> + * filesystem (via gfs2_grow utility), which adds new resource groups.
> + *
> + */
> +
> +int check_rindex_version(struct gfs2_sbd *sdp)
> +{
> + struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
> + struct gfs2_glock *gl = ip->i_gl;
> + int error = 0;
> +
> + /* Read new copy from disk if we don't have the latest */
> + if (sdp->sd_rindex_vn != gl->gl_vn) {
> + struct gfs2_statfs_change_host sc;
> +
> + mutex_lock(&sdp->sd_rindex_mutex);
> + if (sdp->sd_rindex_vn != gl->gl_vn) {
> + error = gfs2_ri_update(ip, &sc);
> + }
> + mutex_unlock(&sdp->sd_rindex_mutex);
> + /* Check consistency and sync statfs. */
> + resync_statfs(sdp, &sc);
> + }
> +
> + return error;
> +}
> +
> +/**
> * gfs2_rindex_hold - Grab a lock on the rindex
> * @sdp: The GFS2 superblock
> * @ri_gh: the glock holder
> @@ -526,20 +587,11 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh)
> int error;
>
> error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh);
> - if (error)
> - return error;
> -
> - /* Read new copy from disk if we don't have the latest */
> - if (sdp->sd_rindex_vn != gl->gl_vn) {
> - mutex_lock(&sdp->sd_rindex_mutex);
> - if (sdp->sd_rindex_vn != gl->gl_vn) {
> - error = gfs2_ri_update(ip);
> - if (error)
> - gfs2_glock_dq_uninit(ri_gh);
> - }
> - mutex_unlock(&sdp->sd_rindex_mutex);
> + if (!error) {
> + error = check_rindex_version(sdp);
> + if (error)
> + gfs2_glock_dq_uninit(ri_gh);
> }
> -
> return error;
> }
>
> diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
> index b01e0cf..3978dae 100644
> --- a/fs/gfs2/rgrp.h
> +++ b/fs/gfs2/rgrp.h
> @@ -21,6 +21,7 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp);
> struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd);
>
> void gfs2_clear_rgrpd(struct gfs2_sbd *sdp);
> +int check_rindex_version(struct gfs2_sbd *sdp);
> int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh);
>
> int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd);
>
More information about the Cluster-devel
mailing list