[Ocfs2-tools-devel] [PATCH 29/50] fsck.ocfs2: Generic ocfs2_extent_rec check.

Tao Ma tao.ma at oracle.com
Mon Jan 11 07:31:15 PST 2010


unwritten extents actually only exists in the extent tree
for the inode, but we check it for every tree types. And
as for blkno alignment check, refcount tree doesn't need
this type of check.

This patch add a check_leaf_rec_func in extent_info so that the
caller of check_el can initialize it to do its own check for
the leaf ocfs2_extent_rec.

Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
 fsck.ocfs2/extent.c         |  116 +++++++++++++++++++++++++------------------
 fsck.ocfs2/include/extent.h |   25 +++++++--
 fsck.ocfs2/xattr.c          |    4 ++
 3 files changed, 92 insertions(+), 53 deletions(-)

diff --git a/fsck.ocfs2/extent.c b/fsck.ocfs2/extent.c
index 2cd7cd9..0d6878b 100644
--- a/fsck.ocfs2/extent.c
+++ b/fsck.ocfs2/extent.c
@@ -141,8 +141,7 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
 			  struct ocfs2_extent_rec *er, int *changed)
 {
 	errcode_t ret = 0;
-	uint64_t first_block;
-	uint32_t last_cluster, clusters;
+	uint32_t clusters;
 
 	clusters = ocfs2_rec_clusters(el->l_tree_depth, er);
 	verbosef("cpos %u clusters %u blkno %"PRIu64"\n", er->e_cpos,
@@ -174,51 +173,8 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
 		goto out;
 	}
 
-	if (!ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(ost->ost_fs->fs_super)) &&
-	    (er->e_flags & OCFS2_EXT_UNWRITTEN) &&
-	    prompt(ost, PY, PR_EXTENT_MARKED_UNWRITTEN,
-		   "The extent record for cluster offset %"PRIu32" "
-		   "in owner %"PRIu64" has the UNWRITTEN flag set, but "
-		   "this filesystem does not support unwritten extents.  "
-		   "Clear the UNWRITTEN flag?", er->e_cpos, owner)) {
-		er->e_flags &= ~OCFS2_EXT_UNWRITTEN;
-		*changed = 1;
-	}
-
-	first_block = ocfs2_blocks_to_clusters(ost->ost_fs, er->e_blkno);
-	first_block = ocfs2_clusters_to_blocks(ost->ost_fs, first_block);
-
-	if (first_block != er->e_blkno &&
-	    prompt(ost, PY, PR_EXTENT_BLKNO_UNALIGNED,
-		   "The extent record for cluster offset %"PRIu32" "
-		   "in owner %"PRIu64" refers to block %"PRIu64" which isn't "
-		   "aligned with the start of a cluster.  Point the extent "
-		   "record at block %"PRIu64" which starts this cluster?",
-		   er->e_cpos, owner,
-		   (uint64_t)er->e_blkno, first_block)) {
-
-		er->e_blkno = first_block;
-		*changed = 1;
-	}
-
-	/* imagine blkno 0, 1 er_clusters.  last_cluster is 1 and 
-	 * fs_clusters is 1, which is ok.. */
-	last_cluster = ocfs2_blocks_to_clusters(ost->ost_fs, er->e_blkno) +
-		       clusters;
-
-	if (last_cluster > ost->ost_fs->fs_clusters &&
-	    prompt(ost, PY, PR_EXTENT_CLUSTERS_OVERRUN,
-		   "The extent record for cluster offset %"PRIu32" "
-		   "in inode %"PRIu64" refers to an extent that goes beyond "
-		   "the end of the volume.  Truncate the extent by %"PRIu32" "
-		   "clusters to fit it in the volume?", er->e_cpos, owner,
-		   last_cluster - ost->ost_fs->fs_clusters)) {
-
-		clusters -= last_cluster - ost->ost_fs->fs_clusters;
-		ocfs2_set_rec_clusters(el->l_tree_depth, er, clusters);
-		*changed = 1;
-	}
-	
+	if (ei->chk_rec_func)
+		ret = ei->chk_rec_func(ost, owner, el, er, changed, ei->para);
 	/* XXX offer to remove leaf records with er_clusters set to 0? */
 
 	/* XXX check that the blocks that are referenced aren't already 
@@ -352,13 +308,77 @@ errcode_t check_el(o2fsck_state *ost, struct extent_info *ei,
 	return 0;
 }
 
+errcode_t o2fsck_check_extent_rec(o2fsck_state *ost,
+				  uint64_t owner,
+				  struct ocfs2_extent_list *el,
+				  struct ocfs2_extent_rec *er,
+				  int *changed,
+				  void *para)
+{
+	uint32_t clusters, last_cluster;
+	uint64_t first_block;
+	struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super);
+	struct ocfs2_dinode *di = para;
+
+	clusters = ocfs2_rec_clusters(el->l_tree_depth, er);
+	first_block = ocfs2_blocks_to_clusters(ost->ost_fs, er->e_blkno);
+	first_block = ocfs2_clusters_to_blocks(ost->ost_fs, first_block);
+
+	if (first_block != er->e_blkno &&
+	    prompt(ost, PY, PR_EXTENT_BLKNO_UNALIGNED,
+		   "The extent record for cluster offset %"PRIu32" "
+		   "in owner %"PRIu64" refers to block %"PRIu64" which isn't "
+		   "aligned with the start of a cluster.  Point the extent "
+		   "record at block %"PRIu64" which starts this cluster?",
+		   er->e_cpos, owner,
+		   (uint64_t)er->e_blkno, first_block)) {
+
+		er->e_blkno = first_block;
+		*changed = 1;
+	}
+
+	/* imagine blkno 0, 1 er_clusters.  last_cluster is 1 and
+	 * fs_clusters is 1, which is ok.. */
+	last_cluster = ocfs2_blocks_to_clusters(ost->ost_fs, er->e_blkno) +
+		       clusters;
+
+	if (last_cluster > ost->ost_fs->fs_clusters &&
+	    prompt(ost, PY, PR_EXTENT_CLUSTERS_OVERRUN,
+		   "The extent record for cluster offset %"PRIu32" "
+		   "in inode %"PRIu64" refers to an extent that goes beyond "
+		   "the end of the volume.  Truncate the extent by %"PRIu32" "
+		   "clusters to fit it in the volume?", er->e_cpos, owner,
+		   last_cluster - ost->ost_fs->fs_clusters)) {
+
+		clusters -= last_cluster - ost->ost_fs->fs_clusters;
+		ocfs2_set_rec_clusters(el->l_tree_depth, er, clusters);
+		*changed = 1;
+	}
+
+	if (!ocfs2_writes_unwritten_extents(sb) &&
+	    (er->e_flags & OCFS2_EXT_UNWRITTEN) &&
+	    prompt(ost, PY, PR_EXTENT_MARKED_UNWRITTEN,
+		   "The extent record for cluster offset %"PRIu32" "
+		   "in owner %"PRIu64" has the UNWRITTEN flag set, but "
+		   "this filesystem does not support unwritten extents.  "
+		   "Clear the UNWRITTEN flag?", er->e_cpos,
+		   (uint64_t)di->i_blkno)) {
+		er->e_flags &= ~OCFS2_EXT_UNWRITTEN;
+		*changed = 1;
+	}
+
+	return 0;
+}
+
 errcode_t o2fsck_check_extents(o2fsck_state *ost,
 			       struct ocfs2_dinode *di)
 {
 	errcode_t ret;
 	struct extent_info ei = {0, };
 	int changed = 0;
-	
+
+	ei.chk_rec_func = o2fsck_check_extent_rec;
+	ei.para = di;
 	ret = check_el(ost, &ei, di->i_blkno, &di->id2.i_list,
 	         ocfs2_extent_recs_per_inode(ost->ost_fs->fs_blocksize),
 		 &changed);
diff --git a/fsck.ocfs2/include/extent.h b/fsck.ocfs2/include/extent.h
index d33fb5e..857d7fd 100644
--- a/fsck.ocfs2/include/extent.h
+++ b/fsck.ocfs2/include/extent.h
@@ -22,12 +22,21 @@
 
 #include "fsck.h"
 
+typedef errcode_t (check_leaf_er_func)(o2fsck_state *ost,
+				       uint64_t owner,
+				       struct ocfs2_extent_list *el,
+				       struct ocfs2_extent_rec *er,
+				       int *changed,
+				       void *para);
+
 struct extent_info {
-	uint64_t	ei_max_size;
-	uint64_t	ei_clusters;
-	uint64_t	ei_last_eb_blk;
-	uint16_t	ei_expected_depth;
-	unsigned	ei_expect_depth:1;
+	uint64_t		ei_max_size;
+	uint64_t		ei_clusters;
+	uint64_t		ei_last_eb_blk;
+	uint16_t		ei_expected_depth;
+	unsigned		ei_expect_depth:1;
+	check_leaf_er_func	*chk_rec_func;
+	void			*para;
 };
 
 errcode_t o2fsck_check_extents(o2fsck_state *ost,
@@ -37,6 +46,12 @@ errcode_t check_el(o2fsck_state *ost, struct extent_info *ei,
 		   uint64_t owner,
 		   struct ocfs2_extent_list *el,
 		   uint16_t max_recs, int *changed);
+errcode_t o2fsck_check_extent_rec(o2fsck_state *ost,
+				  uint64_t owner,
+				  struct ocfs2_extent_list *el,
+				  struct ocfs2_extent_rec *er,
+				  int *changed,
+				  void *para);
 
 #endif /* __O2FSCK_EXTENT_H__ */
 
diff --git a/fsck.ocfs2/xattr.c b/fsck.ocfs2/xattr.c
index be6a606..07cc97d 100644
--- a/fsck.ocfs2/xattr.c
+++ b/fsck.ocfs2/xattr.c
@@ -380,6 +380,8 @@ static errcode_t check_xattr_value(o2fsck_state *ost,
 	errcode_t ret = 0;
 	uint64_t owner;
 
+	ei.chk_rec_func = o2fsck_check_extent_rec;
+	ei.para = di;
 	for (i = 0 ; i < xh->xh_count; i++) {
 		int change = 0;
 		struct ocfs2_xattr_entry *xe = &xh->xh_entries[i];
@@ -605,6 +607,8 @@ static errcode_t o2fsck_check_xattr_index_block(o2fsck_state *ost,
 	if (!el->l_next_free_rec)
 		return 0;
 
+	ei.chk_rec_func = o2fsck_check_extent_rec;
+	ei.para = di;
 	ret = check_el(ost, &ei, xb->xb_blkno, el,
 		ocfs2_xattr_recs_per_xb(ost->ost_fs->fs_blocksize),
 		changed);
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list