From a422465fd842b354a2b59c528785761fd55ceeed Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 13 Apr 2012 12:58:53 -0600 Subject: [PATCH] ext2fs: add readahead method to improve scanning Add a readahead method for prefetching ranges of disk blocks. This is useful for inode table scanning, and other large contiguous ranges of blocks, and may also prove useful for random block prefetch, since it will allow reordering of the IO without waiting synchronously for the reads to complete. It is currently using the posix_fadvise(POSIX_FADV_WILLNEED) interface, as this proved most efficient during our testing Signed-off-by: Andreas Dilger --- lib/ext2fs/ext2_io.h | 3 +++ lib/ext2fs/unix_io.c | 24 +++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/ext2fs/ext2_io.h b/lib/ext2fs/ext2_io.h index 1894fb8..6b4c93c 100644 --- a/lib/ext2fs/ext2_io.h +++ b/lib/ext2fs/ext2_io.h @@ -90,6 +90,8 @@ struct struct_io_manager { int count, const void *data); errcode_t (*discard)(io_channel channel, unsigned long long block, unsigned long long count); + errcode_t (*readahead)(io_channel channel, unsigned long long block, + int count); long reserved[16]; }; @@ -103,6 +105,7 @@ struct struct_io_manager { #define io_channel_close(c) ((c)->manager->close((c))) #define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s)) #define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d)) +#define io_channel_readahead(c,b,n) ((c)->manager->readahead((c),b,n)) #define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d)) #define io_channel_flush(c) ((c)->manager->flush((c))) #define io_channel_bumpcount(c) ((c)->refcount++) diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index c3185b6..f1b96df 100644 --- a/lib/ext2fs/unix_io.c +++ b/lib/ext2fs/unix_io.c @@ -15,6 +15,9 @@ * %End-Header% */ +#define _XOPEN_SOURCE 600 +#define _DARWIN_C_SOURCE +#define _FILE_OFFSET_BITS 64 #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #ifndef _GNU_SOURCE @@ -35,6 +38,9 @@ #ifdef __linux__ #include #endif +#if HAVE_SYS_TYPES_H +#include +#endif #ifdef HAVE_SYS_IOCTL_H #include #endif @@ -44,9 +50,6 @@ #if HAVE_SYS_STAT_H #include #endif -#if HAVE_SYS_TYPES_H -#include -#endif #if HAVE_SYS_RESOURCE_H #include #endif @@ -786,6 +789,20 @@ static errcode_t unix_write_blk64(io_channel channel, unsigned long long block, #endif /* NO_IO_CACHE */ } +static errcode_t unix_readahead(io_channel channel, unsigned long long block, + int count) +{ +#ifdef POSIX_FADV_WILLNEED + struct unix_private_data *data; + + data = (struct unix_private_data *)channel->private_data; + posix_fadvise(data->dev, (ext2_loff_t)block * channel->block_size, + (ext2_loff_t)count * channel->block_size, + POSIX_FADV_WILLNEED); +#endif + return 0; +} + static errcode_t unix_write_blk(io_channel channel, unsigned long block, int count, const void *buf) { @@ -937,6 +954,7 @@ static struct struct_io_manager struct_unix_manager = { unix_read_blk64, unix_write_blk64, unix_discard, + unix_readahead, }; io_manager unix_io_manager = &struct_unix_manager; -- 1.8.3.1