Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2023-11-28 00:48:50 +0300
committerCorinna Vinschen <corinna@vinschen.de>2023-11-28 12:55:38 +0300
commitf64f3eced8e0f51753bc199f3ba96fab06a54848 (patch)
tree49469f3ec06191c031172782e3ec191a484b67c4 /winsup
parent114f89caff7b9b62b0b12bc2c6d143daf47b8042 (diff)
Cygwin: pwrite(2): sparsify file
write(2) sparsifies a file after an lseek far enough beyond EOF. Let pwrite(2) sparsify as well if offset is far enough beyond EOF. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/fhandler/disk_file.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index b49b25c71..c70afed49 100644
--- a/winsup/cygwin/fhandler/disk_file.cc
+++ b/winsup/cygwin/fhandler/disk_file.cc
@@ -1724,6 +1724,7 @@ fhandler_disk_file::pwrite (void *buf, size_t count, off_t offset, void *aio)
{
NTSTATUS status;
IO_STATUS_BLOCK io;
+ FILE_STANDARD_INFORMATION fsi;
LARGE_INTEGER off = { QuadPart:offset };
HANDLE evt = aio ? (HANDLE) aiocb->aio_wincb.event : NULL;
PIO_STATUS_BLOCK pio = aio ? (PIO_STATUS_BLOCK) &aiocb->aio_wincb : &io;
@@ -1732,6 +1733,25 @@ fhandler_disk_file::pwrite (void *buf, size_t count, off_t offset, void *aio)
if (prw_handle && (prw_handle_isasync != !!aio))
NtClose (prw_handle), prw_handle = NULL;
+ /* If the file system supports sparse files and the application is
+ writing beyond EOF spanning more than one sparsifiable chunk,
+ convert the file to a sparse file. */
+ if (pc.support_sparse ()
+ && !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
+ && NT_SUCCESS (NtQueryInformationFile (get_handle (),
+ &io, &fsi, sizeof fsi,
+ FileStandardInformation))
+ && offset >= fsi.EndOfFile.QuadPart + (128 * 1024))
+ {
+ NTSTATUS status;
+ status = NtFsControlFile (get_handle (), NULL, NULL, NULL,
+ &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
+ if (NT_SUCCESS (status))
+ pc.file_attributes (pc.file_attributes ()
+ | FILE_ATTRIBUTE_SPARSE_FILE);
+ debug_printf ("%y = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
+ status, pc.get_nt_native_path ());
+ }
if (!prw_handle && prw_open (true, aio))
goto non_atomic;
status = NtWriteFile (prw_handle, evt, NULL, NULL, pio, buf, count,