Paul Gofman : ntdll: Perform fsync() in client for files and directories.

Alexandre Julliard julliard at winehq.org
Tue Jun 9 15:27:49 CDT 2020


Module: wine
Branch: master
Commit: 3078f10d43d834b0498358fe0accb565191b7020
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3078f10d43d834b0498358fe0accb565191b7020

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Tue Jun  9 20:00:07 2020 +0300

ntdll: Perform fsync() in client for files and directories.

Fixes stuttering in Assetto Corsa Competizione (multiplayer mode).

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/file.c       | 10 +++++++++-
 dlls/ntdll/tests/file.c | 21 +++++++++++++++++++++
 server/file.c           | 14 +-------------
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 1b70e47367..aba7b608f6 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -3584,7 +3584,15 @@ NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK *io )
     if (ret == STATUS_ACCESS_DENIED)
         ret = unix_funcs->server_get_unix_fd( hFile, FILE_APPEND_DATA, &fd, &needs_close, &type, NULL );
 
-    if (!ret && type == FD_TYPE_SERIAL)
+    if (!ret && (type == FD_TYPE_FILE || type == FD_TYPE_DIR))
+    {
+        if (fsync(fd))
+            ret = FILE_GetNtStatus();
+
+        io->u.Status    = ret;
+        io->Information = 0;
+    }
+    else if (!ret && type == FD_TYPE_SERIAL)
     {
         ret = COMM_FlushBuffersFile( fd );
     }
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 1d0682a633..184b7cdad5 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -4860,14 +4860,26 @@ static void test_flush_buffers_file(void)
     status = pNtFlushBuffersFile(hfile, (IO_STATUS_BLOCK *)0xdeadbeaf);
     ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status);
 
+    io_status_block.Information = 0xdeadbeef;
+    io_status_block.Status = 0xdeadbeef;
     status = pNtFlushBuffersFile(hfile, &io_status_block);
     ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
+    ok(io_status_block.Status == STATUS_SUCCESS, "Got unexpected io_status_block.Status %#x.\n",
+            io_status_block.Status);
+    ok(!io_status_block.Information, "Got unexpected io_status_block.Information %#lx.\n",
+            io_status_block.Information);
 
     status = pNtFlushBuffersFile(hfileread, &io_status_block);
     ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#x.\n", status);
 
+    io_status_block.Information = 0xdeadbeef;
+    io_status_block.Status = 0xdeadbeef;
     status = pNtFlushBuffersFile(NULL, &io_status_block);
     ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status);
+    ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#x.\n",
+            io_status_block.Status);
+    ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#lx.\n",
+            io_status_block.Information);
 
     CloseHandle(hfileread);
     CloseHandle(hfile);
@@ -4878,6 +4890,15 @@ static void test_flush_buffers_file(void)
     status = pNtFlushBuffersFile(hfile, &io_status_block);
     ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#x.\n", status);
 
+    io_status_block.Information = 0xdeadbeef;
+    io_status_block.Status = 0xdeadbeef;
+    status = pNtFlushBuffersFile((HANDLE)0xdeadbeef, &io_status_block);
+    ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#x.\n", status);
+    ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#x.\n",
+            io_status_block.Status);
+    ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#lx.\n",
+            io_status_block.Information);
+
     CloseHandle(hfile);
     DeleteFileA(buffer);
 }
diff --git a/server/file.c b/server/file.c
index bce202138e..38260cfd2b 100644
--- a/server/file.c
+++ b/server/file.c
@@ -75,7 +75,6 @@ static struct list *file_get_kernel_obj_list( struct object *obj );
 static void file_destroy( struct object *obj );
 
 static int file_get_poll_events( struct fd *fd );
-static int file_flush( struct fd *fd, struct async *async );
 static enum server_fd_type file_get_fd_type( struct fd *fd );
 
 static const struct object_ops file_ops =
@@ -108,7 +107,7 @@ static const struct fd_ops file_fd_ops =
     file_get_fd_type,             /* get_fd_type */
     no_fd_read,                   /* read */
     no_fd_write,                  /* write */
-    file_flush,                   /* flush */
+    no_fd_flush,                  /* flush */
     default_fd_get_file_info,     /* get_file_info */
     no_fd_get_volume_info,        /* get_volume_info */
     default_fd_ioctl,             /* ioctl */
@@ -296,17 +295,6 @@ static int file_get_poll_events( struct fd *fd )
     return events;
 }
 
-static int file_flush( struct fd *fd, struct async *async )
-{
-    int unix_fd = get_unix_fd( fd );
-    if (unix_fd != -1 && fsync( unix_fd ) == -1)
-    {
-        file_set_error();
-        return 0;
-    }
-    return 1;
-}
-
 static enum server_fd_type file_get_fd_type( struct fd *fd )
 {
     struct file *file = get_fd_user( fd );




More information about the wine-cvs mailing list