gfs2-utils: master - fsck.gfs2: reprocess inodes when blocks are added

Bob Peterson rpeterso at fedoraproject.org
Mon May 20 16:18:08 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=782609bd24ee9be771952b77a3fbdf5097820eb1
Commit:        782609bd24ee9be771952b77a3fbdf5097820eb1
Parent:        39c9d28e4989ffd16cb8c5248c90424d34599c4b
Author:        Bob Peterson <rpeterso at redhat.com>
AuthorDate:    Fri Mar 8 10:12:16 2013 -0700
Committer:     Bob Peterson <rpeterso at redhat.com>
CommitterDate: Mon May 20 11:12:46 2013 -0500

fsck.gfs2: reprocess inodes when blocks are added

This patch adds several calls to reprocess_inode when functions
may have potentially added blocks to a dinode. This happens, for
example, when leaf blocks are split or new leaf blocks are added.
The purpose of reprocessing the inode is to properly mark the new
blocks in the fsck blockmap. If we don't, the new blocks may be
flagged as wrong in the bitmap, and set free in pass5.
---
 gfs2/fsck/metawalk.c |    6 ++++++
 gfs2/fsck/pass1.c    |   11 +++++++++++
 gfs2/fsck/pass2.c    |   15 +++++++++------
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index cb1ffa4..2f574bf 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1474,9 +1474,12 @@ int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass)
 {
 	struct gfs2_inode *ip;
 	int error = 0;
+	uint64_t cur_blks;
 
 	ip = fsck_load_inode(sdp, block);
 
+	cur_blks = ip->i_di.di_blocks;
+
 	if (ip->i_di.di_flags & GFS2_DIF_EXHASH)
 		error = check_leaf_blks(ip, pass);
 	else
@@ -1485,6 +1488,9 @@ int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass)
 	if (error < 0)
 		stack;
 
+	if (ip->i_di.di_blocks != cur_blks)
+		reprocess_inode(ip, _("Current"));
+
 	fsck_inode_put(&ip); /* does a brelse */
 	return error;
 }
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index e827a55..5137559 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1022,6 +1022,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 	struct block_count bc = {0};
 	long bad_pointers;
 	uint64_t block = ip->i_bh->b_blocknr;
+	uint64_t lf_blks = 0;
 
 	bad_pointers = 0L;
 
@@ -1083,8 +1084,18 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		}
 	}
 
+	if (lf_dip)
+		lf_blks = lf_dip->i_di.di_blocks;
+
 	pass1_fxns.private = &bc;
 	error = check_metatree(ip, &pass1_fxns);
+
+	/* Pass1 may have added some blocks to lost+found by virtue of leafs
+	   that were misplaced. If it did, we need to reprocess lost+found
+	   to correctly account for its blocks. */
+	if (lf_dip && lf_dip->i_di.di_blocks != lf_blks)
+		reprocess_inode(lf_dip, "lost+found");
+
 	if (fsck_abort || error < 0)
 		return 0;
 	if (error > 0) {
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 0b714d6..2336aa5 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -1448,7 +1448,7 @@ struct metawalk_fxns pass2_fxns = {
 static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 		     int builder(struct gfs2_sbd *sdp))
 {
-	uint64_t iblock = 0;
+	uint64_t iblock = 0, cur_blks;
 	struct dir_status ds = {0};
 	char *filename;
 	int filename_len;
@@ -1468,12 +1468,15 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 
 	pass2_fxns.private = (void *) &ds;
 	if (ds.q == gfs2_bad_block) {
+		cur_blks = sysinode->i_di.di_blocks;
 		/* First check that the directory's metatree is valid */
 		error = check_metatree(sysinode, &pass2_fxns);
 		if (error < 0) {
 			stack;
 			return error;
 		}
+		if (sysinode->i_di.di_blocks != cur_blks)
+			reprocess_inode(sysinode, _("System inode"));
 	}
 	error = check_dir(sysinode->i_sbd, iblock, &pass2_fxns);
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -1493,8 +1496,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 	if (!ds.dotdir) {
 		log_err( _("No '.' entry found for %s directory.\n"), dirname);
 		if (query( _("Is it okay to add '.' entry? (y/n) "))) {
-			uint64_t cur_blks = sysinode->i_di.di_blocks;
-
+			cur_blks = sysinode->i_di.di_blocks;
 			sprintf(tmp_name, ".");
 			filename_len = strlen(tmp_name); /* no trailing NULL */
 			if (!(filename = malloc(sizeof(char) * filename_len))) {
@@ -1585,7 +1587,7 @@ static inline int is_system_dir(struct gfs2_sbd *sdp, uint64_t block)
  */
 int pass2(struct gfs2_sbd *sdp)
 {
-	uint64_t dirblk;
+	uint64_t dirblk, cur_blks;
 	uint8_t q;
 	struct dir_status ds = {0};
 	struct gfs2_inode *ip;
@@ -1647,12 +1649,15 @@ int pass2(struct gfs2_sbd *sdp)
 			/* First check that the directory's metatree
 			 * is valid */
 			ip = fsck_load_inode(sdp, dirblk);
+			cur_blks = ip->i_di.di_blocks;
 			error = check_metatree(ip, &pass2_fxns);
 			fsck_inode_put(&ip);
 			if (error < 0) {
 				stack;
 				return error;
 			}
+			if (ip->i_di.di_blocks != cur_blks)
+				reprocess_inode(ip, "current");
 		}
 		error = check_dir(sdp, dirblk, &pass2_fxns);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
@@ -1711,8 +1716,6 @@ int pass2(struct gfs2_sbd *sdp)
 				(unsigned long long)dirblk);
 
 			if (query( _("Is it okay to add '.' entry? (y/n) "))) {
-				uint64_t cur_blks;
-
 				sprintf(tmp_name, ".");
 				filename_len = strlen(tmp_name); /* no trailing
 								    NULL */


More information about the cluster-commits mailing list