[Ocfs2-tools-devel] [PATCH 11/11] fsck.ocfs2: Add readahead in Pass 2
Goldwyn Rodrigues
rgoldwyn at gmail.com
Fri Sep 23 09:49:57 PDT 2011
On Thu, Sep 22, 2011 at 9:04 PM, Sunil Mushran <sunil.mushran at oracle.com> wrote:
> This patch adds code to readahead directory blocks in pass 2. It reads upto
> 1024 blocks. Those blocks are then verified after which the utility reads
> another 1024 blocks. And so on. This scheme prevents blowing up the cache.
>
> What this does not as yet is pre-read the directory index blocks and the
> inodes specified in the directory block. That is left for a later exercise.
>
> The test was run on a 2TB volume having 15M files. The cache size was 820MB.
>
> Pass 2: Checking directory entries
>
> Before:
> I/O read disk/cache: 3897MB / 131MB, write: 0MB, rate: 2.84MB/s
> Times real: 1416.929s, user: 124.587s, sys: 17.412s
>
> After:
> I/O read disk/cache: 3902MB / 3937MB, write: 0MB, rate: 25.82MB/s
> Times real: 303.600s, user: 95.781s, sys: 13.443s
>
> Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
> ---
> fsck.ocfs2/dirblocks.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 52 insertions(+), 1 deletions(-)
>
> diff --git a/fsck.ocfs2/dirblocks.c b/fsck.ocfs2/dirblocks.c
> index 67b0eb5..ed8790e 100644
> --- a/fsck.ocfs2/dirblocks.c
> +++ b/fsck.ocfs2/dirblocks.c
> @@ -36,6 +36,51 @@
> #include "util.h"
> #include "extent.h"
>
> +#define NUM_RA_BLOCKS 1024
> +static void o2fsck_readahead_dirblocks(o2fsck_state *ost, struct rb_node *node,
> + struct rb_node **last_read_node)
> +{
> + ocfs2_filesys *fs = ost->ost_fs;
> + o2fsck_dirblock_entry *dbe;
> + struct io_aio_unit *aios = NULL;
> + char *buf = NULL;
> + int buflen = NUM_RA_BLOCKS * fs->fs_blocksize;
> + uint32_t offset = 0;
> + int i;
> + errcode_t ret;
> +
> + *last_read_node = NULL;
> +
> + if (!fs->fs_io)
> + return;
> +
> + if (buflen > io_get_cache_size(fs->fs_io))
> + return;
> +
> + ret = ocfs2_malloc_blocks(fs->fs_io, NUM_RA_BLOCKS, &buf);
> + if (ret)
> + goto out;
> + memset(buf, 0, buflen);
> +
> + ret = ocfs2_malloc(sizeof(struct io_aio_unit) * NUM_RA_BLOCKS, &aios);
> + if (ret)
> + goto out;
> +
> + for (i = 0; node && (i < NUM_RA_BLOCKS); ++i, node = rb_next(node)) {
> + dbe = rb_entry(node, o2fsck_dirblock_entry, e_node);
> + aios[i].aio_blkno = dbe->e_blkno;
> + aios[i].aio_buf = buf + offset;
> + offset += fs->fs_blocksize;
> + *last_read_node = node;
> + }
> +
> + ret = io_aio_read_blocks(fs->fs_io, aios, i);
> +
> +out:
> + ocfs2_free(&aios);
> + ocfs2_free(&buf);
> +}
> +
> errcode_t o2fsck_add_dir_block(o2fsck_dirblocks *db, uint64_t ino,
> uint64_t blkno, uint64_t blkcount)
> {
> @@ -143,16 +188,22 @@ void o2fsck_dir_block_iterate(o2fsck_state *ost, dirblock_iterator func,
> {
> o2fsck_dirblocks *db = &ost->ost_dirblocks;
> o2fsck_dirblock_entry *dbe;
> - struct rb_node *node;
> + struct rb_node *node, *last_read_node = NULL;
> unsigned ret;
> + int readahead = 1;
>
> for (node = rb_first(&db->db_root); node; node = rb_next(node)) {
> dbe = rb_entry(node, o2fsck_dirblock_entry, e_node);
> + if (readahead)
> + o2fsck_readahead_dirblocks(ost, node, &last_read_node);
> + readahead = 0;
> ret = func(dbe, priv_data);
> if (ret & OCFS2_DIRENT_ABORT)
> break;
> if (ost->ost_prog)
> tools_progress_step(ost->ost_prog, 1);
> + if (last_read_node == node)
> + readahead = 1;
You can do away with readahead variable if you move this condition
when calling o2fsck_readahead_dirblocks()
> }
> }
>
--
Goldwyn
More information about the Ocfs2-tools-devel
mailing list