From: Zi Yan <ziy@nvidia.com>
To: Matthew Wilcox <willy@infradead.org>
Cc: linux-xfs@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net, cluster-devel@redhat.com,
linux-mm@kvack.org, ocfs2-devel@oss.oracle.com,
linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
linux-erofs@lists.ozlabs.org, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v7 10/24] mm: Add readahead address space operation
Date: Thu, 20 Feb 2020 10:00:30 -0500 [thread overview]
Message-ID: <5D7CE6BD-FABD-4901-AEF0-E0F10FC00EB1@nvidia.com> (raw)
In-Reply-To: <20200219210103.32400-11-willy@infradead.org>
[-- Attachment #1: Type: text/plain, Size: 7352 bytes --]
On 19 Feb 2020, at 16:00, Matthew Wilcox wrote:
> From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>
> This replaces ->readpages with a saner interface:
> - Return void instead of an ignored error code.
> - Page cache is already populated with locked pages when ->readahead
> is called.
> - New arguments can be passed to the implementation without changing
> all the filesystems that use a common helper function like
> mpage_readahead().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
> Documentation/filesystems/locking.rst | 6 +++++-
> Documentation/filesystems/vfs.rst | 15 +++++++++++++++
> include/linux/fs.h | 2 ++
> include/linux/pagemap.h | 18 ++++++++++++++++++
> mm/readahead.c | 12 ++++++++++--
> 5 files changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
> index 5057e4d9dcd1..0af2e0e11461 100644
> --- a/Documentation/filesystems/locking.rst
> +++ b/Documentation/filesystems/locking.rst
> @@ -239,6 +239,7 @@ prototypes::
> int (*readpage)(struct file *, struct page *);
> int (*writepages)(struct address_space *, struct writeback_control *);
> int (*set_page_dirty)(struct page *page);
> + void (*readahead)(struct readahead_control *);
> int (*readpages)(struct file *filp, struct address_space *mapping,
> struct list_head *pages, unsigned nr_pages);
> int (*write_begin)(struct file *, struct address_space *mapping,
> @@ -271,7 +272,8 @@ writepage: yes, unlocks (see below)
> readpage: yes, unlocks
> writepages:
> set_page_dirty no
> -readpages:
> +readahead: yes, unlocks
> +readpages: no
> write_begin: locks the page exclusive
> write_end: yes, unlocks exclusive
> bmap:
> @@ -295,6 +297,8 @@ the request handler (/dev/loop).
> ->readpage() unlocks the page, either synchronously or via I/O
> completion.
>
> +->readahead() unlocks the pages that I/O is attempted on like ->readpage().
> +
> ->readpages() populates the pagecache with the passed pages and starts
> I/O against them. They come unlocked upon I/O completion.
>
> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
> index 7d4d09dd5e6d..ed17771c212b 100644
> --- a/Documentation/filesystems/vfs.rst
> +++ b/Documentation/filesystems/vfs.rst
> @@ -706,6 +706,7 @@ cache in your filesystem. The following members are defined:
> int (*readpage)(struct file *, struct page *);
> int (*writepages)(struct address_space *, struct writeback_control *);
> int (*set_page_dirty)(struct page *page);
> + void (*readahead)(struct readahead_control *);
> int (*readpages)(struct file *filp, struct address_space *mapping,
> struct list_head *pages, unsigned nr_pages);
> int (*write_begin)(struct file *, struct address_space *mapping,
> @@ -781,12 +782,26 @@ cache in your filesystem. The following members are defined:
> If defined, it should set the PageDirty flag, and the
> PAGECACHE_TAG_DIRTY tag in the radix tree.
>
> +``readahead``
> + Called by the VM to read pages associated with the address_space
> + object. The pages are consecutive in the page cache and are
> + locked. The implementation should decrement the page refcount
> + after starting I/O on each page. Usually the page will be
> + unlocked by the I/O completion handler. If the filesystem decides
> + to stop attempting I/O before reaching the end of the readahead
> + window, it can simply return. The caller will decrement the page
> + refcount and unlock the remaining pages for you. Set PageUptodate
> + if the I/O completes successfully. Setting PageError on any page
> + will be ignored; simply unlock the page if an I/O error occurs.
> +
> ``readpages``
> called by the VM to read pages associated with the address_space
> object. This is essentially just a vector version of readpage.
> Instead of just one page, several pages are requested.
> readpages is only used for read-ahead, so read errors are
> ignored. If anything goes wrong, feel free to give up.
> + This interface is deprecated and will be removed by the end of
> + 2020; implement readahead instead.
>
> ``write_begin``
> Called by the generic buffered write code to ask the filesystem
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 3cd4fe6b845e..d4e2d2964346 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -292,6 +292,7 @@ enum positive_aop_returns {
> struct page;
> struct address_space;
> struct writeback_control;
> +struct readahead_control;
>
> /*
> * Write life time hint values.
> @@ -375,6 +376,7 @@ struct address_space_operations {
> */
> int (*readpages)(struct file *filp, struct address_space *mapping,
> struct list_head *pages, unsigned nr_pages);
> + void (*readahead)(struct readahead_control *);
>
> int (*write_begin)(struct file *, struct address_space *mapping,
> loff_t pos, unsigned len, unsigned flags,
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index 4989d330fada..b3008605fd1b 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -669,6 +669,24 @@ static inline struct page *readahead_page(struct readahead_control *rac)
> return page;
> }
>
> +/* The byte offset into the file of this readahead block */
> +static inline loff_t readahead_pos(struct readahead_control *rac)
> +{
> + return (loff_t)rac->_index * PAGE_SIZE;
> +}
> +
> +/* The number of bytes in this readahead block */
> +static inline loff_t readahead_length(struct readahead_control *rac)
> +{
> + return (loff_t)rac->_nr_pages * PAGE_SIZE;
> +}
> +
> +/* The index of the first page in this readahead block */
> +static inline unsigned int readahead_index(struct readahead_control *rac)
> +{
> + return rac->_index;
> +}
rac->_index is pgoff_t, so readahead_index() should return the same type, right?
BTW, pgoff_t is unsigned long.
> +
> /* The number of pages in this readahead block */
> static inline unsigned int readahead_count(struct readahead_control *rac)
> {
> diff --git a/mm/readahead.c b/mm/readahead.c
> index aaa209559ba2..07cdfbf00f4b 100644
> --- a/mm/readahead.c
> +++ b/mm/readahead.c
> @@ -124,7 +124,14 @@ static void read_pages(struct readahead_control *rac, struct list_head *pages)
>
> blk_start_plug(&plug);
>
> - if (aops->readpages) {
> + if (aops->readahead) {
> + aops->readahead(rac);
> + /* Clean up the remaining pages */
> + while ((page = readahead_page(rac))) {
> + unlock_page(page);
> + put_page(page);
> + }
> + } else if (aops->readpages) {
> aops->readpages(rac->file, rac->mapping, pages,
> readahead_count(rac));
> /* Clean up the remaining pages */
> @@ -234,7 +241,8 @@ void force_page_cache_readahead(struct address_space *mapping,
> struct file_ra_state *ra = &filp->f_ra;
> unsigned long max_pages;
>
> - if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages))
> + if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages &&
> + !mapping->a_ops->readahead))
> return;
>
> /*
> --
> 2.25.0
--
Best Regards,
Yan Zi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 854 bytes --]
next prev parent reply other threads:[~2020-02-20 15:00 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-19 21:00 [PATCH v7 00/23] Change readahead API Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 01/24] mm: Move readahead prototypes from mm.h Matthew Wilcox
2020-02-21 2:43 ` John Hubbard
2020-02-21 21:48 ` Matthew Wilcox
2020-02-22 0:15 ` John Hubbard
2020-02-24 21:32 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 02/24] mm: Return void from various readahead functions Matthew Wilcox
2020-02-24 21:33 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 03/24] mm: Ignore return value of ->readpages Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 04/24] mm: Move readahead nr_pages check into read_pages Matthew Wilcox
2020-02-20 14:36 ` Zi Yan
2020-02-21 4:24 ` John Hubbard
2020-02-24 21:34 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 05/24] mm: Use readahead_control to pass arguments Matthew Wilcox
2020-02-24 21:36 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 06/24] mm: Rename various 'offset' parameters to 'index' Matthew Wilcox
2020-02-21 2:21 ` John Hubbard
2020-02-21 3:27 ` John Hubbard
2020-02-19 21:00 ` [PATCH v7 07/24] mm: rename readahead loop variable to 'i' Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 08/24] mm: Remove 'page_offset' from readahead loop Matthew Wilcox
2020-02-21 2:48 ` John Hubbard
2020-02-24 21:37 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 09/24] mm: Put readahead pages in cache earlier Matthew Wilcox
2020-02-21 3:19 ` John Hubbard
2020-02-21 3:43 ` Matthew Wilcox
2020-02-21 4:19 ` John Hubbard
2020-02-24 21:40 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 10/24] mm: Add readahead address space operation Matthew Wilcox
2020-02-20 15:00 ` Zi Yan [this message]
2020-02-20 15:10 ` Matthew Wilcox
2020-02-21 4:30 ` John Hubbard
2020-02-24 21:41 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 11/24] mm: Move end_index check out of readahead loop Matthew Wilcox
2020-02-21 3:50 ` John Hubbard
2020-02-21 15:35 ` Matthew Wilcox
2020-02-21 19:41 ` John Hubbard
2020-02-19 21:00 ` [PATCH v7 12/24] mm: Add page_cache_readahead_unbounded Matthew Wilcox
2020-02-24 21:53 ` [Cluster-devel] " Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 13/24] fs: Convert mpage_readpages to mpage_readahead Matthew Wilcox
2020-02-24 21:54 ` [Cluster-devel] " Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 14/24] btrfs: Convert from readpages to readahead Matthew Wilcox
2020-02-20 9:42 ` Johannes Thumshirn
2020-02-20 13:48 ` Matthew Wilcox
2020-02-20 15:46 ` Christoph Hellwig
2020-02-20 15:54 ` Matthew Wilcox
2020-02-20 15:57 ` Christoph Hellwig
2020-02-24 21:43 ` Christoph Hellwig
2020-02-24 21:54 ` Matthew Wilcox
2020-02-24 21:57 ` Christoph Hellwig
2020-02-19 21:00 ` [PATCH v7 15/24] erofs: Convert uncompressed files " Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 16/24] erofs: Convert compressed " Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 17/24] ext4: Convert " Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 18/24] ext4: Pass the inode to ext4_mpage_readpages Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 19/24] f2fs: Convert from readpages to readahead Matthew Wilcox
2020-02-19 21:00 ` [PATCH v7 20/24] fuse: " Matthew Wilcox
2020-02-19 21:01 ` [PATCH v7 21/24] iomap: Restructure iomap_readpages_actor Matthew Wilcox
2020-02-20 15:47 ` Christoph Hellwig
2020-02-20 16:24 ` Matthew Wilcox
2020-02-24 22:17 ` Christoph Hellwig
2020-02-25 1:49 ` Matthew Wilcox
2020-02-22 0:44 ` Darrick J. Wong
2020-02-22 1:54 ` Matthew Wilcox
2020-02-23 17:55 ` Darrick J. Wong
2020-02-19 21:01 ` [PATCH v7 22/24] iomap: Convert from readpages to readahead Matthew Wilcox
2020-02-20 15:49 ` Christoph Hellwig
2020-02-20 16:57 ` Matthew Wilcox
2020-02-22 1:00 ` Darrick J. Wong
2020-02-24 4:33 ` Matthew Wilcox
2020-02-24 16:52 ` Darrick J. Wong
2020-02-22 1:03 ` Darrick J. Wong
2020-02-22 1:09 ` Matthew Wilcox
2020-02-19 21:01 ` [PATCH v7 23/24] mm: Document why we don't set PageReadahead Matthew Wilcox
2020-02-19 21:01 ` [PATCH v7 24/24] mm: Use memalloc_nofs_save in readahead path Matthew Wilcox
2020-02-20 17:54 ` [PATCH v7 00/23] Change readahead API David Sterba
2020-02-20 22:39 ` Matthew Wilcox
2020-02-21 11:59 ` David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5D7CE6BD-FABD-4901-AEF0-E0F10FC00EB1@nvidia.com \
--to=ziy@nvidia.com \
--cc=cluster-devel@redhat.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-erofs@lists.ozlabs.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-xfs@vger.kernel.org \
--cc=ocfs2-devel@oss.oracle.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).