[Cluster-devel] [fsck.gfs2 v2 PATCH 29/40] fsck.gfs2: re-add a non-allocating repair_leaf to pass1

Bob Peterson rpeterso at redhat.com
Fri May 6 17:39:22 UTC 2016


In an earlier patch, the repair_leaf function was removed from
pass1. This turns out to cause a problem where there is leaf block
corruption. This patch adds back in a non-allocating function so
things work as they used to.

Signed-off-by: Bob Peterson <rpeterso at redhat.com>
---
 gfs2/fsck/pass1.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ee20b9e..6908ac7 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -142,6 +142,52 @@ static int delete_block(struct gfs2_inode *ip, uint64_t block,
 	return -1;
 }
 
+/* This is a pass1-specific leaf repair. Since we are not allowed to do
+ * block allocations, we do what we can. */
+static int pass1_repair_leaf(struct gfs2_inode *ip, uint64_t *leaf_no,
+			     int lindex, int ref_count, const char *msg)
+{
+	uint64_t *cpyptr;
+	char *padbuf;
+	int pad_size, i;
+
+	log_err( _("Directory Inode %llu (0x%llx) points to leaf %llu"
+		   " (0x%llx) %s.\n"),
+		 (unsigned long long)ip->i_di.di_num.no_addr,
+		 (unsigned long long)ip->i_di.di_num.no_addr,
+		 (unsigned long long)*leaf_no,
+		 (unsigned long long)*leaf_no, msg);
+	if (!query( _("Attempt to patch around it? (y/n) "))) {
+		log_err( _("Bad leaf left in place.\n"));
+		goto out;
+	}
+
+	padbuf = malloc(ref_count * sizeof(uint64_t));
+	cpyptr = (uint64_t *)padbuf;
+	for (i = 0; i < ref_count; i++) {
+		*cpyptr = 0;
+		cpyptr++;
+	}
+	pad_size = ref_count * sizeof(uint64_t);
+	log_err(_("Writing zeros to the hash table of directory %lld "
+		  "(0x%llx) at index: 0x%x for 0x%x pointers.\n"),
+		(unsigned long long)ip->i_di.di_num.no_addr,
+		(unsigned long long)ip->i_di.di_num.no_addr, lindex,
+		ref_count);
+	if (ip->i_sbd->gfs1)
+		gfs1_writei(ip, padbuf, lindex * sizeof(uint64_t), pad_size);
+	else
+		gfs2_writei(ip, padbuf, lindex * sizeof(uint64_t), pad_size);
+	free(padbuf);
+	log_err( _("Directory Inode %llu (0x%llx) patched.\n"),
+		 (unsigned long long)ip->i_di.di_num.no_addr,
+		 (unsigned long long)ip->i_di.di_num.no_addr);
+
+out:
+	*leaf_no = 0;
+	return 0;
+}
+
 struct metawalk_fxns pass1_fxns = {
 	.private = NULL,
 	.check_leaf = p1check_leaf,
@@ -153,6 +199,7 @@ struct metawalk_fxns pass1_fxns = {
 	.check_eattr_entry = check_eattr_entries,
 	.check_eattr_extentry = check_extended_leaf_eattr,
 	.big_file_msg = big_file_comfort,
+	.repair_leaf = pass1_repair_leaf,
 	.undo_check_meta = undo_check_metalist,
 	.undo_check_data = undo_check_data,
 	.delete_block = delete_block,
-- 
2.5.5




More information about the Cluster-devel mailing list