diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-09-30 13:52:34 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-09-30 13:52:34 +0000 |
commit | 2d355410b7b59710e61b45e529900f9ebbd668e8 (patch) | |
tree | 2886afae145598a4242d7d59766c171e94494f99 /winsup/cygwin/path.cc | |
parent | ab3cd8885800a6fcf60b0d503b402d55202257c6 (diff) | |
download | cygnal-2d355410b7b59710e61b45e529900f9ebbd668e8.tar.gz cygnal-2d355410b7b59710e61b45e529900f9ebbd668e8.tar.bz2 cygnal-2d355410b7b59710e61b45e529900f9ebbd668e8.zip |
* fhandler.cc: Drop including nfs.h.
* fhandler_disk_file.cc: Ditto.
(fhandler_base::fstat_by_nfs_ea): Use fattr3 from path_conv member,
unless called from fstat.
* path.cc: Drop including nfs.h.
(symlink_info::check): Rearrange definition of file info buffers.
Fetch fattr3 info for files on NFS and store in conv_hdl for later
use in fhandler_base::fstat_by_nfs_ea. Use fattr3 file type to
recognize symlink on NFS and try to fetch symlink target only for
actual symlinks.
* path.h: Include nfs.h.
(class path_conv_handle): Change file info storage to union of
FILE_NETWORK_OPEN_INFORMATION and fattr3 structures.
(path_conv_handle::fnoi): Align to aforementioned change.
(path_conv_handle::nfsattr): New method.
(path_conv::nfsattr): New method.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index c1f306efa..8c98e4dab 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -67,7 +67,6 @@ #include "cygtls.h" #include "tls_pbuf.h" #include "environ.h" -#include "nfs.h" #include <assert.h> #include <ntdll.h> #include <wchar.h> @@ -2398,9 +2397,6 @@ restart: } } - FILE_BASIC_INFORMATION fbi; - PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi (); - if (NT_SUCCESS (status) /* Check file system while we're having the file open anyway. This speeds up path_conv noticably (~10%). */ @@ -2408,17 +2404,34 @@ restart: { if (fs.is_nfs ()) { - /* NFS doesn't handle FileNetworkOpenInformation when called - via NtQueryInformationFile (STATUS_INVALID_PARAMETER). - Since we only need FileAttributes for NFS anyway, we just - fetch the FileBasicInformation. */ - status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, - FileBasicInformation); + struct { + FILE_FULL_EA_INFORMATION ffei; + char buf[sizeof (NFS_V3_ATTR) + sizeof (fattr3)]; + } ffei_buf; + struct { + FILE_GET_EA_INFORMATION fgei; + char buf[sizeof (NFS_V3_ATTR)]; + } fgei_buf; + + fgei_buf.fgei.NextEntryOffset = 0; + fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1; + stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR); + status = NtQueryEaFile (h, &io, &ffei_buf.ffei, sizeof ffei_buf, + TRUE, &fgei_buf.fgei, sizeof fgei_buf, + NULL, TRUE); if (NT_SUCCESS (status)) - fileattr = fbi.FileAttributes; + { + fattr3 *nfs_attr = (fattr3 *) + (ffei_buf.ffei.EaName + ffei_buf.ffei.EaNameLength + 1); + memcpy (conv_hdl.nfsattr (), nfs_attr, sizeof (fattr3)); + fileattr = ((nfs_attr->type & 7) == NF3DIR) + ? FILE_ATTRIBUTE_DIRECTORY : 0; + } } else { + PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi (); + status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi, FileNetworkOpenInformation); if ((status == STATUS_INVALID_PARAMETER @@ -2428,6 +2441,8 @@ restart: /* This occurs when accessing SMB share root dirs hosted on NT4 (STATUS_INVALID_PARAMETER), or when trying to access SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */ + FILE_BASIC_INFORMATION fbi; + status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi, FileBasicInformation); if (NT_SUCCESS (status)) @@ -2529,6 +2544,8 @@ restart: } else { + PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi (); + fileattr = fdi_buf.fdi.FileAttributes; memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi); /* Amazing, but true: The FILE_NETWORK_OPEN_INFORMATION @@ -2627,7 +2644,7 @@ restart: else if (res) { /* A symlink is never a directory. */ - pfnoi->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; + conv_hdl.fnoi ()->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY; break; } } @@ -2649,7 +2666,7 @@ restart: /* If the file is on an NFS share and could be opened with extended attributes, check if it's a symlink. Only files can be symlinks (which can be symlinks to directories). */ - else if (fs.is_nfs () && !no_ea && !(fileattr & FILE_ATTRIBUTE_DIRECTORY)) + else if (fs.is_nfs () && (conv_hdl.nfsattr ()->type & 7) == NF3LNK) { res = check_nfs_symlink (h); if (res) |