[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [PATCH 37/42] fsck.gfs2: don't invalidate files with duplicate data block refs



From: Bob Peterson <rpeterso redhat com>

Before this patch, whenever pass1 encountered a duplicated data block
pointer, it would mark the file as invalid. But if reason the block
was duplicated was due to a different bad inode, the inode with the
valid data block reference was still punished and deleted.

This patch adds an additional check to see if the previous reference
to the data block was as a _valid_ metadata block. If the previous
reference was as metadata, and the metadata checked out okay, then
it can't possibly be a data block for the second reference. In that
case, we know for a fact that the second reference is invalid. But
if the previous reference was also as data, the inode might be okay
and duplicate resolving in pass1b might sort it out and leave this
inode as the only valid reference. In that case, we should treat the
inode as valid, not invalid. So this patch basically treats duplicate
data block references as "innocent until proven guilty" rather than
just the opposite.

rhbz#902920
---
 gfs2/fsck/pass1.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 12c5795..74d5fb6 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -425,18 +425,32 @@ static int check_data(struct gfs2_inode *ip, uint64_t metablock,
 			log_err(_("from metadata block %llu (0x%llx)\n"),
 				(unsigned long long)metablock,
 				(unsigned long long)metablock);
-
+				
+		if (q >= gfs2_indir_blk && q <= gfs2_jdata) {
+			log_info(_("The block was processed earlier as valid "
+				   "metadata, so it can't possibly be "
+				   "data.\n"));
+			/* We still need to add a duplicate record here because
+			   when check_metatree tries to delete the inode, we
+			   can't have the "undo" functions freeing the block
+			   out from other the original referencing inode. */
+			add_duplicate_ref(ip, block, ref_as_data, 0,
+					  INODE_VALID);
+			return 1;
+		}
 		if (q != gfs2_meta_inval) {
 			log_info( _("Seems to be a normal duplicate; I'll "
 				    "sort it out in pass1b.\n"));
 			add_duplicate_ref(ip, block, ref_as_data, 0,
 					  INODE_VALID);
-			return 1;
+			/* This inode references the block as data. So if this
+			   all is validated, we want to keep this count. */
+			return 0;
 		}
 		log_info( _("The block was invalid as metadata but might be "
 			    "okay as data.  I'll sort it out in pass1b.\n"));
 		add_duplicate_ref(ip, block, ref_as_data, 0, INODE_VALID);
-		return 1;
+		return 0;
 	}
 	/* In gfs1, rgrp indirect blocks are marked in the bitmap as "meta".
 	   In gfs2, "meta" is only for dinodes. So here we dummy up the
-- 
1.7.11.7


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]