lkml.org 
[lkml]   [2021]   [May]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.11 133/329] NFS: Fix handling of cookie verifier in uncached_readdir()
    Date
    From: Trond Myklebust <trond.myklebust@hammerspace.com>

    [ Upstream commit 13884ff2bef01df37c450c6dd09122f92333dccc ]

    If we're doing uncached readdir(), then the readdir cookie could be
    different from the one cached in the nfs_inode. We should therefore
    ensure that we save that one in the struct nfs_open_dir_context.

    Fixes: 35df59d3ef69 ("NFS: Reduce number of RPC calls when doing uncached readdir")
    Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/nfs/dir.c | 13 +++++++------
    1 file changed, 7 insertions(+), 6 deletions(-)

    diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
    index c3618b6abfc0..ca1dddc81436 100644
    --- a/fs/nfs/dir.c
    +++ b/fs/nfs/dir.c
    @@ -975,10 +975,10 @@ static int readdir_search_pagecache(struct nfs_readdir_descriptor *desc)
    /*
    * Once we've found the start of the dirent within a page: fill 'er up...
    */
    -static void nfs_do_filldir(struct nfs_readdir_descriptor *desc)
    +static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
    + const __be32 *verf)
    {
    struct file *file = desc->file;
    - struct nfs_inode *nfsi = NFS_I(file_inode(file));
    struct nfs_cache_array *array;
    unsigned int i = 0;

    @@ -992,7 +992,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc)
    desc->eof = true;
    break;
    }
    - memcpy(desc->verf, nfsi->cookieverf, sizeof(desc->verf));
    + memcpy(desc->verf, verf, sizeof(desc->verf));
    if (i < (array->size-1))
    desc->dir_cookie = array->array[i+1].cookie;
    else
    @@ -1049,7 +1049,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)

    for (i = 0; !desc->eof && i < sz && arrays[i]; i++) {
    desc->page = arrays[i];
    - nfs_do_filldir(desc);
    + nfs_do_filldir(desc, verf);
    }
    desc->page = NULL;

    @@ -1070,6 +1070,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
    {
    struct dentry *dentry = file_dentry(file);
    struct inode *inode = d_inode(dentry);
    + struct nfs_inode *nfsi = NFS_I(inode);
    struct nfs_open_dir_context *dir_ctx = file->private_data;
    struct nfs_readdir_descriptor *desc;
    int res;
    @@ -1123,7 +1124,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
    break;
    }
    if (res == -ETOOSMALL && desc->plus) {
    - clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
    + clear_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
    nfs_zap_caches(inode);
    desc->page_index = 0;
    desc->plus = false;
    @@ -1133,7 +1134,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
    if (res < 0)
    break;

    - nfs_do_filldir(desc);
    + nfs_do_filldir(desc, nfsi->cookieverf);
    nfs_readdir_page_unlock_and_put_cached(desc);
    } while (!desc->eof);

    --
    2.30.2


    \
     
     \ /
      Last update: 2021-05-17 17:31    [W:4.791 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site