I've moved the whole thing into fhandler_disk_file::open and made it conditional on FILE_SUPPORTS_SPARSE_FILES. I had to add new method to path_conv to get access to flags member of fs_info. This patch includes wincap changes but they can be left out as the rest of the patch doesn't rely on them anymore.
Vaclav Haisman 2003-02-17 Vaclav Haisman <[EMAIL PROTECTED]> * include/winioctl.h (FSCTL_SET_SPARSE): Define. 2003-02-18 Vaclav Haisman <[EMAIL PROTECTED]> * wincap.h (wincaps::supports_sparse_files): New flag. (wincapc::supports_sparse_files): New method. * wincap.cc (wincap_unknown): Define value for the new flag. (wincap_95): Ditto. (wincap_95osr2): Ditto. (wincap_98): Ditto. (wincap_98se): Ditto. (wincap_me): Ditto. (wincap_nt3): Ditto. (wincap_nt4): Ditto. (wincap_nt4sp4): Ditto. (wincap_2000): Ditto. (wincap_xp): Ditto. * path.h (path_conv::fs_flags): New method. * fhandler_disk_file.cc: Include winioctl.h for DeviceIoControl. (fhandler_disk_file::open): Set newly created and truncated files as sparse on platforms that support it. Index: cygwin/fhandler_disk_file.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/fhandler_disk_file.cc,v retrieving revision 1.40 diff -u -p -r1.40 fhandler_disk_file.cc --- cygwin/fhandler_disk_file.cc 10 Feb 2003 22:43:29 -0000 1.40 +++ cygwin/fhandler_disk_file.cc 18 Feb 2003 21:48:39 -0000 @@ -26,6 +26,7 @@ details. */ #include "pinfo.h" #include <assert.h> #include <ctype.h> +#include <winioctl.h> #define _COMPILING_NEWLIB #include <dirent.h> @@ -386,6 +387,19 @@ fhandler_disk_file::open (path_conv *rea return 0; } + /* Set newly created and truncated files as sparse files. */ + if ((real_path->fs_flags () & FILE_SUPPORTS_SPARSE_FILES) + && (get_access () & GENERIC_WRITE) == GENERIC_WRITE + && (get_flags () & (O_CREAT | O_TRUNC))) + { + DWORD dw; + HANDLE h = get_handle (); + BOOL r = DeviceIoControl (h , FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, + NULL); + syscall_printf ("%d = DeviceIoControl(0x%x, FSCTL_SET_SPARSE, NULL, 0, " + "NULL, 0, &dw, NULL)", r, h); + } + set_symlink_p (real_path->issymlink ()); set_execable_p (real_path->exec_state ()); set_socket_p (real_path->issocket ()); Index: cygwin/path.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/path.h,v retrieving revision 1.51 diff -u -p -r1.51 path.h --- cygwin/path.h 13 Feb 2003 03:13:37 -0000 1.51 +++ cygwin/path.h 18 Feb 2003 21:38:50 -0000 @@ -152,6 +152,7 @@ class path_conv short get_unitn () {return devn == FH_BAD ? 0 : unit;} DWORD file_attributes () {return fileattr;} DWORD drive_type () {return fs.drive_type;} + DWORD fs_flags () {return fs.flags;} BOOL fs_fast_ea () {return fs.sym_opt & PC_CHECK_EA;} void set_path (const char *p) {strcpy (path, p);} char *return_and_clear_normalized_path (); Index: cygwin/wincap.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/wincap.cc,v retrieving revision 1.18 diff -u -p -r1.18 wincap.cc --- cygwin/wincap.cc 15 Oct 2002 17:04:20 -0000 1.18 +++ cygwin/wincap.cc 18 Feb 2003 21:38:51 -0000 @@ -47,7 +47,8 @@ static NO_COPY wincaps wincap_unknown = has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_95 = { @@ -86,7 +87,8 @@ static NO_COPY wincaps wincap_95 = { has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_95osr2 = { @@ -125,7 +127,8 @@ static NO_COPY wincaps wincap_95osr2 = { has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_98 = { @@ -164,7 +167,8 @@ static NO_COPY wincaps wincap_98 = { has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_98se = { @@ -203,7 +207,8 @@ static NO_COPY wincaps wincap_98se = { has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_me = { @@ -242,7 +247,8 @@ static NO_COPY wincaps wincap_me = { has_64bit_file_access:false, has_process_io_counters:false, supports_reading_modem_output_lines:false, - needs_memory_protection:false + needs_memory_protection:false, + supports_sparse_files:false }; static NO_COPY wincaps wincap_nt3 = { @@ -281,7 +287,8 @@ static NO_COPY wincaps wincap_nt3 = { has_64bit_file_access:true, has_process_io_counters:false, supports_reading_modem_output_lines:true, - needs_memory_protection:true + needs_memory_protection:true, + supports_sparse_files:false }; static NO_COPY wincaps wincap_nt4 = { @@ -320,7 +327,8 @@ static NO_COPY wincaps wincap_nt4 = { has_64bit_file_access:true, has_process_io_counters:false, supports_reading_modem_output_lines:true, - needs_memory_protection:true + needs_memory_protection:true, + supports_sparse_files:false }; static NO_COPY wincaps wincap_nt4sp4 = { @@ -359,7 +367,8 @@ static NO_COPY wincaps wincap_nt4sp4 = { has_64bit_file_access:true, has_process_io_counters:false, supports_reading_modem_output_lines:true, - needs_memory_protection:true + needs_memory_protection:true, + supports_sparse_files:false }; static NO_COPY wincaps wincap_2000 = { @@ -398,7 +407,8 @@ static NO_COPY wincaps wincap_2000 = { has_64bit_file_access:true, has_process_io_counters:true, supports_reading_modem_output_lines:true, - needs_memory_protection:true + needs_memory_protection:true, + supports_sparse_files:true }; static NO_COPY wincaps wincap_xp = { @@ -437,7 +447,8 @@ static NO_COPY wincaps wincap_xp = { has_64bit_file_access:true, has_process_io_counters:true, supports_reading_modem_output_lines:true, - needs_memory_protection:true + needs_memory_protection:true, + supports_sparse_files:true }; wincapc wincap; Index: cygwin/wincap.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/wincap.h,v retrieving revision 1.14 diff -u -p -r1.14 wincap.h --- cygwin/wincap.h 15 Oct 2002 17:04:20 -0000 1.14 +++ cygwin/wincap.h 18 Feb 2003 21:38:51 -0000 @@ -49,6 +49,7 @@ struct wincaps unsigned has_process_io_counters : 1; unsigned supports_reading_modem_output_lines : 1; unsigned needs_memory_protection : 1; + unsigned supports_sparse_files : 1; }; class wincapc @@ -102,6 +103,7 @@ public: bool IMPLEMENT (has_process_io_counters) bool IMPLEMENT (supports_reading_modem_output_lines) bool IMPLEMENT (needs_memory_protection) + bool IMPLEMENT (supports_sparse_files) #undef IMPLEMENT }; Index: w32api/include/winioctl.h =================================================================== RCS file: /cvs/src/src/winsup/w32api/include/winioctl.h,v retrieving revision 1.8 diff -u -p -r1.8 winioctl.h --- w32api/include/winioctl.h 7 Nov 2002 14:14:01 -0000 1.8 +++ w32api/include/winioctl.h 18 Feb 2003 21:39:00 -0000 @@ -69,6 +69,7 @@ extern "C" { #define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_WRITE_DATA) #define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, +METHOD_BUFFERED, FILE_SPECIAL_ACCESS) #define DEVICE_TYPE DWORD #define FILE_DEVICE_BEEP 1 #define FILE_DEVICE_CD_ROM 2