[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