From bc4f1d60680bf1c8c69a4eb935715b6cf5c04ba5 Mon Sep 17 00:00:00 2001
From: Eric Pouech <epouech@codeweavers.com>
Date: Sun, 30 Jun 2024 09:54:37 +0200
Subject: [PATCH] server: Ensure in pending delete on close that path to unlink
 are unique.

This avoids the server piling up closed_fd objects when several delete are
called on the same path.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
---
 server/fd.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/server/fd.c b/server/fd.c
index c82ed49034e..ce32e7f8397 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1169,6 +1169,15 @@ static struct inode *get_inode( dev_t dev, ino_t ino, int unix_fd )
     return inode;
 }
 
+static int inode_has_pending_close( struct inode *inode, const char *path )
+{
+    struct closed_fd *fd;
+
+    LIST_FOR_EACH_ENTRY( fd, &inode->closed, struct closed_fd, entry )
+        if (!strcmp( fd->unix_name, path )) return 1;
+    return 0;
+}
+
 /* add fd to the inode list of file descriptors to close */
 static void inode_add_closed_fd( struct inode *inode, struct closed_fd *fd )
 {
@@ -1185,7 +1194,7 @@ static void inode_add_closed_fd( struct inode *inode, struct closed_fd *fd )
         free( fd->unix_name );
         free( fd );
     }
-    else if (fd->disp_flags & FILE_DISPOSITION_DELETE)
+    else if ((fd->disp_flags & FILE_DISPOSITION_DELETE) && !inode_has_pending_close( inode, fd->unix_name ))
     {
         /* close the fd but keep the structure around for unlink */
         if (fd->unix_fd != -1) close( fd->unix_fd );
-- 
GitLab