[Cluster-devel] [PATCH 32/42] fsck.gfs2: don't remove buffers from the list when errors are found

rpeterso at redhat.com rpeterso at redhat.com
Mon Apr 8 14:41:04 UTC 2013


From: Bob Peterson <rpeterso at redhat.com>

Before this patch, if an error was encountered while marking the
data blocks, the blocks would be removed from the linked list.
Now that we've got "undo" functions, we need to be able to undo
the designations of those blocks, which means we need to keep those
buffers on the linked list so they're found later. If we don't,
the undo data block function won't process them, and therefore they'll
be marked as "data" blocks in the bitmap, but no files will reference
the blocks (because the error causes the inode to be deleted).
With this patch, the metadata that points to the faulty data is kept
on the linked list, and after the error is found, the undo function
will therefore find it and mark its blocks as "free".

rhbz#902920
---
 gfs2/fsck/metawalk.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 4e18a7b..3aa1398 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1383,7 +1383,7 @@ static int hdr_size(struct gfs2_buffer_head *bh, int height)
 int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 {
 	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
-	osi_list_t *list;
+	osi_list_t *list, *tmp;
 	struct gfs2_buffer_head *bh;
 	uint32_t height = ip->i_di.di_height;
 	int  i, head_size;
@@ -1423,23 +1423,16 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	if (ip->i_di.di_blocks > COMFORTABLE_BLKS)
 		last_reported_fblock = -10000000;
 
-	while (error >= 0 && !osi_list_empty(list)) {
+	for (tmp = list->next; error >= 0 && tmp != list; tmp = tmp->next) {
 		if (fsck_abort) {
 			free_metalist(ip, &metalist[0]);
 			return 0;
 		}
-		bh = osi_list_entry(list->next, struct gfs2_buffer_head,
-				    b_altlist);
-
+		bh = osi_list_entry(tmp, struct gfs2_buffer_head, b_altlist);
 		head_size = hdr_size(bh, height);
-		if (!head_size) {
-			if (bh == ip->i_bh)
-				osi_list_del(&bh->b_altlist);
-			else
-				brelse(bh);
+		if (!head_size)
 			continue;
-		}
-
+		
 		if (pass->check_data)
 			rc = check_data(ip, pass, bh, head_size,
 					&blks_checked);
-- 
1.7.11.7




More information about the Cluster-devel mailing list