[newlib-cygwin] Cygwin: improve O_TMPFILE handling
Corinna Vinschen
corinna@sourceware.org
Wed Feb 14 11:55:00 GMT 2018
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=7ae73be14194ccadc9a7557be33c3940ca4667cb
commit 7ae73be14194ccadc9a7557be33c3940ca4667cb
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Wed Feb 14 12:55:24 2018 +0100
Cygwin: improve O_TMPFILE handling
Windows does not remove FILE_ATTRIBUTE_TEMPORARY by itself after a
file has been closed. It's just some attribute which can be set or
removed at will, despite its purpose.
Apparently there are tools out there which use FILE_ATTRIBUTE_TEMPORARY
accidentally or wrongly, even Microsoft's own tools are affected. In
the end, the filesystem is potentially full of files with this attribute
set.
Implement O_TMPFILE files with FILE_ATTRIBUTE_TEMPORARY and
FILE_ATTRIBUTE_HIDDEN set. This combination is pretty unlikely.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/fhandler.cc | 7 +++++--
winsup/cygwin/fhandler.h | 2 ++
winsup/cygwin/fhandler_disk_file.cc | 33 ++++++++++++++++++++++-----------
3 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 7da1c4e..086be73 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -603,11 +603,14 @@ fhandler_base::open (int flags, mode_t mode)
as with FILE_ATTRIBUTE_TEMPORARY. The latter speeds up file access,
because the OS tries to keep the file in memory as much as possible.
In conjunction with FILE_DELETE_ON_CLOSE, ideally the OS never has
- to write to the disk at all. */
+ to write to the disk at all.
+ Note that O_TMPFILE_FILE_ATTRS also sets the DOS HIDDEN attribute
+ to help telling Cygwin O_TMPFILE files apart from other files
+ accidentally setting FILE_ATTRIBUTE_TEMPORARY. */
if (flags & O_TMPFILE)
{
access |= DELETE;
- file_attributes |= FILE_ATTRIBUTE_TEMPORARY;
+ file_attributes |= O_TMPFILE_FILE_ATTRS;
options |= FILE_DELETE_ON_CLOSE;
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index a446e75..9d2b263 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -37,6 +37,8 @@ details. */
never be used in Cygwin for this function. */
#define PIPE_ADD_PID FILE_FLAG_FIRST_PIPE_INSTANCE
+#define O_TMPFILE_FILE_ATTRS (FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN)
+
extern const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table;
#define __fmode (*(user_data->fmode_ptr))
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index f079965..cb6be25 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1243,16 +1243,28 @@ fhandler_disk_file::link (const char *newpath)
__seterrno_from_nt_status (status);
return -1;
}
- else if (pc.file_attributes () & FILE_ATTRIBUTE_TEMPORARY)
- {
- /* If the original file has been opened with O_TMPFILE the file has
- FILE_ATTRIBUTE_TEMPORARY set. After a successful hardlink the
- file is not temporary anymore in the usual sense. So we remove
- FILE_ATTRIBUTE_TEMPORARY here, even if this makes the original file
- visible in directory enumeration. */
+ else if ((pc.file_attributes () & O_TMPFILE_FILE_ATTRS)
+ == O_TMPFILE_FILE_ATTRS)
+ {
+ /* An O_TMPFILE file has FILE_ATTRIBUTE_TEMPORARY and
+ FILE_ATTRIBUTE_HIDDEN set. After a successful hardlink the file is
+ not temporary anymore in the usual sense. So we remove these
+ attributes here, even if this makes the original link (temporarily)
+ visible in directory enumeration.
+
+ Note that we don't create a reopen attribute for the original
+ link but rather a normal attribute for the just created link.
+ The reason is a curious behaviour of Windows: If we remove
+ the O_TMPFILE attributes on the original link, the new link
+ will not show up in file system listings, long after the original
+ link has been closed and removed. The file and its metadata will
+ be kept in memory only as long as Windows sees fit. By opening
+ the new link, we request the attribute changes on the new link,
+ so after closing it Windows will have an increased interest to
+ write back the metadata. */
OBJECT_ATTRIBUTES attr;
status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
- pc.init_reopen_attr (attr, fh), &io,
+ newpc.get_object_attr (attr, sec_none_nih), &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
debug_printf ("Opening for removing TEMPORARY attrib failed, "
@@ -1263,8 +1275,7 @@ fhandler_disk_file::link (const char *newpath)
fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart
= fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL;
- fbi.FileAttributes = (pc.file_attributes ()
- & ~FILE_ATTRIBUTE_TEMPORARY)
+ fbi.FileAttributes = (pc.file_attributes () & ~O_TMPFILE_FILE_ATTRS)
?: FILE_ATTRIBUTE_NORMAL;
status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
FileBasicInformation);
@@ -2213,7 +2224,7 @@ go_ahead:
}
/* We don't show O_TMPFILE files in the filesystem. This is a kludge,
so we may end up removing this snippet again. */
- if (FileAttributes & FILE_ATTRIBUTE_TEMPORARY)
+ if ((FileAttributes & O_TMPFILE_FILE_ATTRS) == O_TMPFILE_FILE_ATTRS)
goto restart;
RtlInitCountedUnicodeString (&fname, FileName, FileNameLength);
d_mounts (dir)->check_mount (&fname);
More information about the Cygwin-cvs
mailing list