cluster: STABLE3 - GFS2: fsck.gfs2 should fix the system statfs file

Bob Peterson rpeterso at fedoraproject.org
Thu Dec 3 16:29:30 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=537d4d1d9a0243feeea9606a00432406fa663f98
Commit:        537d4d1d9a0243feeea9606a00432406fa663f98
Parent:        3ece431ba45b191d345694ac2728d4044851cbda
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Thu Dec 3 10:17:26 2009 -0600
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Thu Dec 3 10:17:26 2009 -0600

GFS2: fsck.gfs2 should fix the system statfs file

This patch allows fsck.gfs2 to check the statfs file values
against the real size of the file system by running through
the resource group information.  If found to be incorrect,
it fixes the statfs file.  To facilitate this, the function
do_init in libgfs2 was broken apart into its constituent
pieces to build the inum file and statfs file and mkfs.gfs2
was changed to use the two functions that replace it.

rhbz#539337
---
 gfs2/fsck/main.c          |   70 ++++++++++++++++++++++++++++++++++++++++++++-
 gfs2/libgfs2/libgfs2.h    |    3 +-
 gfs2/libgfs2/structures.c |   60 +++++++++++++++++++-------------------
 gfs2/mkfs/main_mkfs.c     |    3 +-
 4 files changed, 103 insertions(+), 33 deletions(-)

diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index f74e09d..68e8428 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -259,6 +259,70 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 	return 0;
 }
 
+static void check_statfs(struct gfs2_sbd *sdp)
+{
+	osi_list_t *tmp;
+	struct rgrp_list *rgd;
+	struct gfs2_rindex *ri;
+	struct gfs2_statfs_change sc;
+	char buf[sizeof(struct gfs2_statfs_change)];
+	int count;
+
+	/* Read the current statfs values */
+	count = gfs2_readi(sdp->md.statfs, buf, 0,
+			   sdp->md.statfs->i_di.di_size);
+	if (count == sizeof(struct gfs2_statfs_change))
+		gfs2_statfs_change_in(&sc, buf);
+
+	/* Calculate the real values from the rgrp information */
+	sdp->blks_total = 0;
+	sdp->blks_alloced = 0;
+	sdp->dinodes_alloced = 0;
+
+	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+		ri = &rgd->ri;
+		sdp->blks_total += ri->ri_data;
+		sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
+		sdp->dinodes_alloced += rgd->rg.rg_dinodes;
+	}
+
+	/* See if they match */
+	if (sc.sc_total == sdp->blks_total &&
+	    sc.sc_free == (sdp->blks_total - sdp->blks_alloced) &&
+	    sc.sc_dinodes == sdp->dinodes_alloced) {
+		log_info( _("The statfs file is accurate.\n"));
+		return;
+	}
+	log_err( _("The statfs file is wrong:\n\n"));
+	log_err( _("Current statfs values:\n"));
+	log_err( _("blocks:  %lld (0x%llx)\n"),
+		sc.sc_total, sc.sc_total);
+	log_err( _("free:    %lld (0x%llx)\n"),
+		sc.sc_free, sc.sc_free);
+	log_err( _("dinodes: %lld (0x%llx)\n\n"),
+		sc.sc_dinodes, sc.sc_dinodes);
+
+	log_err( _("Calculated statfs values:\n"));
+	log_err( _("blocks:  %lld (0x%llx)\n"),
+		sdp->blks_total, sdp->blks_total);
+	log_err( _("free:    %lld (0x%llx)\n"),
+		sdp->blks_total - sdp->blks_alloced,
+		sdp->blks_total - sdp->blks_alloced);
+	log_err( _("dinodes: %lld (0x%llx)\n"),
+		sdp->dinodes_alloced, sdp->dinodes_alloced);
+
+	errors_found++;
+	if (!query(&opts, _("Okay to fix the master statfs file? (y/n)"))) {
+		log_err( _("The statfs file was not fixed.\n"));
+		return;
+	}
+
+	do_init_statfs(sdp);
+	log_err( _("The statfs file was fixed.\n"));
+	errors_corrected++;
+}
+
 int main(int argc, char **argv)
 {
 	struct gfs2_sbd sb;
@@ -384,6 +448,9 @@ int main(int argc, char **argv)
 		error = FSCK_CANCELED;
 	}
 	update_sys_files = (opts.no ? not_updated : updated);
