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
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-09-21 20:07:20 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-09-21 20:07:20 +0400
commit7ba1698ed99abca171d2beb9091168e20cdd8b34 (patch)
treedac48a44f52a36f3dbeb973526857860b7138114
parent6fb0ddfe34df8360faf7bca096bdd45678d1c825 (diff)
* fhandler.cc (fhandler_base::open): Always open NFS files with
FILE_READ_EA, even when opening with O_WRONLY to allow fstat. * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Call FlushFileBuffers if file has been opened for writing. Explain why. (fhandler_base::fstat_by_handle): Renew content of pc.fnoi if called via fstat. Explain why. Fix formatting. * path.cc (symlink_info::check): Try to open file the second time with FILE_READ_EA permissions since it's needed in later calls to fhandler_base::fstat_by_nfs_ea.
-rw-r--r--winsup/cygwin/ChangeLog12
-rw-r--r--winsup/cygwin/fhandler.cc15
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc29
-rw-r--r--winsup/cygwin/path.cc7
4 files changed, 52 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b854c378b..9788adef9 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,15 @@
+2010-09-21 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::open): Always open NFS files with
+ FILE_READ_EA, even when opening with O_WRONLY to allow fstat.
+ * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Call
+ FlushFileBuffers if file has been opened for writing. Explain why.
+ (fhandler_base::fstat_by_handle): Renew content of pc.fnoi if called
+ via fstat. Explain why. Fix formatting.
+ * path.cc (symlink_info::check): Try to open file the second time with
+ FILE_READ_EA permissions since it's needed in later calls to
+ fhandler_base::fstat_by_nfs_ea.
+
2010-09-20 Christopher Faylor <me+cygwin@cgf.cx>
* include/sys/cygwin.h (PID_NOTCYGWIN): New enum.
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 1998979f7..64451f672 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -501,16 +501,19 @@ fhandler_base::open (int flags, mode_t mode)
break;
}
- if (query_open () && pc.fs_is_nfs ())
+ if (pc.fs_is_nfs ())
{
/* Make sure we can read EAs of files on an NFS share. Also make
- sure that we're going to act on the file itself, even if it'a
+ sure that we're going to act on the file itself, even if it's a
a symlink. */
access |= FILE_READ_EA;
- if (query_open () >= query_write_control)
- access |= FILE_WRITE_EA;
- plen = sizeof nfs_aol_ffei;
- p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
+ if (query_open ())
+ {
+ if (query_open () >= query_write_control)
+ access |= FILE_WRITE_EA;
+ plen = sizeof nfs_aol_ffei;
+ p = (PFILE_FULL_EA_INFORMATION) &nfs_aol_ffei;
+ }
}
if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY))
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 02376f6a5..cff345d31 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -305,6 +305,14 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
char buf[sizeof (NFS_V3_ATTR)];
} fgei_buf;
+ /* NFS stumbles over its own caching. If you write to the file,
+ a subsequent fstat does not return the actual size of the file,
+ but the size at the time the handle has been opened. Unless
+ access through another handle invalidates the caching within the
+ NFS client. */
+ if (get_io_handle () && (get_access () & GENERIC_WRITE))
+ FlushFileBuffers (get_io_handle ());
+
fgei_buf.fgei.NextEntryOffset = 0;
fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR);
@@ -356,6 +364,21 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
NTSTATUS status = 0;
IO_STATUS_BLOCK io;
+ /* If the file has been opened for other purposes than stat, we can't rely
+ on the information stored in pc.fnoi. So we overwrite them here. */
+ if (get_io_handle ())
+ {
+ PFILE_NETWORK_OPEN_INFORMATION pfnoi = pc.fnoi ();
+ status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
+ FileNetworkOpenInformation);
+ if (!NT_SUCCESS (status))
+ {
+ debug_printf ("%p = NtQueryInformationFile(%S, "
+ "FileNetworkOpenInformation)",
+ status, pc.get_nt_native_path ());
+ return -1;
+ }
+ }
if (!pc.hasgood_inode ())
fsi.NumberOfLinks = 1;
else
@@ -364,7 +387,8 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
FileStandardInformation);
if (!NT_SUCCESS (status))
{
- debug_printf ("%p = NtQueryInformationFile(%S, FileStandardInformation)",
+ debug_printf ("%p = NtQueryInformationFile(%S, "
+ "FileStandardInformation)",
status, pc.get_nt_native_path ());
return -1;
}
@@ -374,7 +398,8 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
FileInternalInformation);
if (!NT_SUCCESS (status))
{
- debug_printf ("%p = NtQueryInformationFile(%S, FileInternalInformation)",
+ debug_printf ("%p = NtQueryInformationFile(%S, "
+ "FileInternalInformation)",
status, pc.get_nt_native_path ());
return -1;
}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index d29aff028..32bb4c0a9 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2296,10 +2296,11 @@ restart:
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT,
eabuf, easize);
- if (status == STATUS_ACCESS_DENIED)
+ if (status == STATUS_ACCESS_DENIED && eabuf)
{
- status = NtCreateFile (&h, access = MIN_STAT_ACCESS, &attr, &io,
- NULL, 0, FILE_SHARE_VALID_FLAGS, FILE_OPEN,
+ status = NtCreateFile (&h, access = MIN_STAT_ACCESS | FILE_READ_EA,
+ &attr, &io, NULL, 0, FILE_SHARE_VALID_FLAGS,
+ FILE_OPEN,
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT,
eabuf, easize);