[Ocfs2-tools-devel] [PATCH 18/20] fsck.ocfs2: Let pass1b handle discontig block group.
Tao Ma
tao.ma at oracle.com
Mon May 17 01:47:05 PDT 2010
In pass1b, in case we find duplicated clusters, we have
to handle the discontig block group.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
fsck.ocfs2/pass1b.c | 61 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/fsck.ocfs2/pass1b.c b/fsck.ocfs2/pass1b.c
index 3ca1d7d..0eb3e91 100644
--- a/fsck.ocfs2/pass1b.c
+++ b/fsck.ocfs2/pass1b.c
@@ -367,6 +367,7 @@ struct process_extents_context {
struct ocfs2_dinode *di;
errcode_t ret;
uint64_t global_bitmap_blkno;
+ char *extra_buf;
};
static errcode_t process_dup_clusters(struct process_extents_context *pc,
@@ -415,14 +416,44 @@ static int process_inode_chains(ocfs2_filesys *fs, uint64_t gd_blkno,
{
struct process_extents_context *pc = priv_data;
uint32_t clusters = pc->di->id2.i_chain.cl_cpg;
+ struct ocfs2_group_desc *gd;
+ int i;
if (pc->di->i_blkno == pc->global_bitmap_blkno)
clusters = 1;
- pc->ret = process_dup_clusters(pc,
- ocfs2_blocks_to_clusters(fs, gd_blkno),
- clusters, 0);
+ if (!ocfs2_supports_discontig_bg(OCFS2_RAW_SB(fs->fs_super)) ||
+ (pc->di->i_blkno == pc->global_bitmap_blkno)) {
+ pc->ret = process_dup_clusters(pc,
+ ocfs2_blocks_to_clusters(fs, gd_blkno),
+ clusters, 0);
+ goto out;
+ }
+
+ pc->ret = ocfs2_read_group_desc(fs, gd_blkno, pc->extra_buf);
+ if (pc->ret)
+ goto out;
+ gd = (struct ocfs2_group_desc *)pc->extra_buf;
+ if (!ocfs2_gd_is_discontig(gd)) {
+ pc->ret = process_dup_clusters(pc,
+ ocfs2_blocks_to_clusters(fs, gd_blkno),
+ clusters, 0);
+ goto out;
+ }
+
+ /* Now check the discontiguous group case. */
+ for (i = 0; i < gd->bg_list.l_next_free_rec; i++) {
+ struct ocfs2_extent_rec *rec = &gd->bg_list.l_recs[i];
+
+ pc->ret = process_dup_clusters(pc,
+ ocfs2_blocks_to_clusters(fs,
+ rec->e_blkno),
+ rec->e_leaf_clusters,
+ rec->e_cpos);
+ }
+
+out:
return pc->ret ? OCFS2_CHAIN_ERROR | OCFS2_CHAIN_ABORT : 0;
}
@@ -642,7 +673,8 @@ out:
static errcode_t pass1b_process_inode(o2fsck_state *ost,
struct dup_context *dct,
- uint64_t ino, struct ocfs2_dinode *di)
+ uint64_t ino, struct ocfs2_dinode *di,
+ char *extra_buf)
{
errcode_t ret = 0;
static uint64_t global_bitmap_blkno = 0;
@@ -650,6 +682,7 @@ static errcode_t pass1b_process_inode(o2fsck_state *ost,
.ost = ost,
.dct = dct,
.di = di,
+ .extra_buf = extra_buf,
};
/*
@@ -713,7 +746,7 @@ static errcode_t o2fsck_pass1b(o2fsck_state *ost, struct dup_context *dct)
{
errcode_t ret;
uint64_t blkno;
- char *buf;
+ char *buf = NULL, *extra_buf = NULL;
struct ocfs2_dinode *di;
ocfs2_inode_scan *scan;
ocfs2_filesys *fs = ost->ost_fs;
@@ -729,12 +762,18 @@ static errcode_t o2fsck_pass1b(o2fsck_state *ost, struct dup_context *dct)
goto out;
}
+ ret = ocfs2_malloc_block(fs->fs_io, &extra_buf);
+ if (ret) {
+ com_err(whoami, ret, "while allocating extra buffer");
+ goto out;
+ }
+
di = (struct ocfs2_dinode *)buf;
ret = ocfs2_open_inode_scan(fs, &scan);
if (ret) {
com_err(whoami, ret, "while opening inode scan");
- goto out_free;
+ goto out;
}
/*
@@ -762,17 +801,19 @@ static errcode_t o2fsck_pass1b(o2fsck_state *ost, struct dup_context *dct)
if (!(di->i_flags & OCFS2_VALID_FL))
continue;
- ret = pass1b_process_inode(ost, dct, blkno, di);
+ ret = pass1b_process_inode(ost, dct, blkno, di, extra_buf);
if (ret)
break;
}
ocfs2_close_inode_scan(scan);
-out_free:
- ocfs2_free(&buf);
-
out:
+ if (buf)
+ ocfs2_free(&buf);
+ if (extra_buf)
+ ocfs2_free(&extra_buf);
+
return ret;
}
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list