Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 35adedb8830cf948b43b86231991124b > files > 179

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

commit f7bd730c35b34d89d4e38d37d0148fb05997b596
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Wed Aug 17 10:33:07 2011 -0500

    fsck.gfs2: Remove bad inodes from duplicate tree
    
    The problem was that if an inode was determined to be "bad" (lots of
    corruption) and its metadata blocks were invalidated in pass1, the
    "bad" block for the inode was set as "data" in the bitmap.  Later,
    that caused duplicate reference processing (pass1b) to not remove the
    block from the inode tree inside function check_n_fix_bitmap when the
    bad block was freed. Later still, in pass4, that caused the now
    deleted inode to be processed again, at which time it would reprocess
    the inode's metadata and free all blocks, including blocks that were
    duplicate-referenced by other inodes.  In other words, pass4 freed
    blocks out from under valid references when it should not have. This
    patch changes the bitmap type for "bad" blocks from "data" to
    "inode". That causes function check_n_fix_bitmap to try to remove the
    bad block from the inode tree, so pass4 never processes it by mistake.
    
    This patch also changes a few debug messages to make them shorter so
    that the output files aren't as big to search through.
    
    rhbz#877150

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 1c06253..b7fff1c 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -117,36 +117,28 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 		   output easier to debug. */
 		if (ip->i_di.di_num.no_addr == bblock) {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("%s inode found at block %lld "
-					 "(0x%llx): marking as '%s'\n"),
+				       _("%s inode found at block "
+					 "0x%llx: marking as '%s'\n"),
 				       btype, (unsigned long long)
 				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
 				       block_type_string(mark));
 		} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode %lld (0x%llx) references "
-					 "%s block %lld (0x%llx): "
+				       _("inode 0x%llx references "
+					 "%s block 0x%llx: "
 					 "marking as '%s'\n"),
 				       (unsigned long long)
 				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
 				       btype, (unsigned long long)bblock,
-				       (unsigned long long)bblock,
 				       block_type_string(mark));
 		} else {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode %lld (0x%llx) references "
-					 "%s block %lld (0x%llx): "
+				       _("inode 0x%llx references "
+					 "%s block 0x%llx: "
 					 "marking as '%s'\n"),
 				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
 				       ip->i_di.di_num.no_addr, btype,
 				       (unsigned long long)bblock,
-				       (unsigned long long)bblock,
 				       block_type_string(mark));
 		}
 	}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f92e29e..35c716f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -387,8 +387,12 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 	*bh = NULL;
 
 	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
+		/* The bad dinode should be invalidated later due to
+		   "unrecoverable" errors.  The inode itself should be
+		   set "free" and removed from the inodetree by
+		   undo_check_metalist. */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("itself"), gfs2_bad_block);
+				  _("bad block referencing"), gfs2_bad_block);
 		log_debug( _("Bad indirect block (invalid/out of range) "
 			     "found in inode %lld (0x%llx).\n"),
 			   (unsigned long long)ip->i_di.di_num.no_addr,
@@ -461,7 +465,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("itself"), gfs2_block_free);
+				  _("bad block referencing"), gfs2_block_free);
 		return 1;
 	}
 	if (S_ISDIR(ip->i_di.di_mode) && h == ip->i_di.di_height)