+
+	check_statfs(sbp);
+
 	/* Free up our system inodes */
 	inode_put(sbp->md.inum, update_sys_files);
 	inode_put(sbp->md.statfs, update_sys_files);
@@ -398,8 +465,9 @@ int main(int argc, char **argv)
 	if (lf_dip)
 		inode_put(lf_dip, update_sys_files);
 
-	if (!opts.no)
+	if (!opts.no && errors_corrected)
 		log_notice( _("Writing changes to disk\n"));
+
 	bsync(&sbp->buf_list);
 	bsync(&sbp->nvbuf_list);
 	destroy(sbp);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3d7b28a..bc2507e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -687,7 +687,8 @@ extern int build_statfs(struct gfs2_sbd *sdp);
 extern int build_rindex(struct gfs2_sbd *sdp);
 extern int build_quota(struct gfs2_sbd *sdp);
 extern int build_root(struct gfs2_sbd *sdp);
-extern int do_init(struct gfs2_sbd *sdp);
+extern int do_init_inum(struct gfs2_sbd *sdp);
+extern int do_init_statfs(struct gfs2_sbd *sdp);
 extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
 extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
 extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 734efde..8e9ad86 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -368,42 +368,42 @@ int build_root(struct gfs2_sbd *sdp)
 	return 0;
 }
 
-int do_init(struct gfs2_sbd *sdp)
+int do_init_inum(struct gfs2_sbd *sdp)
 {
-	{
-		struct gfs2_inode *ip = sdp->md.inum;
-		uint64_t buf;
-		int count;
-
-		buf = cpu_to_be64(sdp->md.next_inum);
-		count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
-		if (count != sizeof(uint64_t))
-			return -1;
+	struct gfs2_inode *ip = sdp->md.inum;
+	uint64_t buf;
+	int count;
 
-		if (sdp->debug)
-			printf("\nNext Inum: %"PRIu64"\n",
-			       sdp->md.next_inum);
-	}
+	buf = cpu_to_be64(sdp->md.next_inum);
+	count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		return -1;
 
-	{
-		struct gfs2_inode *ip = sdp->md.statfs;
-		struct gfs2_statfs_change sc;
-		char buf[sizeof(struct gfs2_statfs_change)];
-		int count;
+	if (sdp->debug)
+		printf("\nNext Inum: %"PRIu64"\n",
+		       sdp->md.next_inum);
+	return 0;
+}
 
-		sc.sc_total = sdp->blks_total;
-		sc.sc_free = sdp->blks_total - sdp->blks_alloced;
-		sc.sc_dinodes = sdp->dinodes_alloced;
+int do_init_statfs(struct gfs2_sbd *sdp)
+{
+	struct gfs2_inode *ip = sdp->md.statfs;
+	struct gfs2_statfs_change sc;
+	char buf[sizeof(struct gfs2_statfs_change)];
+	int count;
 
-		gfs2_statfs_change_out(&sc, buf);
-		count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
-		if (count != sizeof(struct gfs2_statfs_change))
-			return -1;
+	sc.sc_total = sdp->blks_total;
+	sc.sc_free = sdp->blks_total - sdp->blks_alloced;
+	sc.sc_dinodes = sdp->dinodes_alloced;
 
-		if (sdp->debug) {
-			printf("\nStatfs:\n");
-			gfs2_statfs_change_print(&sc);
-		}
+	gfs2_statfs_change_out(&sc, buf);
+	count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
+	if (count != sizeof(struct gfs2_statfs_change))
+		return -1;
+
+	if (sdp->debug) {
+		printf("\nStatfs:\n");
+		gfs2_statfs_change_print(&sc);
 	}
 	return 0;
 }
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index ee43bbd..4c1d94f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -633,7 +633,8 @@ void main_mkfs(int argc, char *argv[])
 	build_rindex(sdp);
 	build_quota(sdp);
 
-	do_init(sdp);
+	do_init_inum(sdp);
+	do_init_statfs(sdp);
 
 	/* Cleanup */
 


More information about the cluster-commits mailing list