[Ocfs2-devel] [PATCH 2/2] Ocfs2: Optimize punching-hole codes v5.

Tao Ma tao.ma at oracle.com
Fri Apr 9 02:22:01 PDT 2010


Hi Tristan,

Tristan Ye wrote:
> V5 patch simplifies the logic of handling existing holes and procedures
> for skipping extent blocks, and removed most of confusing comments.
> 
> V5 patch has survived with fill_verify_holes testcase in ocfs2-test,
> it also passed my manual sanity check and stress tests with enormous
> extent records.
> Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
> ---
>  fs/ocfs2/file.c |  173 +++++++++++++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 148 insertions(+), 25 deletions(-)
> 
> diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
> index db2e0c9..907653e 100644
> --- a/fs/ocfs2/file.c
> +++ b/fs/ocfs2/file.c
> @@ -1423,18 +1423,97 @@ out:
>  	return ret;
>  }
>  
> +static int ocfs2_find_rec(struct ocfs2_extent_list *el,
> +			  u32 pos,
> +			  int include_pos)
Why you need this 'include_pos'? btw, there is only one caller with 
include_pos = 0, so why not remove it? ;)
> +{
> +	int i;
> +	struct ocfs2_extent_rec *rec = NULL;
> +
> +	for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
> +
> +		rec = &el->l_recs[i];
> +
> +		if (include_pos) {
> +			if (le32_to_cpu(rec->e_cpos) <= pos)
> +				break;
> +		} else {
> +			if (le32_to_cpu(rec->e_cpos) < pos)
> +				break;
> +		}
> +	}
> +
> +	return i;
> +}
> +
> +/*
> + * Helper to calculate the punching pos and length in one run, we handle the
> + * following three cases in order:
> + *
> + * - remove the entire record
> + * - remove a partial record
> + * - no record needs to be removed (hole-punching completed)
> +*/
> +static void ocfs2_calc_trunc_pos(struct inode *inode,
> +				 struct ocfs2_extent_list *el,
> +				 struct ocfs2_extent_rec *rec,
> +				 u32 trunc_start, u32 *trunc_cpos,
> +				 u32 *trunc_len, u32 *trunc_end,
> +				 u64 *blkno, int *done)
> +{
> +	int ret = 0;
> +	u32 coff, range;
> +
> +	range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec);
> +
> +	if (le32_to_cpu(rec->e_cpos) >= trunc_start) {
> +		*trunc_cpos = le32_to_cpu(rec->e_cpos);
> +		/*
> +		 * Skip holes if any.
> +		 */
> +		if (range < *trunc_end)
> +			*trunc_end = range;
> +		*trunc_len = *trunc_end - le32_to_cpu(rec->e_cpos);
> +		*blkno = le64_to_cpu(rec->e_blkno);
> +		*trunc_end = le32_to_cpu(rec->e_cpos);
> +	} else if (range > trunc_start) {
> +		*trunc_cpos = trunc_start;
> +		*trunc_len = range - trunc_start;
I guess there should be a bug? what if the old trunc_end < range?
then *trunc_len should be min(range, *trunc_end) - trunc_start?
> +		coff = trunc_start - le32_to_cpu(rec->e_cpos);
> +		*blkno = le64_to_cpu(rec->e_blkno) +
> +				ocfs2_clusters_to_blocks(inode->i_sb, coff);
> +		*trunc_end = trunc_start;
> +	} else {
> +		/*
> +		 * It may have two following possibilities:
> +		 *
> +		 * - last record has been removed
> +		 * - trunc_start was within a hole
> +		 *
> +		 * both two cases mean the completion of hole punching.
> +		 */
> +		ret = 1;
> +	}
> +
> +	*done = ret;
> +}
> +
Regards,
Tao



More information about the Ocfs2-devel mailing list