[Ocfs2-tools-devel] [PATCH 18/22] fsck.ocfs2: Make pass0 aware of discontig block group.

Tao Ma tao.ma at oracle.com
Wed Mar 31 21:41:22 PDT 2010


Add a parameter 'suballocator' in chain_state so that
we can read/write group_desc properly when handling
group. Also make mark_group_used set the bitmap properly.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 fsck.ocfs2/pass0.c |   71 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/fsck.ocfs2/pass0.c b/fsck.ocfs2/pass0.c
index 5fc0cf3..40a15a9 100644
--- a/fsck.ocfs2/pass0.c
+++ b/fsck.ocfs2/pass0.c
@@ -68,6 +68,7 @@ struct chain_state {
 	uint32_t	cs_total_bits;
 	uint32_t	cs_chain_no;
 	uint16_t	cs_cpg;
+	int		cs_suballoc;
 };
 
 static void find_max_free_bits(struct ocfs2_group_desc *gd, int *max_free_bits)
@@ -95,7 +96,8 @@ static void find_max_free_bits(struct ocfs2_group_desc *gd, int *max_free_bits)
  * the specified allocator file.
  */
 static errcode_t check_group_parent(ocfs2_filesys *fs, uint64_t group,
-				    uint64_t ino, uint16_t chain,int *exist)
+				    uint64_t ino, uint16_t chain, int *exist,
+				    int suballoc)
 {
 	errcode_t ret;
 	uint64_t gd_blkno;
@@ -139,7 +141,8 @@ static errcode_t check_group_parent(ocfs2_filesys *fs, uint64_t group,
 			break;
 		}
 
-		ret = ocfs2_read_group_desc(fs, gd_blkno, gd_buf, 0);
+		ret = ocfs2_read_group_desc(fs, gd_blkno, gd_buf,
+					    suballoc);
 		if (ret)
 			goto out;
 		gd = (struct ocfs2_group_desc *)gd_buf;
@@ -190,7 +193,8 @@ static errcode_t repair_group_desc(o2fsck_state *ost,
 		int exist = 0;
 		ret = check_group_parent(ost->ost_fs, bg->bg_blkno,
 					 bg->bg_parent_dinode,
-					 bg->bg_chain, &exist);
+					 bg->bg_chain, &exist,
+					 cs->cs_suballoc);
 
 		/* If we finds that the group really exists in the specified
 		 * chain of the specified alloc inode, then this may be a
@@ -255,7 +259,7 @@ static errcode_t repair_group_desc(o2fsck_state *ost,
 
 	if (changed) {
 		ret = ocfs2_write_group_desc(ost->ost_fs, bg->bg_blkno,
-					     (char *)bg, 0);
+					     (char *)bg, cs->cs_suballoc);
 		if (ret) {
 			com_err(whoami, ret, "while writing a group "
 				"descriptor to block %"PRIu64" somewhere in "
@@ -279,7 +283,8 @@ out:
 static void unlink_group_desc(o2fsck_state *ost,
 			      struct ocfs2_dinode *di,
 			      struct ocfs2_group_desc *bg,
-			      uint64_t blkno)
+			      uint64_t blkno,
+			      int suballoc)
 {
 	struct ocfs2_chain_list *cl;
 	struct ocfs2_chain_rec *cr;
@@ -313,7 +318,7 @@ static void unlink_group_desc(o2fsck_state *ost,
 		next_desc = cr->c_blkno;
 		while(next_desc) {
 			ret = ocfs2_read_group_desc(ost->ost_fs, next_desc,
-						    (char *)link, 0);
+						    (char *)link, suballoc);
 			if (ret) {
 				com_err(whoami, ret, "while reading a "
 					"group descriptor from block %"PRIu64,
@@ -328,7 +333,8 @@ static void unlink_group_desc(o2fsck_state *ost,
 
 			link->bg_next_group = bg->bg_next_group;
 			ret = ocfs2_write_group_desc(ost->ost_fs, next_desc,
-						     (char *)link, 0);
+						     (char *)link,
+						     suballoc);
 			if (ret) {
 				com_err(whoami, ret, "while writing a group "
 					"descriptor to block %"PRIu64" "
@@ -380,18 +386,32 @@ out:
 }
 
 static void mark_group_used(o2fsck_state *ost, struct chain_state *cs,
-			    uint64_t blkno, int just_desc)
+			    uint64_t blkno, int just_desc,
+			    struct ocfs2_group_desc *desc)
 {
-	uint16_t clusters;
+	int i;
+	uint16_t clusters = 0;
 
 	if (just_desc)
 		clusters = 1;
-	else
+	else if (!cs->cs_suballoc || !desc || !desc->bg_list.l_next_free_rec)
 		clusters = cs->cs_cpg;
 
-	o2fsck_mark_clusters_allocated(ost, 
+	if (clusters) {
+		o2fsck_mark_clusters_allocated(ost,
 				ocfs2_blocks_to_clusters(ost->ost_fs, blkno),
 				clusters);
+		return;
+	}
+
+	/* Now check the discontiguous group case. */
+	for (i = 0; i < desc->bg_list.l_next_free_rec; i++) {
+		struct ocfs2_extent_rec *rec = &desc->bg_list.l_recs[i];
+
+		o2fsck_mark_clusters_allocated(ost,
+			ocfs2_blocks_to_clusters(ost->ost_fs, rec->e_blkno),
+			rec->e_leaf_clusters);
+	}
 }
 
 /*
@@ -497,13 +517,13 @@ static errcode_t check_chain(o2fsck_state *ost,
 					o2fsck_bitmap_clear(allowed, blkno,
 							    &was_set);
 					mark_group_used(ost, cs, bg1->bg_blkno,
-							allowed != NULL);
+							allowed != NULL, bg1);
 				} else if (forbidden)
 					o2fsck_bitmap_set(forbidden, blkno,
 							  &was_set);
 			} else
 				mark_group_used(ost, cs, bg1->bg_blkno,
-						allowed != NULL);
+						allowed != NULL, bg1);
 			blkno = bg1->bg_next_group;
 		}
 
@@ -537,7 +557,8 @@ static errcode_t check_chain(o2fsck_state *ost,
 			ocfs2_read_blocks(ost->ost_fs, blkno,
 					  blocks_per_group, pre_cache_buf);
 
-		ret = ocfs2_read_group_desc(ost->ost_fs, blkno, (char *)bg2, 0);
+		ret = ocfs2_read_group_desc(ost->ost_fs, blkno, (char *)bg2,
+					    cs->cs_suballoc);
 		if (ret == OCFS2_ET_BAD_GROUP_DESC_MAGIC) {
 			if (prompt(ost, PY, PR_CHAIN_LINK_MAGIC,
 				   "Chain %d in allocator at inode "
@@ -605,7 +626,8 @@ static errcode_t check_chain(o2fsck_state *ost,
 			bg1->bg_next_group = 0;
 			ret = ocfs2_write_group_desc(ost->ost_fs,
 					             bg1->bg_blkno,
-						     (char *)bg1, 0);
+						     (char *)bg1,
+						     cs->cs_suballoc);
 			if (ret) {
 				com_err(whoami, ret, "while writing a group "
 					"descriptor at depth %d in chain %d "
@@ -646,7 +668,8 @@ static errcode_t verify_chain_alloc(o2fsck_state *ost,
 				    char *buf1, char *buf2,
 				    char *pre_cache_buf,
 				    ocfs2_bitmap *allowed,
-				    ocfs2_bitmap *forbidden)
+				    ocfs2_bitmap *forbidden,
+				    int suballoc)
 {
 	struct chain_state cs = {0, };
 	struct ocfs2_chain_list *cl;
@@ -657,6 +680,8 @@ static errcode_t verify_chain_alloc(o2fsck_state *ost,
 	errcode_t ret = 0;
 	uint64_t chain_bytes;
 
+	cs.cs_suballoc = suballoc;
+
 	if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
 		   strlen(OCFS2_INODE_SIGNATURE))) {
 		printf("Allocator inode %"PRIu64" doesn't have an inode "
@@ -754,6 +779,7 @@ static errcode_t verify_chain_alloc(o2fsck_state *ost,
 		cs = (struct chain_state) {
 			.cs_chain_no = i,
 			.cs_cpg = cl->cl_cpg,
+			.cs_suballoc = suballoc,
 		};
 		ret = check_chain(ost, di, &cs, cr, buf1, buf2, pre_cache_buf,
 				  &changed, allowed, forbidden);
@@ -909,7 +935,8 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
 		o2fsck_bitmap_set(allowed, blkno, NULL);
 	}
 
-	ret = verify_chain_alloc(ost, di, buf1, buf2, NULL, allowed, forbidden);
+	ret = verify_chain_alloc(ost, di, buf1, buf2, NULL,
+				 allowed, forbidden, 0);
 	if (ret) {
 		com_err(whoami, ret, "while looking up chain allocator inode "
 			"%"PRIu64, (uint64_t)di->i_blkno);
@@ -927,7 +954,7 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
 			    "so shouldn't be in the allocator.  Remove it "
 			    "from the chain?", blkno)) {
 
-			mark_group_used(ost, &cs, blkno, 1);
+			mark_group_used(ost, &cs, blkno, 1, NULL);
 			continue;
 		}
 
@@ -939,7 +966,7 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
 			continue;
 		}
 
-		unlink_group_desc(ost, di, bg, blkno);
+		unlink_group_desc(ost, di, bg, blkno, 0);
 	}
 
 	/* find the blocks that we think should have been in the chains
@@ -1044,7 +1071,7 @@ static errcode_t verify_bitmap_descs(o2fsck_state *ost,
 			goto out;
 		}
 
-		mark_group_used(ost, &cs, bg->bg_blkno, 1);
+		mark_group_used(ost, &cs, bg->bg_blkno, 1, bg);
 	}
 
 out:
@@ -1236,7 +1263,7 @@ retry_bitmap:
 					 blocks + ost->ost_fs->fs_blocksize,
 					 blocks + 
 					 (ost->ost_fs->fs_blocksize * 2), 
-					 pre_cache_buf, NULL, NULL);
+					 pre_cache_buf, NULL, NULL, 1);
 
 		/* XXX maybe helped by the alternate super block */
 		if (ret)
@@ -1289,7 +1316,7 @@ retry_bitmap:
 					 blocks + ost->ost_fs->fs_blocksize,
 					 blocks + 
 					 (ost->ost_fs->fs_blocksize * 2), 
-					 pre_cache_buf, NULL, NULL);
+					 pre_cache_buf, NULL, NULL, 1);
 
 		/* XXX maybe helped by the alternate super block */
 		if (ret)
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list