Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 97

gfs2-utils-0.1.62-28.el5.src.rpm

commit b68607cde920f70f38c595c35e91daf84802e1f3
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Thu Dec 3 09:13:51 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

diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 0b76790..5f30f12 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -269,6 +269,70 @@ int check_system_inodes(struct gfs2_sbd *sdp)
 	return 0;
 }
 
+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;
@@ -391,6 +455,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);
@@ -405,8 +472,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 1283353..7a505a1 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -715,7 +715,8 @@ void build_statfs(struct gfs2_sbd *sdp);
 void build_rindex(struct gfs2_sbd *sdp);
 void build_quota(struct gfs2_sbd *sdp);
 void build_root(struct gfs2_sbd *sdp);
-void do_init(struct gfs2_sbd *sdp);
+void do_init_inum(struct gfs2_sbd *sdp);
+void do_init_statfs(struct gfs2_sbd *sdp);
 int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
 int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format);
 int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index e5507ca..43a7e0f 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -378,43 +378,41 @@ build_root(struct gfs2_sbd *sdp)
 	}
 }
 
-void
-do_init(struct gfs2_sbd *sdp)
+void 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))
-			die("do_init (1)\n");
-
-		if (sdp->debug)
-			printf("\nNext Inum: %"PRIu64"\n",
-			       sdp->md.next_inum);
-	}
+	struct gfs2_inode *ip = sdp->md.inum;
+	uint64_t buf;
+	int count;
 
-	{
-		struct gfs2_inode *ip = sdp->md.statfs;
-		struct gfs2_statfs_change sc;
-		char buf[sizeof(struct gfs2_statfs_change)];
-		int count;
+	buf = cpu_to_be64(sdp->md.next_inum);
+	count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		die("do_init (1)\n");
 
-		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("\nNext Inum: %"PRIu64"\n",
+		       sdp->md.next_inum);
+}
 
-		gfs2_statfs_change_out(&sc, buf);
-		count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
-		if (count != sizeof(struct gfs2_statfs_change))
-			die("do_init (2)\n");
+void 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;
 
-		if (sdp->debug) {
-			printf("\nStatfs:\n");
-			gfs2_statfs_change_print(&sc);
-		}
+	sc.sc_total = sdp->blks_total;
+	sc.sc_free = sdp->blks_total - sdp->blks_alloced;
+	sc.sc_dinodes = sdp->dinodes_alloced;
+
+	gfs2_statfs_change_out(&sc, buf);
+	count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
+	if (count != sizeof(struct gfs2_statfs_change))
+		die("do_init (2)\n");
+
+	if (sdp->debug) {
+		printf("\nStatfs:\n");
+		gfs2_statfs_change_print(&sc);
 	}
 }
 
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 634b894..615a17c 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -498,7 +498,8 @@ main_mkfs(int argc, char *argv[])
 	build_rindex(sdp);
 	build_quota(sdp);
 
-	do_init(sdp);
+	do_init_inum(sdp);
+	do_init_statfs(sdp);
 
 	/* Cleanup */