From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Tue, 17 Apr 2007 16:01:47 +0100 Subject: [Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command In-Reply-To: <46239835.5070507@redhat.com> References: <46239835.5070507@redhat.com> Message-ID: <1176822107.1636.270.camel@quoit.chygwyn.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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); >