[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