fsck.gfs2: File read-ahead
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 fsck.gfs2: File read-ahead
Hi,
This patch introduces file read-ahead to pass1.
Regards,
Bob Peterson
Red Hat File Systems
--- gfs2/fsck/metawalk.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-- gfs2/fsck/metawalk.h | 1 + gfs2/fsck/pass1.c | 1 + 3 files changed, 65 insertions(+), 2 deletions(-)
gfs2/fsck/metawalk.c +63 -2
@@ -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);
gfs2/fsck/metawalk.h +1 -0
@@ -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,
gfs2/fsck/pass1.c +1 -0
@@ -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,
PATCH 1/1 fsck.gfs2: File read-ahead
Hi,
Quoted 3 lines · Bob Peterson
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.
Quoted 139 lines
Regards,
Bob Peterson
Red Hat File SystemsSigned-off-by Bob Peterson <[email protected]>--- gfs2/fsck/metawalk.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-- gfs2/fsck/metawalk.h | 1 + gfs2/fsck/pass1.c | 1 + 3 files changed, 65 insertions(+), 2 deletions(-)gfs2/fsck/metawalk.c +63
-2@@ -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);gfs2/fsck/metawalk.h +1
-0@@ -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,gfs2/fsck/pass1.c +1
-0@@ -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,
PATCH 1/1 fsck.gfs2: File read-ahead
----- Original Message -----
Quoted 10 lines
Hi,
Quoted 3 lines · Bob Peterson
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.
Hi Steve,
Yes, exactly. Doing read-ahead for the other cases is a waste of time.
Regards,
Bob Peterson
Red Hat File Systems