From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Fri, 11 Jul 2014 17:07:19 +0100 Subject: [Cluster-devel] [gfs2-utils PATCH] fsck.gfs2: File read-ahead In-Reply-To: <884434227.6309633.1405011284079.JavaMail.zimbra@redhat.com> References: <884434227.6309633.1405011284079.JavaMail.zimbra@redhat.com> Message-ID: <53C00BB7.1070902@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 > --- > 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, >