[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