[Ocfs2-tools-devel] [PATCH] fsck.ocfs2(1.2): Modify e_clusters if it isn't equal to eb contains.

Joel Becker Joel.Becker at oracle.com
Tue Nov 25 09:42:41 PST 2008


sob

On Thu, Nov 20, 2008 at 11:29:41AM +0800, Tao Ma wrote:
> In bug 7553939, we meet with a scenario that the clusters haven't
> been allocated to the extent block(no update) while the inode already
> have the i_clusters and e_clusters updated. The commit
> 09166ad03c83f39f2dcd77c74cd4672c3a371dfa has fixed the problem
> of i_clusters corruption, so this one intends to fix e_clusters.
> We calculate the total clusters within the extent block and then
> modify the extent record if it doesn't show the right value.
> 
> Please note that to be safe, it only fix the corruption happens in the
> last extent block. If there is any corruption happens in other extent block,
> we don't touch it(actually if we modify it, we may leave a hole there and
> make the system corrupted). The good thing is that in ocfs2-1.2, we don't
> support sparse files, and we only extend files, so if there is one corruption
> like 7553939, it must happen in the last extent block.
> 
> One more thing, in ocfs2-1.4, we support sparse files, so it can be handled
> gracefully. So this is only a fix for ocfs2-tools-1.2.
> 
> Signed-off-by: Tao Ma <tao.ma at oracle.com>
> ---
>  fsck.ocfs2/extent.c               |   36 ++++++++++++++++++++++++++++--------
>  fsck.ocfs2/fsck.ocfs2.checks.8.in |    7 +++++++
>  2 files changed, 35 insertions(+), 8 deletions(-)
> 
> diff --git a/fsck.ocfs2/extent.c b/fsck.ocfs2/extent.c
> index 0690408..d4b5364 100644
> --- a/fsck.ocfs2/extent.c
> +++ b/fsck.ocfs2/extent.c
> @@ -57,11 +57,12 @@ struct extent_info {
>  static errcode_t check_el(o2fsck_state *ost, struct extent_info *ei,
>  			  struct ocfs2_dinode *di,
>  			  struct ocfs2_extent_list *el,
> -			  uint16_t max_recs, int *changed);
> +			  uint16_t max_recs, int *changed,
> +			  uint32_t *total_clusters);
>  
>  static errcode_t check_eb(o2fsck_state *ost, struct extent_info *ei,
>  			  struct ocfs2_dinode *di, uint64_t blkno,
> -			  int *is_valid)
> +			  int *is_valid, uint32_t *total_clusters)
>  {
>  	int changed = 0;
>  	char *buf = NULL;
> @@ -128,7 +129,7 @@ static errcode_t check_eb(o2fsck_state *ost, struct extent_info *ei,
>  
>  	check_el(ost, ei, di, &eb->h_list,
>  		 ocfs2_extent_recs_per_eb(ost->ost_fs->fs_blocksize), 
> -		 &changed);
> +		 &changed, total_clusters);
>  
>  	if (changed) {
>  		ret = ocfs2_write_extent_block(ost->ost_fs, blkno, buf);
> @@ -155,7 +156,7 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
>  {
>  	errcode_t ret = 0;
>  	uint64_t first_block;
> -	uint32_t last_cluster;
> +	uint32_t last_cluster, total_clusters;
>  
>  	verbosef("cpos %u clusters %u blkno %"PRIu64"\n", er->e_cpos,
>  		 er->e_clusters, er->e_blkno);
> @@ -170,7 +171,9 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
>  		 * is checked */
>  		ei->ei_expect_depth = 1;
>  		ei->ei_expected_depth = el->l_tree_depth - 1;
> -		check_eb(ost, ei, di, er->e_blkno, &is_valid);
> +		ret = 0;
> +		total_clusters = 0;
> +		check_eb(ost, ei, di, er->e_blkno, &is_valid, &total_clusters);
>  		if (!is_valid && 
>  		    prompt(ost, PY, PR_EXTENT_EB_INVALID,
>  			   "The extent record for cluster offset "
> @@ -181,8 +184,22 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
>  
>  			er->e_blkno = 0;
>  			*changed = 1;
> +			goto out;
>  		}
> -		ret = 0;
> +
> +		if (el->l_recs[el->l_next_free_rec-1].e_blkno == er->e_blkno &&
> +		    total_clusters != er->e_clusters &&
> +		    prompt(ost, PY, PR_EXTENT_EB_CLUSTER_RANGE,
> +			   "The extent record for cluster offset %"PRIu32" "
> +			   "in inode %"PRIu64" has a cluster count of %"PRIu32
> +			   " while its extent block has %"PRIu32" clusters "
> +			   "allocated. Change it to what extent block "
> +			   "represents?", er->e_cpos, di->i_blkno,
> +			   er->e_clusters, total_clusters)) {
> +			er->e_clusters = total_clusters;
> +			*changed = 1;
> +		}
> +
>  		goto out;
>  	}
>  
> @@ -230,7 +247,8 @@ out:
>  static errcode_t check_el(o2fsck_state *ost, struct extent_info *ei,
>  			  struct ocfs2_dinode *di,
>  			  struct ocfs2_extent_list *el,
> -			  uint16_t max_recs, int *changed)
> +			  uint16_t max_recs, int *changed,
> +			  uint32_t *total_clusters)
>  {
>  	int trust_next_free = 1;
>  	struct ocfs2_extent_rec *er;
> @@ -319,6 +337,8 @@ static errcode_t check_el(o2fsck_state *ost, struct extent_info *ei,
>  			continue;
>  		}
>  
> +		if (total_clusters)
> +			*total_clusters += er->e_clusters;
>  
>  		/* we've already accounted for the extent block as part of
>  		 * the extent block chain groups */
> @@ -350,7 +370,7 @@ errcode_t o2fsck_check_extents(o2fsck_state *ost,
>  	
>  	ret = check_el(ost, &ei, di, &di->id2.i_list, 
>  	         ocfs2_extent_recs_per_inode(ost->ost_fs->fs_blocksize),
> -		 &changed);
> +		 &changed, NULL);
>  
>  	if (changed)
>  		o2fsck_write_inode(ost, di->i_blkno, di);
> diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
> index 2e30f9d..8551018 100644
> --- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
> +++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
> @@ -71,6 +71,13 @@ extent tree references an invalid extent block.
>  Answering yes stops the tree from referencing the invalid extent block.  This
>  may truncate data from the file which contains the tree.
>  
> +.SS "EXTENT_EB_CLUSTER_RANGE"
> +Deep extent trees are built by forming a tree out of extent blocks.  An
> +extent record represent a wrong clusters count than the extent block contains.
> +
> +Answering yes change clusters count in the extent record to the number the below
> +extent block contains.
> +
>  .SS "EXTENT_LIST_DEPTH"
>  Extent lists contain a record of their depth in the tree.  An extent list
>  was found whose recorded depth doesn't match the position they have in the
> -- 
> 1.5.5
> 

-- 

 There are morethings in heaven and earth, Horatio,
 Than are dreamt of in your philosophy.

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list