From: trondmy@kernel.org To: linux-nfs@vger.kernel.org Subject: [PATCH 05/12] NFS: Don't discard readdir results Date: Mon, 2 Nov 2020 13:06:51 -0500 Message-ID: <20201102180658.6218-6-trondmy@kernel.org> (raw) In-Reply-To: <20201102180658.6218-5-trondmy@kernel.org> From: Trond Myklebust <trond.myklebust@hammerspace.com> If a readdir call returns more data than we can fit into one page cache page, then allocate a new one for that data rather than discarding the data. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- fs/nfs/dir.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 89cd8d5d9d3e..6f84038735a1 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -321,6 +321,21 @@ static void nfs_readdir_page_set_eof(struct page *page) kunmap_atomic(array); } +static struct page *nfs_readdir_page_get_next(struct address_space *mapping, + pgoff_t index, u64 cookie) +{ + struct page *page; + + page = nfs_readdir_page_get_locked(mapping, index, cookie); + if (page) { + if (nfs_readdir_page_last_cookie(page) == cookie) + return page; + unlock_page(page); + put_page(page); + } + return NULL; +} + static inline int is_32bit_api(void) { @@ -638,13 +653,15 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry, } /* Perform conversion from xdr to cache array */ -static -int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, - struct page **xdr_pages, struct page *page, unsigned int buflen) +static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, + struct nfs_entry *entry, + struct page **xdr_pages, + struct page *fillme, unsigned int buflen) { + struct address_space *mapping = desc->file->f_mapping; struct xdr_stream stream; struct xdr_buf buf; - struct page *scratch; + struct page *scratch, *new, *page = fillme; int status; scratch = alloc_page(GFP_KERNEL); @@ -667,6 +684,21 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en desc->dir_verifier); status = nfs_readdir_add_to_array(entry, page); + if (status != -ENOSPC) + continue; + + if (page->mapping != mapping) + break; + new = nfs_readdir_page_get_next(mapping, page->index + 1, + entry->prev_cookie); + if (!new) + break; + if (page != fillme) { + unlock_page(page); + put_page(page); + } + page = new; + status = nfs_readdir_add_to_array(entry, page); } while (!status && !entry->eof); switch (status) { @@ -682,6 +714,11 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en break; } + if (page != fillme) { + unlock_page(page); + put_page(page); + } + put_page(scratch); return status; } -- 2.28.0
next prev parent reply index Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-11-02 18:06 [PATCH 00/12] Readdir enhancements trondmy 2020-11-02 18:06 ` [PATCH 01/12] NFS: Ensure contents of struct nfs_open_dir_context are consistent trondmy 2020-11-02 18:06 ` [PATCH 02/12] NFS: Clean up readdir struct nfs_cache_array trondmy 2020-11-02 18:06 ` [PATCH 03/12] NFS: Clean up nfs_readdir_page_filler() trondmy 2020-11-02 18:06 ` [PATCH 04/12] NFS: Clean up directory array handling trondmy 2020-11-02 18:06 ` trondmy [this message] 2020-11-02 18:06 ` [PATCH 06/12] NFS: Remove unnecessary kmap in nfs_readdir_xdr_to_array() trondmy 2020-11-02 18:06 ` [PATCH 07/12] NFS: Replace kmap() with kmap_atomic() in nfs_readdir_search_array() trondmy 2020-11-02 18:06 ` [PATCH 08/12] NFS: Simplify struct nfs_cache_array_entry trondmy 2020-11-02 18:06 ` [PATCH 09/12] NFS: Support larger readdir buffers trondmy 2020-11-02 18:06 ` [PATCH 10/12] NFS: More readdir cleanups trondmy 2020-11-02 18:06 ` [PATCH 11/12] NFS: nfs_do_filldir() does not return a value trondmy 2020-11-02 18:06 ` [PATCH 12/12] NFS: Reduce readdir stack usage trondmy 2020-11-03 14:18 ` [PATCH 03/12] NFS: Clean up nfs_readdir_page_filler() Benjamin Coddington 2020-11-03 14:24 ` Benjamin Coddington 2020-11-03 13:35 ` [PATCH 02/12] NFS: Clean up readdir struct nfs_cache_array Benjamin Coddington 2020-11-03 14:09 ` Benjamin Coddington 2020-11-03 14:34 ` Benjamin Coddington 2020-11-02 20:40 ` [PATCH 00/12] Readdir enhancements David Wysochanski 2020-11-02 21:32 ` Trond Myklebust
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=20201102180658.6218-6-trondmy@kernel.org \ --to=trondmy@kernel.org \ --cc=linux-nfs@vger.kernel.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
Linux-NFS Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \ linux-nfs@vger.kernel.org public-inbox-index linux-nfs Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-nfs AGPL code for this site: git clone https://public-inbox.org/public-inbox.git