bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
PATCH 1/1 bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
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(-)
fs/gfs2/ops_super.c +3 -0
@@ -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
fs/gfs2/rgrp.c +66 -14
111 lines not on this page · raw message
fs/gfs2/rgrp.h +1 -0
@@ -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);
PATCH 1/1 bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
Hi,
Looks good & applied to the -nmw git tree. Thanks,
Steve.
Quoted 175 lines · Robert Peterson
This patch addresses Bugzilla Bug 235430: GFS2: kernel changes needed to support new
gfs2_growcommand. This is against the -nmw git tree. This is what it does, in patch order:1. First, in
gfs2_statfs, it calls functioncheck_rindex_version, which has been broken out ofgfs2_rindex_hold. Without this, the "df" always gives the old statfs information untilgfs2_rindex_holdis called next, which can happen, for instance, when a new file is created.
2. Functionri_updatenow 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_statfsthat 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, thecheck_rindex_versionhas been broken out ofgfs2_rindex_holdso it may be called fromgfs2_statfsas well asgfs2_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(-)fs/gfs2/ops_super.c +3
-0@@ -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 fs/gfs2/rgrp.c +66
-14@@ -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; }fs/gfs2/rgrp.h +1
-0@@ -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);