lkml.org 
[lkml]   [2021]   [Feb]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 39/65] cifs: report error instead of invalid when revalidating a dentry fails
    Date
    From: Aurelien Aptel <aaptel@suse.com>

    commit 21b200d091826a83aafc95d847139b2b0582f6d1 upstream.

    Assuming
    - //HOST/a is mounted on /mnt
    - //HOST/b is mounted on /mnt/b

    On a slow connection, running 'df' and killing it while it's
    processing /mnt/b can make cifs_get_inode_info() returns -ERESTARTSYS.

    This triggers the following chain of events:
    => the dentry revalidation fail
    => dentry is put and released
    => superblock associated with the dentry is put
    => /mnt/b is unmounted

    This patch makes cifs_d_revalidate() return the error instead of 0
    (invalid) when cifs_revalidate_dentry() fails, except for ENOENT (file
    deleted) and ESTALE (file recreated).

    Signed-off-by: Aurelien Aptel <aaptel@suse.com>
    Suggested-by: Shyam Prasad N <nspmangalore@gmail.com>
    Reviewed-by: Shyam Prasad N <nspmangalore@gmail.com>
    CC: stable@vger.kernel.org
    Signed-off-by: Steve French <stfrench@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/cifs/dir.c | 22 ++++++++++++++++++++--
    1 file changed, 20 insertions(+), 2 deletions(-)

    --- a/fs/cifs/dir.c
    +++ b/fs/cifs/dir.c
    @@ -738,6 +738,7 @@ static int
    cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
    {
    struct inode *inode;
    + int rc;

    if (flags & LOOKUP_RCU)
    return -ECHILD;
    @@ -747,8 +748,25 @@ cifs_d_revalidate(struct dentry *direntr
    if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
    CIFS_I(inode)->time = 0; /* force reval */

    - if (cifs_revalidate_dentry(direntry))
    - return 0;
    + rc = cifs_revalidate_dentry(direntry);
    + if (rc) {
    + cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc);
    + switch (rc) {
    + case -ENOENT:
    + case -ESTALE:
    + /*
    + * Those errors mean the dentry is invalid
    + * (file was deleted or recreated)
    + */
    + return 0;
    + default:
    + /*
    + * Otherwise some unexpected error happened
    + * report it as-is to VFS layer
    + */
    + return rc;
    + }
    + }
    else {
    /*
    * If the inode wasn't known to be a dfs entry when

    \
     
     \ /
      Last update: 2021-02-08 17:40    [W:29.593 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site