cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
@ 2007-04-16 15:37 Robert Peterson
  2007-04-17 15:01 ` Steven Whitehouse
  0 siblings, 1 reply; 2+ messages in thread
From: Robert Peterson @ 2007-04-16 15:37 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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);



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command
  2007-04-16 15:37 [Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command Robert Peterson
@ 2007-04-17 15:01 ` Steven Whitehouse
  0 siblings, 0 replies; 2+ messages in thread
From: Steven Whitehouse @ 2007-04-17 15:01 UTC (permalink / raw)
  To: cluster-devel.redhat.com

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);
> 



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-04-17 15:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-16 15:37 [Cluster-devel] [PATCH] bz 235430: GFS2: kernel changes needed to support new gfs2_grow command Robert Peterson
2007-04-17 15:01 ` Steven Whitehouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).