Skip to content

Commit d94edba

Browse files
neerajsi-msftdscho
authored andcommitted
core.fsyncobjectfiles: add windows support for batch mode
This commit adds a win32 implementation for fsync_no_flush that is called git_fsync. The 'NtFlushBuffersFileEx' function being called is available since Windows 8. If the function is not available, we return -1 and Git falls back to doing a full fsync. The operating system is told to flush data only without a hardware flush primitive. A later full fsync will cause the metadata log to be flushed and then the disk cache to be flushed on NTFS and ReFS. Other filesystems will treat this as a full flush operation. I added a new file here for this system call so as not to conflict with downstream changes in the git-for-windows repository related to fscache. Signed-off-by: Neeraj Singh <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b4be391 commit d94edba

File tree

5 files changed

+39
-1
lines changed

5 files changed

+39
-1
lines changed

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ int mingw_getpagesize(void);
329329
#define getpagesize mingw_getpagesize
330330
#endif
331331

332+
int win32_fsync_no_flush(int fd);
333+
#define fsync_no_flush win32_fsync_no_flush
334+
332335
struct rlimit {
333336
unsigned int rlim_cur;
334337
};

compat/win32/flush.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "../../git-compat-util.h"
2+
#include <winternl.h>
3+
#include "lazyload.h"
4+
5+
int win32_fsync_no_flush(int fd)
6+
{
7+
IO_STATUS_BLOCK io_status;
8+
9+
#define FLUSH_FLAGS_FILE_DATA_ONLY 1
10+
11+
DECLARE_PROC_ADDR(ntdll.dll, NTSTATUS, NTAPI, NtFlushBuffersFileEx,
12+
HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParameterSize,
13+
PIO_STATUS_BLOCK IoStatusBlock);
14+
15+
if (!INIT_PROC_ADDR(NtFlushBuffersFileEx)) {
16+
errno = ENOSYS;
17+
return -1;
18+
}
19+
20+
memset(&io_status, 0, sizeof(io_status));
21+
if (NtFlushBuffersFileEx((HANDLE)_get_osfhandle(fd), FLUSH_FLAGS_FILE_DATA_ONLY,
22+
NULL, 0, &io_status)) {
23+
errno = EINVAL;
24+
return -1;
25+
}
26+
27+
return 0;
28+
}

config.mak.uname

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ endif
463463
CFLAGS =
464464
BASIC_CFLAGS = -nologo -I. -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
465465
COMPAT_OBJS = compat/msvc.o compat/winansi.o \
466+
compat/win32/flush.o \
466467
compat/win32/path-utils.o \
467468
compat/win32/pthread.o compat/win32/syslog.o \
468469
compat/win32/trace2_win32_process_info.o \
@@ -640,6 +641,7 @@ ifeq ($(uname_S),MINGW)
640641
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
641642
COMPAT_OBJS += compat/mingw.o compat/winansi.o \
642643
compat/win32/trace2_win32_process_info.o \
644+
compat/win32/flush.o \
643645
compat/win32/path-utils.o \
644646
compat/win32/pthread.o compat/win32/syslog.o \
645647
compat/win32/dirent.o

contrib/buildsystems/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
261261
NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0
262262
USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP
263263
UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET)
264-
list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c compat/win32/path-utils.c
264+
list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c
265+
compat/win32/flush.c compat/win32/path-utils.c
265266
compat/win32/pthread.c compat/win32mmap.c compat/win32/syslog.c
266267
compat/win32/trace2_win32_process_info.c compat/win32/dirent.c
267268
compat/nedmalloc/nedmalloc.c compat/strdup.c)

wrapper.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ int git_fsync(int fd, enum fsync_action action)
573573
SYNC_FILE_RANGE_WAIT_AFTER);
574574
#endif
575575

576+
#ifdef fsync_no_flush
577+
return fsync_no_flush(fd);
578+
#endif
579+
576580
errno = ENOSYS;
577581
return -1;
578582

0 commit comments

Comments
 (0)