[Cluster-devel] [gfs2-utils PATCH] fsck.gfs2: File read-ahead

Steven Whitehouse swhiteho at redhat.com
Fri Jul 11 16:07:19 UTC 2014


Hi,

On 10/07/14 17:54, Bob Peterson wrote:
> Hi,
>
> This patch introduces file read-ahead to pass1.
Why not the other passes too? Is that just because they are not checking 
all the indirect data?

Steve.

> Regards,
>
> Bob Peterson
> Red Hat File Systems
>
> Signed-off-by: Bob Peterson <rpeterso at redhat.com>
> ---
>   gfs2/fsck/metawalk.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--
>   gfs2/fsck/metawalk.h |  1 +
>   gfs2/fsck/pass1.c    |  1 +
>   3 files changed, 65 insertions(+), 2 deletions(-)
>
> diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
> index 659af4e..8da17c6 100644
> --- a/gfs2/fsck/metawalk.c
> +++ b/gfs2/fsck/metawalk.c
> @@ -1184,6 +1184,59 @@ static void free_metalist(struct gfs2_inode *ip, osi_list_t *mlp)
>   	}
>   }
>   
> +static void file_ra(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
> +		    int head_size, int maxptrs, int h)
> +{
> +	struct gfs2_sbd *sdp = ip->i_sbd;
> +	uint64_t *p, sblock = 0, block;
> +	int extlen = 0;
> +
> +	if (h + 2 == ip->i_di.di_height) {
> +		p = (uint64_t *)(bh->b_data + head_size);
> +		if (*p && *(p + 1)) {
> +			sblock = be64_to_cpu(*p);
> +			p++;
> +			block = be64_to_cpu(*p);
> +			extlen = block - sblock;
> +			if (extlen > 1 && extlen <= maxptrs) {
> +				posix_fadvise(sdp->device_fd,
> +					      sblock * sdp->bsize,
> +					      (extlen + 1) * sdp->bsize,
> +					      POSIX_FADV_WILLNEED);
> +				return;
> +			}
> +		}
> +		extlen = 0;
> +	}
> +	for (p = (uint64_t *)(bh->b_data + head_size);
> +	     p < (uint64_t *)(bh->b_data + sdp->bsize); p++) {
> +		if (*p) {
> +			if (!sblock) {
> +				sblock = be64_to_cpu(*p);
> +				extlen = 1;
> +				continue;
> +			}
> +			block = be64_to_cpu(*p);
> +			if (block == sblock + extlen) {
> +				extlen++;
> +				continue;
> +			}
> +		}
> +		if (extlen && sblock) {
> +			if (extlen > 1)
> +				extlen--;
> +			posix_fadvise(sdp->device_fd, sblock * sdp->bsize,
> +				      extlen * sdp->bsize,
> +				      POSIX_FADV_WILLNEED);
> +			extlen = 0;
> +			p--;
> +		}
> +	}
> +	if (extlen)
> +		posix_fadvise(sdp->device_fd, sblock * sdp->bsize,
> +			      extlen * sdp->bsize, POSIX_FADV_WILLNEED);
> +}
> +
>   /**
>    * build_and_check_metalist - check a bunch of indirect blocks
>    *                            This includes hash table blocks for directories
> @@ -1204,6 +1257,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
>   	int h, head_size, iblk_type;
>   	uint64_t *ptr, block;
>   	int error, was_duplicate, is_valid;
> +	int maxptrs;
>   
>   	osi_list_add(&metabh->b_altlist, &mlp[0]);
>   
> @@ -1225,13 +1279,18 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
>   				iblk_type = GFS2_METATYPE_JD;
>   			else
>   				iblk_type = GFS2_METATYPE_IN;
> -			if (ip->i_sbd->gfs1)
> +			if (ip->i_sbd->gfs1) {
>   				head_size = sizeof(struct gfs_indirect);
> -			else
> +				maxptrs = (ip->i_sbd->bsize - head_size) /
> +					sizeof(uint64_t);
> +			} else {
>   				head_size = sizeof(struct gfs2_meta_header);
> +				maxptrs = ip->i_sbd->sd_inptrs;
> +			}
>   		} else {
>   			iblk_type = GFS2_METATYPE_DI;
>   			head_size = sizeof(struct gfs2_dinode);
> +			maxptrs = ip->i_sbd->sd_diptrs;
>   		}
>   		prev_list = &mlp[h - 1];
>   		cur_list = &mlp[h];
> @@ -1246,6 +1305,8 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
>   				continue;
>   			}
>   
> +			if (pass->readahead)
> +				file_ra(ip, bh, head_size, maxptrs, h);
>   			/* Now check the metadata itself */
>   			for (ptr = (uint64_t *)(bh->b_data + head_size);
>   			     (char *)ptr < (bh->b_data + ip->i_sbd->bsize);
> diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
> index 5e30bfe..a4e0676 100644
> --- a/gfs2/fsck/metawalk.h
> +++ b/gfs2/fsck/metawalk.h
> @@ -94,6 +94,7 @@ enum meta_check_rc {
>   struct metawalk_fxns {
>   	void *private;
>   	int invalid_meta_is_fatal;
> +	int readahead;
>   	int (*check_leaf_depth) (struct gfs2_inode *ip, uint64_t leaf_no,
>   				 int ref_count, struct gfs2_buffer_head *lbh);
>   	int (*check_leaf) (struct gfs2_inode *ip, uint64_t block,
> diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
> index 4f1b77a..fec2f64 100644
> --- a/gfs2/fsck/pass1.c
> +++ b/gfs2/fsck/pass1.c
> @@ -1055,6 +1055,7 @@ static int rangecheck_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
>   
>   struct metawalk_fxns rangecheck_fxns = {
>           .private = NULL,
> +	.readahead = 1,
>           .check_metalist = rangecheck_metadata,
>           .check_data = rangecheck_data,
>           .check_leaf = rangecheck_leaf,
>




More information about the Cluster-devel mailing list