From patchwork Sat Feb 1 10:37:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 315895 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BA0552C00A7 for ; Sat, 1 Feb 2014 21:37:44 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751568AbaBAKhn (ORCPT ); Sat, 1 Feb 2014 05:37:43 -0500 Received: from userp1040.oracle.com ([156.151.31.81]:37333 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751413AbaBAKhe (ORCPT ); Sat, 1 Feb 2014 05:37:34 -0500 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s11AbVgC020755 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 1 Feb 2014 10:37:32 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s11AbU2T022271 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 1 Feb 2014 10:37:31 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userz7022.oracle.com (8.14.5+Sun/8.14.4) with ESMTP id s11AbUw0029403; Sat, 1 Feb 2014 10:37:30 GMT Received: from localhost (/67.160.151.179) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 01 Feb 2014 02:37:29 -0800 Subject: [PATCH 1/3] ext2fs: add readahead method to improve scanning To: tytso@mit.edu, darrick.wong@oracle.com From: "Darrick J. Wong" Cc: linux-ext4@vger.kernel.org, Andreas Dilger Date: Sat, 01 Feb 2014 02:37:27 -0800 Message-ID: <20140201103727.9011.91402.stgit@birch.djwong.org> In-Reply-To: <20140201103721.9011.5971.stgit@birch.djwong.org> References: <20140201103721.9011.5971.stgit@birch.djwong.org> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Source-IP: ucsinet21.oracle.com [156.151.31.93] Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Frøm: Andreas Dilger 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 [darrick.wong@oracle.com] Make the arguments to the readahead function take the same ULL values as the other IO functions, and return an appropriate error code when fadvise isn't available. Signed-off-by: Andreas Dilger Signed-off-by: Darrick J. Wong --- lib/ext2fs/ext2_io.h | 4 ++++ lib/ext2fs/io_manager.c | 9 +++++++++ lib/ext2fs/unix_io.c | 28 +++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/lib/ext2fs/ext2_io.h b/lib/ext2fs/ext2_io.h index 1894fb8..00e22e0 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, + unsigned long long count); long reserved[16]; }; @@ -124,6 +126,8 @@ extern errcode_t io_channel_discard(io_channel channel, unsigned long long count); extern errcode_t io_channel_alloc_buf(io_channel channel, int count, void *ptr); +extern errcode_t io_channel_readahead(io_channel io, unsigned long long block, + unsigned long long count); /* unix_io.c */ extern io_manager unix_io_manager; diff --git a/lib/ext2fs/io_manager.c b/lib/ext2fs/io_manager.c index 34e4859..1acbb1d 100644 --- a/lib/ext2fs/io_manager.c +++ b/lib/ext2fs/io_manager.c @@ -128,3 +128,12 @@ errcode_t io_channel_alloc_buf(io_channel io, int count, void *ptr) else return ext2fs_get_mem(size, ptr); } + +errcode_t io_channel_readahead(io_channel io, unsigned long long block, + unsigned long long count) +{ + if (!io->manager->readahead) + return EXT2_ET_OP_NOT_SUPPORTED; + + return io->manager->readahead(io, block, nblocks); +} diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c index 0cc0f52..bc4490c 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 @@ -119,6 +122,8 @@ static errcode_t unix_write_blk64(io_channel channel, unsigned long long block, int count, const void *data); static errcode_t unix_discard(io_channel channel, unsigned long long block, unsigned long long count); +static errcode_t unix_readahead(io_channel channel, unsigned long long block, + unsigned long long count); static struct struct_io_manager struct_unix_manager = { EXT2_ET_MAGIC_IO_MANAGER, @@ -135,6 +140,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; @@ -828,6 +834,22 @@ 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, + unsigned long long 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); + return 0; +#else + return EXT2_ET_OP_NOT_SUPPORTED; +#endif +} + static errcode_t unix_write_blk(io_channel channel, unsigned long block, int count, const void *buf) {