* 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.
This commit is contained in:
parent
6fb0ddfe34
commit
7ba1698ed9
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user