[Ocfs2-tools-devel] [PATCH 19/22] o2image: Make it read group_desc properly.

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


Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 o2image/o2image.c |   53 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/o2image/o2image.c b/o2image/o2image.c
index cf9f0dc..e66e362 100644
--- a/o2image/o2image.c
+++ b/o2image/o2image.c
@@ -45,6 +45,7 @@
 
 static errcode_t traverse_inode(ocfs2_filesys *ofs, uint64_t inode);
 char *program_name = NULL;
+uint64_t gb_blkno;
 
 static void usage(void)
 {
@@ -60,9 +61,36 @@ static errcode_t mark_localalloc_bits(ocfs2_filesys *ofs,
 	return 0;
 }
 
+static uint64_t get_block_from_group(ocfs2_filesys *ofs,
+				     struct ocfs2_group_desc *grp,
+				     int bpc, int suballoc, int bit_offset)
+{
+	int cpos, i;
+	struct ocfs2_extent_rec *rec;
+
+	if (!suballoc || !grp->bg_list.l_next_free_rec)
+		return grp->bg_blkno + bit_offset;
+
+	/* handle discontiguous group. */
+	cpos = bit_offset / bpc;
+	for (i = 0; i < grp->bg_list.l_next_free_rec; i++) {
+		rec = &grp->bg_list.l_recs[i];
+
+		if (rec->e_cpos <= cpos &&
+		    rec->e_cpos + rec->e_leaf_clusters > cpos)
+			break;
+	}
+
+	if (i == grp->bg_list.l_next_free_rec)
+		abort();
+
+	return rec->e_blkno + bit_offset -
+		ocfs2_clusters_to_blocks(ofs, rec->e_cpos);
+}
+
 static errcode_t traverse_group_desc(ocfs2_filesys *ofs,
 				     struct ocfs2_group_desc *grp,
-				     int dump_type)
+				     int dump_type, int bpc, int suballoc)
 {
 	errcode_t ret = 0;
 	uint64_t blkno;
@@ -70,11 +98,12 @@ static errcode_t traverse_group_desc(ocfs2_filesys *ofs,
 
 	blkno = grp->bg_blkno;
 	for (i = 1; i < grp->bg_bits; i++) {
+		blkno = get_block_from_group(ofs, grp, bpc, suballoc, i);
 		if ((dump_type == OCFS2_IMAGE_READ_INODE_YES) &&
 		    ocfs2_test_bit(i, grp->bg_bitmap))
-			ret = traverse_inode(ofs, (blkno + i));
+			ret = traverse_inode(ofs, blkno);
 		else
-			ocfs2_image_mark_bitmap(ofs, blkno + i);
+			ocfs2_image_mark_bitmap(ofs, blkno);
 	}
 	return ret;
 }
@@ -127,9 +156,10 @@ out:
 	return ret;
 }
 
-static errcode_t traverse_chains(ocfs2_filesys *ofs,
-				 struct ocfs2_chain_list *cl, int dump_type)
+static errcode_t traverse_chains(ocfs2_filesys *ofs, struct ocfs2_dinode *di,
+				 int dump_type)
 {
+	struct ocfs2_chain_list *cl = &(di->id2.i_chain);
 	struct ocfs2_group_desc *grp;
 	struct ocfs2_chain_rec *rec;
 	errcode_t ret = 0;
@@ -149,13 +179,16 @@ static errcode_t traverse_chains(ocfs2_filesys *ofs,
 		blkno = rec->c_blkno;
 		while (blkno) {
 			ocfs2_image_mark_bitmap(ofs, blkno);
-			ret = ocfs2_read_group_desc(ofs, blkno, buf, 0);
+			ret = ocfs2_read_group_desc(ofs, blkno, buf,
+						    di->i_blkno != gb_blkno);
 			if (ret)
 				goto out;
 
 			grp = (struct ocfs2_group_desc *)buf;
 			if (dump_type) {
-				ret = traverse_group_desc(ofs, grp, dump_type);
+				ret = traverse_group_desc(ofs, grp,
+						dump_type, cl->cl_bpc,
+						di->i_blkno != gb_blkno);
 				if (ret)
 					goto out;
 			}
@@ -231,7 +264,7 @@ static errcode_t traverse_inode(ocfs2_filesys *ofs, uint64_t inode)
 	if ((di->i_flags & OCFS2_LOCAL_ALLOC_FL))
 		ret = mark_localalloc_bits(ofs, &(di->id2.i_lab));
 	else if (di->i_flags & OCFS2_CHAIN_FL)
-		ret = traverse_chains(ofs, &(di->id2.i_chain), dump_type);
+		ret = traverse_chains(ofs, di, dump_type);
 	else if (di->i_flags & OCFS2_DEALLOC_FL)
 		ret = mark_dealloc_bits(ofs, &(di->id2.i_dealloc));
 	else
@@ -600,6 +633,10 @@ int main(int argc, char **argv)
 		exit(1);
 	}
 
+	ret = ocfs2_lookup_system_inode(ofs, GLOBAL_BITMAP_SYSTEM_INODE,
+					0, &gb_blkno);
+	if (ret)
+		return ret;
 	/*
 	 * If src_file is opened with OCFS2_FLAG_IMAGE_FILE, then no need to
 	 * allocate and initialize ocfs2_image_state. ocfs2_open would have
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list