From 4dd25011f0e17509b1641ae76a8fb8022018a6d3 Mon Sep 17 00:00:00 2001 From: Jim906 Date: Wed, 14 May 2025 10:16:53 -0400 Subject: [PATCH] nfs4: Avoid deleting nodes when unlinking * Stop deleting Inode objects in VnodeToInode::Unlink(). * Allow ~VnodeToInode() to do this in nfs4_remove_vnode(), instead. At the time the unlink hook is called, other threads could still have the file open. With this change, the nfs4 driver can pass the open/unlink test in the Connectathon NFS testsuite. Change-Id: I6e4f67fbafad73dd2eeb285dbd2b9fa9670bf5b5 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9282 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp | 9 ++------- .../kernel/file_systems/nfs4/kernel_interface.cpp | 9 +++------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp index 198964017c..47635f3b40 100644 --- a/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/VnodeToInode.cpp @@ -39,13 +39,8 @@ VnodeToInode::Unlink(InodeNames* parent, const char* name) { WriteLocker _(fLock); if (fInode != NULL && !IsRoot()) { - bool removed = fInode->GetFileSystem()->InoIdMap()->RemoveName(fID, - parent, name); - if (removed) { - delete fInode; - fInode = NULL; - } - return removed; + return fInode->GetFileSystem()->InoIdMap()->RemoveName(fID, parent, + name); } return false; diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index a8c68bed40..b46d2608a9 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -341,13 +341,10 @@ nfs4_remove_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter) if (node == fs->Root()) return B_OK; - if (node != NULL && node->IsStale()) { - // in the case of a stale node, VnodeToInode::Unlink was never called by the client, - // so the Inode hasn't been deleted yet - vti->Clear(); - } + // Verify that all known names have been unlinked. + FileInfo fileInfo; + ASSERT(fs->InoIdMap()->GetFileInfo(&fileInfo, vti->ID()) == B_ENTRY_NOT_FOUND); - ASSERT(vti->GetPointer() == NULL); delete vti; return B_OK;