On 11.08.2022 15:54, Pavel Tikhomirov wrote:
Imagine code path:

static
void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
{
...
         dentry = d_lookup(parent, &filename); // get non-null dentry
         if (dentry != NULL) { // true
                 /* Is there a mountpoint here? If so, just exit */
                 if (!nfs_fsid_equal(&NFS_SB(dentry->d_sb)->fsid,
                                         &entry->fattr->fsid)) // false
                         goto out;
                 if (nfs_same_file(dentry, entry)) { // false
                         if (!entry->fh->size)
                                 goto out;
                         nfs_set_verifier(dentry, 
nfs_save_change_attribute(dir));
                         status = nfs_refresh_inode(dentry->d_inode, 
entry->fattr);
                         if (!status)
                                 nfs_setsecurity(dentry->d_inode, entry->fattr, 
entry->label);
                         goto out;
                 } else {
                         if (d_invalidate(dentry) != 0) // false
                                 goto out;
                         dput(dentry); // put dentry first time
                 }
         }
         if (!entry->fh->size) // true
                goto out;
...
out:
         dput(dentry); // put dentry second time
}

Because of this excess dput we get a crash in __put_nfs_open_context
as ctx->dentry->inode becomes zero.

Problem appeared due to bad port of [1] in RHEL.

7dc72d5f7a0e ("NFS: Fix inode corruption in nfs_prime_dcache()") [1]

https://jira.sw.ru/browse/PSBM-141526
Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>

Acked-by: Konstantin Khorenko <khore...@virtuozzo.com>

---
  fs/nfs/dir.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index bd1a419d34c7..033e65319327 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -527,7 +527,7 @@ void nfs_prime_dcache(struct dentry *parent, struct 
nfs_entry *entry)
                }
        }
        if (!entry->fh->size)
-               goto out;
+               return;
dentry = d_alloc(parent, &filename);
        if (dentry == NULL)
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to