From: "Benjamin Coddington" <bcodding@redhat.com>
To: trondmy@kernel.org
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH v4 20/21] NFS: Reduce number of RPC calls when doing uncached readdir
Date: Mon, 09 Nov 2020 15:59:53 -0500 [thread overview]
Message-ID: <58FA369F-46B0-47E6-B7C8-E0205427B0C0@redhat.com> (raw)
In-Reply-To: <20201107140325.281678-21-trondmy@kernel.org>
On 7 Nov 2020, at 9:03, trondmy@kernel.org wrote:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
>
> If we're doing uncached readdir, allocate multiple pages in order to
> try to avoid duplicate RPC calls for the same getdents() call.
>
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
Ben
> ---
> fs/nfs/dir.c | 79
> ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 46 insertions(+), 33 deletions(-)
>
> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index b6c3501e8f61..238872d116f7 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -694,12 +694,14 @@ void nfs_prime_dcache(struct dentry *parent,
> struct nfs_entry *entry,
> 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)
> + unsigned int buflen,
> + struct page **arrays,
> + size_t narrays)
> {
> struct address_space *mapping = desc->file->f_mapping;
> struct xdr_stream stream;
> struct xdr_buf buf;
> - struct page *scratch, *new, *page = fillme;
> + struct page *scratch, *new, *page = *arrays;
> int status;
>
> scratch = alloc_page(GFP_KERNEL);
> @@ -725,15 +727,22 @@ static int nfs_readdir_page_filler(struct
> nfs_readdir_descriptor *desc,
> 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)
> - nfs_readdir_page_unlock_and_put(page);
> - page = new;
> + if (narrays > 1) {
> + narrays--;
> + arrays++;
> + page = *arrays;
> + } else {
> + if (page->mapping != mapping)
> + break;
> + new = nfs_readdir_page_get_next(mapping,
> + page->index + 1,
> + entry->prev_cookie);
> + if (!new)
> + break;
> + if (page != *arrays)
> + nfs_readdir_page_unlock_and_put(page);
> + page = new;
> + }
> status = nfs_readdir_add_to_array(entry, page);
> } while (!status && !entry->eof);
>
> @@ -750,7 +759,7 @@ static int nfs_readdir_page_filler(struct
> nfs_readdir_descriptor *desc,
> break;
> }
>
> - if (page != fillme)
> + if (page != *arrays)
> nfs_readdir_page_unlock_and_put(page);
>
> put_page(scratch);
> @@ -790,10 +799,11 @@ static struct page
> **nfs_readdir_alloc_pages(size_t npages)
> }
>
> static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor
> *desc,
> - struct page *page, __be32 *verf_arg,
> - __be32 *verf_res)
> + __be32 *verf_arg, __be32 *verf_res,
> + struct page **arrays, size_t narrays)
> {
> struct page **pages;
> + struct page *page = *arrays;
> struct nfs_entry *entry;
> size_t array_size;
> struct inode *inode = file_inode(desc->file);
> @@ -835,7 +845,8 @@ static int nfs_readdir_xdr_to_array(struct
> nfs_readdir_descriptor *desc,
> break;
> }
>
> - status = nfs_readdir_page_filler(desc, entry, pages, page, pglen);
> + status = nfs_readdir_page_filler(desc, entry, pages, pglen,
> + arrays, narrays);
> } while (!status && nfs_readdir_page_needs_filling(page));
>
> nfs_readdir_free_pages(pages, array_size);
> @@ -884,8 +895,8 @@ static int find_and_lock_cache_page(struct
> nfs_readdir_descriptor *desc)
> if (!desc->page)
> return -ENOMEM;
> if (nfs_readdir_page_needs_filling(desc->page)) {
> - res = nfs_readdir_xdr_to_array(desc, desc->page,
> - nfsi->cookieverf, verf);
> + res = nfs_readdir_xdr_to_array(desc, nfsi->cookieverf, verf,
> + &desc->page, 1);
> if (res < 0) {
> nfs_readdir_page_unlock_and_put_cached(desc);
> if (res == -EBADCOOKIE || res == -ENOTSYNC) {
> @@ -976,35 +987,37 @@ static void nfs_do_filldir(struct
> nfs_readdir_descriptor *desc)
> */
> static int uncached_readdir(struct nfs_readdir_descriptor *desc)
> {
> - struct page *page = NULL;
> + struct page **arrays;
> + size_t i, sz = 16;
> __be32 verf[NFS_DIR_VERIFIER_SIZE];
> int status;
>
> dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie
> %Lu\n",
> (unsigned long long)desc->dir_cookie);
>
> - page = alloc_page(GFP_HIGHUSER);
> - if (!page) {
> - status = -ENOMEM;
> - goto out;
> - }
> + arrays = nfs_readdir_alloc_pages(sz);
> + if (!arrays)
> + return -ENOMEM;
> + for (i = 0; i < sz; i++)
> + nfs_readdir_page_init_array(arrays[i], desc->dir_cookie);
>
> desc->page_index = 0;
> desc->last_cookie = desc->dir_cookie;
> - desc->page = page;
> desc->duped = 0;
>
> - nfs_readdir_page_init_array(page, desc->dir_cookie);
> - status = nfs_readdir_xdr_to_array(desc, page, desc->verf, verf);
> - if (status < 0)
> - goto out_release;
> + status = nfs_readdir_xdr_to_array(desc, desc->verf, verf, arrays,
> sz);
>
> - nfs_do_filldir(desc);
> + for (i = 0; !desc->eof && i < sz; i++) {
> + desc->page = arrays[i];
> + nfs_do_filldir(desc);
> + }
> + desc->page = NULL;
> +
> +
> + for (i = 0; i < sz; i++)
> + nfs_readdir_clear_array(arrays[i]);
> + nfs_readdir_free_pages(arrays, sz);
>
> - out_release:
> - nfs_readdir_clear_array(desc->page);
> - nfs_readdir_page_put(desc);
> - out:
> dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
> __func__, status);
> return status;
> --
> 2.28.0
next prev parent reply other threads:[~2020-11-09 21:00 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-07 14:03 [PATCH v4 00/21] Readdir enhancements trondmy
2020-11-07 14:03 ` [PATCH v4 01/21] NFS: Remove unnecessary inode locking in nfs_llseek_dir() trondmy
2020-11-07 14:03 ` [PATCH v4 02/21] NFS: Remove unnecessary inode lock in nfs_fsync_dir() trondmy
2020-11-07 14:03 ` [PATCH v4 03/21] NFS: Ensure contents of struct nfs_open_dir_context are consistent trondmy
2020-11-07 14:03 ` [PATCH v4 04/21] NFS: Clean up readdir struct nfs_cache_array trondmy
2020-11-07 14:03 ` [PATCH v4 05/21] NFS: Clean up nfs_readdir_page_filler() trondmy
2020-11-07 14:03 ` [PATCH v4 06/21] NFS: Clean up directory array handling trondmy
2020-11-07 14:03 ` [PATCH v4 07/21] NFS: Don't discard readdir results trondmy
2020-11-07 14:03 ` [PATCH v4 08/21] NFS: Remove unnecessary kmap in nfs_readdir_xdr_to_array() trondmy
2020-11-07 14:03 ` [PATCH v4 09/21] NFS: Replace kmap() with kmap_atomic() in nfs_readdir_search_array() trondmy
2020-11-07 14:03 ` [PATCH v4 10/21] NFS: Simplify struct nfs_cache_array_entry trondmy
2020-11-07 14:03 ` [PATCH v4 11/21] NFS: Support larger readdir buffers trondmy
2020-11-07 14:03 ` [PATCH v4 12/21] NFS: More readdir cleanups trondmy
2020-11-07 14:03 ` [PATCH v4 13/21] NFS: nfs_do_filldir() does not return a value trondmy
2020-11-07 14:03 ` [PATCH v4 14/21] NFS: Reduce readdir stack usage trondmy
2020-11-07 14:03 ` [PATCH v4 15/21] NFS: Cleanup to remove nfs_readdir_descriptor_t typedef trondmy
2020-11-07 14:03 ` [PATCH v4 16/21] NFS: Allow the NFS generic code to pass in a verifier to readdir trondmy
2020-11-07 14:03 ` [PATCH v4 17/21] NFS: Handle NFS4ERR_NOT_SAME and NFSERR_BADCOOKIE from readdir calls trondmy
2020-11-07 14:03 ` [PATCH v4 18/21] NFS: Improve handling of directory verifiers trondmy
2020-11-07 14:03 ` [PATCH v4 19/21] NFS: Optimisations for monotonically increasing readdir cookies trondmy
2020-11-07 14:03 ` [PATCH v4 20/21] NFS: Reduce number of RPC calls when doing uncached readdir trondmy
2020-11-07 14:03 ` [PATCH v4 21/21] NFS: Do uncached readdir when we're seeking a cookie in an empty page cache trondmy
2020-11-09 21:41 ` Benjamin Coddington
2020-11-09 21:46 ` Trond Myklebust
2020-11-11 16:43 ` Benjamin Coddington
2020-11-11 17:34 ` Trond Myklebust
2020-11-11 19:53 ` Benjamin Coddington
2020-11-11 20:11 ` Trond Myklebust
2020-11-10 14:48 ` David Wysochanski
2020-11-10 20:55 ` Trond Myklebust
2020-11-09 20:59 ` Benjamin Coddington [this message]
2020-11-09 13:15 ` [PATCH v4 00/21] Readdir enhancements David Wysochanski
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=58FA369F-46B0-47E6-B7C8-E0205427B0C0@redhat.com \
--to=bcodding@redhat.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trondmy@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
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).