* fhandler.cc (fhandler_base::write): Don't attempt to sparsify
an already sparse file. Drop check for FILE_SUPPORTS_SPARSE_FILES flag. Explicitely set FILE_ATTRIBUTE_SPARSE_FILE attribute in cached attributes. (fhandler_base::lseek): Only set did_lseek if sparseness is supported. * fhandler_disk_file.cc (fhandler_disk_file::ftruncate): Don't attempt to sparsify an already sparse file. Explicitely set FILE_ATTRIBUTE_SPARSE_FILE attribute in cached attributes. * mount.cc (oopt): Add "sparse" flag. (fillout_mntent): Ditto. * path.h (enum path_types): Add PATH_SPARSE. (path_conv::support_sparse): New method. (path_conv::fs_flags): Constify. (path_conv::fs_name_len): Ditto. include/sys/mount.h: Replace unused MOUNT_MIXED flag with MOUNT_SPARSE.
This commit is contained in:
parent
60f901f4a9
commit
05297cca5f
@ -1,3 +1,21 @@
|
|||||||
|
2012-12-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.cc (fhandler_base::write): Don't attempt to sparsify
|
||||||
|
an already sparse file. Drop check for FILE_SUPPORTS_SPARSE_FILES
|
||||||
|
flag. Explicitely set FILE_ATTRIBUTE_SPARSE_FILE attribute in
|
||||||
|
cached attributes.
|
||||||
|
(fhandler_base::lseek): Only set did_lseek if sparseness is supported.
|
||||||
|
* fhandler_disk_file.cc (fhandler_disk_file::ftruncate): Don't attempt
|
||||||
|
to sparsify an already sparse file. Explicitely set
|
||||||
|
FILE_ATTRIBUTE_SPARSE_FILE attribute in cached attributes.
|
||||||
|
* mount.cc (oopt): Add "sparse" flag.
|
||||||
|
(fillout_mntent): Ditto.
|
||||||
|
* path.h (enum path_types): Add PATH_SPARSE.
|
||||||
|
(path_conv::support_sparse): New method.
|
||||||
|
(path_conv::fs_flags): Constify.
|
||||||
|
(path_conv::fs_name_len): Ditto.
|
||||||
|
include/sys/mount.h: Replace unused MOUNT_MIXED flag with MOUNT_SPARSE.
|
||||||
|
|
||||||
2012-12-10 Christopher Faylor <me.cygwin2012@cgf.cx>
|
2012-12-10 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||||
|
|
||||||
* sigproc.h (sig_send): Accept tid as argument #3. Default to NULL.
|
* sigproc.h (sig_send): Accept tid as argument #3. Default to NULL.
|
||||||
|
@ -817,15 +817,17 @@ ssize_t __stdcall
|
|||||||
fhandler_base::write (const void *ptr, size_t len)
|
fhandler_base::write (const void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (did_lseek ())
|
||||||
|
{
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
FILE_POSITION_INFORMATION fpi;
|
FILE_POSITION_INFORMATION fpi;
|
||||||
FILE_STANDARD_INFORMATION fsi;
|
FILE_STANDARD_INFORMATION fsi;
|
||||||
|
|
||||||
if (did_lseek ())
|
|
||||||
{
|
|
||||||
did_lseek (false); /* don't do it again */
|
did_lseek (false); /* don't do it again */
|
||||||
|
|
||||||
if (!(get_flags () & O_APPEND)
|
if (!(get_flags () & O_APPEND)
|
||||||
|
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
|
||||||
&& NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
|
&& NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
|
||||||
&io, &fsi, sizeof fsi,
|
&io, &fsi, sizeof fsi,
|
||||||
FileStandardInformation))
|
FileStandardInformation))
|
||||||
@ -833,8 +835,7 @@ fhandler_base::write (const void *ptr, size_t len)
|
|||||||
&io, &fpi, sizeof fpi,
|
&io, &fpi, sizeof fpi,
|
||||||
FilePositionInformation))
|
FilePositionInformation))
|
||||||
&& fpi.CurrentByteOffset.QuadPart
|
&& fpi.CurrentByteOffset.QuadPart
|
||||||
>= fsi.EndOfFile.QuadPart + (128 * 1024)
|
>= fsi.EndOfFile.QuadPart + (128 * 1024))
|
||||||
&& (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES))
|
|
||||||
{
|
{
|
||||||
/* If the file system supports sparse files and the application
|
/* If the file system supports sparse files and the application
|
||||||
is writing after a long seek beyond EOF, convert the file to
|
is writing after a long seek beyond EOF, convert the file to
|
||||||
@ -842,6 +843,9 @@ fhandler_base::write (const void *ptr, size_t len)
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
|
status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
|
||||||
&io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
&io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
pc.file_attributes (pc.file_attributes ()
|
||||||
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
||||||
debug_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
debug_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
}
|
}
|
||||||
@ -1071,6 +1075,7 @@ fhandler_base::lseek (_off64_t offset, int whence)
|
|||||||
|
|
||||||
/* When next we write(), we will check to see if *this* seek went beyond
|
/* When next we write(), we will check to see if *this* seek went beyond
|
||||||
the end of the file and if so, potentially sparsify the file. */
|
the end of the file and if so, potentially sparsify the file. */
|
||||||
|
if (pc.support_sparse ())
|
||||||
did_lseek (true);
|
did_lseek (true);
|
||||||
|
|
||||||
/* If this was a SEEK_CUR with offset 0, we still might have
|
/* If this was a SEEK_CUR with offset 0, we still might have
|
||||||
|
@ -1189,12 +1189,15 @@ fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
|
|||||||
feofi.EndOfFile.QuadPart = length;
|
feofi.EndOfFile.QuadPart = length;
|
||||||
/* Create sparse files only when called through ftruncate, not when
|
/* Create sparse files only when called through ftruncate, not when
|
||||||
called through posix_fallocate. */
|
called through posix_fallocate. */
|
||||||
if (allow_truncate
|
if (allow_truncate && pc.support_sparse ()
|
||||||
&& (pc.fs_flags () & FILE_SUPPORTS_SPARSE_FILES)
|
&& !has_attribute (FILE_ATTRIBUTE_SPARSE_FILE)
|
||||||
&& length >= fsi.EndOfFile.QuadPart + (128 * 1024))
|
&& length >= fsi.EndOfFile.QuadPart + (128 * 1024))
|
||||||
{
|
{
|
||||||
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
|
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
|
||||||
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
pc.file_attributes (pc.file_attributes ()
|
||||||
|
| FILE_ATTRIBUTE_SPARSE_FILE);
|
||||||
syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
|
||||||
status, pc.get_nt_native_path ());
|
status, pc.get_nt_native_path ());
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,8 @@ enum
|
|||||||
device mount */
|
device mount */
|
||||||
MOUNT_CYGWIN_EXEC = 0x00040, /* file or directory is or contains a
|
MOUNT_CYGWIN_EXEC = 0x00040, /* file or directory is or contains a
|
||||||
cygwin executable */
|
cygwin executable */
|
||||||
MOUNT_MIXED = 0x00080, /* reads are text, writes are binary
|
MOUNT_SPARSE = 0x00080, /* Support automatic sparsifying of
|
||||||
not yet implemented */
|
files. */
|
||||||
MOUNT_NOTEXEC = 0x00100, /* don't check files for executable magic */
|
MOUNT_NOTEXEC = 0x00100, /* don't check files for executable magic */
|
||||||
MOUNT_DEVFS = 0x00200, /* /device "filesystem" */
|
MOUNT_DEVFS = 0x00200, /* /device "filesystem" */
|
||||||
MOUNT_PROC = 0x00400, /* /proc "filesystem" */
|
MOUNT_PROC = 0x00400, /* /proc "filesystem" */
|
||||||
|
@ -1028,6 +1028,7 @@ struct opt
|
|||||||
{"override", MOUNT_OVERRIDE, 0},
|
{"override", MOUNT_OVERRIDE, 0},
|
||||||
{"posix=0", MOUNT_NOPOSIX, 0},
|
{"posix=0", MOUNT_NOPOSIX, 0},
|
||||||
{"posix=1", MOUNT_NOPOSIX, 1},
|
{"posix=1", MOUNT_NOPOSIX, 1},
|
||||||
|
{"sparse", MOUNT_SPARSE, 0},
|
||||||
{"text", MOUNT_BINARY, 1},
|
{"text", MOUNT_BINARY, 1},
|
||||||
{"user", MOUNT_SYSTEM, 1}
|
{"user", MOUNT_SYSTEM, 1}
|
||||||
};
|
};
|
||||||
@ -1667,6 +1668,9 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
|||||||
if (flags & MOUNT_NOPOSIX)
|
if (flags & MOUNT_NOPOSIX)
|
||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",posix=0");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",posix=0");
|
||||||
|
|
||||||
|
if (flags & MOUNT_SPARSE)
|
||||||
|
strcat (_my_tls.locals.mnt_opts, (char *) ",sparse");
|
||||||
|
|
||||||
if (!(flags & MOUNT_SYSTEM)) /* user mount */
|
if (!(flags & MOUNT_SYSTEM)) /* user mount */
|
||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",user");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",user");
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ enum path_types
|
|||||||
PATH_EXEC = MOUNT_EXEC,
|
PATH_EXEC = MOUNT_EXEC,
|
||||||
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
||||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||||
|
PATH_SPARSE = MOUNT_SPARSE,
|
||||||
PATH_RO = MOUNT_RO,
|
PATH_RO = MOUNT_RO,
|
||||||
PATH_NOACL = MOUNT_NOACL,
|
PATH_NOACL = MOUNT_NOACL,
|
||||||
PATH_NOPOSIX = MOUNT_NOPOSIX,
|
PATH_NOPOSIX = MOUNT_NOPOSIX,
|
||||||
@ -153,6 +154,11 @@ class path_conv
|
|||||||
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
|
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
|
||||||
bool hasgood_inode () const {return !(path_flags & PATH_IHASH); }
|
bool hasgood_inode () const {return !(path_flags & PATH_IHASH); }
|
||||||
bool isgood_inode (__ino64_t ino) const;
|
bool isgood_inode (__ino64_t ino) const;
|
||||||
|
bool support_sparse () const
|
||||||
|
{
|
||||||
|
return (path_flags & PATH_SPARSE)
|
||||||
|
&& (fs_flags () & FILE_SUPPORTS_SPARSE_FILES);
|
||||||
|
}
|
||||||
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
|
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
|
||||||
int has_dos_filenames_only () const {return path_flags & PATH_DOS;}
|
int has_dos_filenames_only () const {return path_flags & PATH_DOS;}
|
||||||
int has_buggy_open () const {return fs.has_buggy_open ();}
|
int has_buggy_open () const {return fs.has_buggy_open ();}
|
||||||
@ -342,8 +348,8 @@ class path_conv
|
|||||||
short get_unitn () const {return dev.get_minor ();}
|
short get_unitn () const {return dev.get_minor ();}
|
||||||
DWORD file_attributes () const {return fileattr;}
|
DWORD file_attributes () const {return fileattr;}
|
||||||
void file_attributes (DWORD new_attr) {fileattr = new_attr;}
|
void file_attributes (DWORD new_attr) {fileattr = new_attr;}
|
||||||
DWORD fs_flags () {return fs.flags ();}
|
DWORD fs_flags () const {return fs.flags ();}
|
||||||
DWORD fs_name_len () {return fs.name_len ();}
|
DWORD fs_name_len () const {return fs.name_len ();}
|
||||||
bool fs_got_fs () const { return fs.got_fs (); }
|
bool fs_got_fs () const { return fs.got_fs (); }
|
||||||
bool fs_is_fat () const {return fs.is_fat ();}
|
bool fs_is_fat () const {return fs.is_fat ();}
|
||||||
bool fs_is_ntfs () const {return fs.is_ntfs ();}
|
bool fs_is_ntfs () const {return fs.is_ntfs ();}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user