* 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.
This commit is contained in:
Corinna Vinschen 2010-09-30 13:52:34 +00:00
parent ab3cd88858
commit 2d355410b7
5 changed files with 111 additions and 69 deletions

View File

@ -1,3 +1,22 @@
2010-09-30 Corinna Vinschen <corinna@vinschen.de>
* 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.
2010-09-30 Corinna Vinschen <corinna@vinschen.de>
* path.cc (symlink_info::check): Remove erroneous assumption about

View File

@ -28,7 +28,6 @@ details. */
#include "ntdll.h"
#include "cygtls.h"
#include "sigproc.h"
#include "nfs.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */

View File

@ -23,7 +23,6 @@ details. */
#include "pinfo.h"
#include "ntdll.h"
#include "tls_pbuf.h"
#include "nfs.h"
#include "pwdgrp.h"
#include <winioctl.h>
@ -303,51 +302,51 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
struct {
FILE_GET_EA_INFORMATION fgei;
char buf[sizeof (NFS_V3_ATTR)];
} fgei_buf;
} fgei_buf;
fattr3 *nfs_attr = pc.nfsattr ();
/* 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);
status = NtQueryEaFile (get_stat_handle (), &io,
&ffei_buf.ffei, sizeof ffei_buf, TRUE,
&fgei_buf.fgei, sizeof fgei_buf, NULL, TRUE);
if (NT_SUCCESS (status))
if (get_io_handle ())
{
fattr3 *nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
+ ffei_buf.ffei.EaNameLength + 1);
buf->st_dev = nfs_attr->fsid;
buf->st_ino = nfs_attr->fileid;
buf->st_mode = (nfs_attr->mode & 0xfff)
| nfs_type_mapping[nfs_attr->type & 7];
buf->st_nlink = nfs_attr->nlink;
/* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
#if 0
buf->st_uid = nfs_attr->uid;
buf->st_gid = nfs_attr->gid;
#else
buf->st_uid = myself->uid;
buf->st_gid = myself->gid;
#endif
buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
nfs_attr->rdev.specdata2);
buf->st_size = nfs_attr->size;
buf->st_blksize = PREFERRED_IO_BLKSIZE;
buf->st_blocks = nfs_attr->used / 512;
buf->st_atim = nfs_attr->atime;
buf->st_mtim = nfs_attr->mtime;
buf->st_ctim = nfs_attr->ctime;
return 0;
/* 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_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);
status = NtQueryEaFile (get_io_handle (), &io,
&ffei_buf.ffei, sizeof ffei_buf, TRUE,
&fgei_buf.fgei, sizeof fgei_buf, NULL, TRUE);
if (NT_SUCCESS (status))
nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
+ ffei_buf.ffei.EaNameLength + 1);
}
debug_printf ("%p = NtQueryEaFile(%S)", status, pc.get_nt_native_path ());
return -1;
buf->st_dev = nfs_attr->fsid;
buf->st_ino = nfs_attr->fileid;
buf->st_mode = (nfs_attr->mode & 0xfff)
| nfs_type_mapping[nfs_attr->type & 7];
buf->st_nlink = nfs_attr->nlink;
/* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
#if 0
buf->st_uid = nfs_attr->uid;
buf->st_gid = nfs_attr->gid;
#else
buf->st_uid = myself->uid;
buf->st_gid = myself->gid;
#endif
buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
nfs_attr->rdev.specdata2);
buf->st_size = nfs_attr->size;
buf->st_blksize = PREFERRED_IO_BLKSIZE;
buf->st_blocks = nfs_attr->used / 512;
buf->st_atim = nfs_attr->atime;
buf->st_mtim = nfs_attr->mtime;
buf->st_ctim = nfs_attr->ctime;
return 0;
}
int __stdcall

View File

@ -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)

View File

@ -12,6 +12,7 @@ details. */
#include "devices.h"
#include "mount.h"
#include "cygheap_malloc.h"
#include "nfs.h"
#include <sys/ioctl.h>
#include <fcntl.h>
@ -96,17 +97,21 @@ class path_conv_handle
{
HANDLE hdl;
ACCESS_MASK acc;
/* Identical to FILE_NETWORK_OPEN_INFORMATION. We don't want to pull in
ntdll.h here, though. */
struct {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
} _fnoi;
union {
/* Identical to FILE_NETWORK_OPEN_INFORMATION. We don't want to pull in
ntdll.h here, though. */
struct {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
} _fnoi;
/* For NFS. */
fattr3 _fattr3;
} attribs;
public:
path_conv_handle () : hdl (NULL), acc (0) {}
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
@ -129,7 +134,9 @@ public:
inline HANDLE handle () const { return hdl; }
inline ACCESS_MASK access () const { return acc; }
inline struct _FILE_NETWORK_OPEN_INFORMATION *fnoi ()
{ return (struct _FILE_NETWORK_OPEN_INFORMATION *) &_fnoi; }
{ return (struct _FILE_NETWORK_OPEN_INFORMATION *) &attribs._fnoi; }
inline struct fattr3 *nfsattr ()
{ return (struct fattr3 *) &attribs._fattr3; }
};
class path_conv
@ -321,6 +328,7 @@ class path_conv
HANDLE handle () const { return conv_handle.handle (); }
ACCESS_MASK access () const { return conv_handle.access (); }
struct _FILE_NETWORK_OPEN_INFORMATION *fnoi () { return conv_handle.fnoi (); }
struct fattr3 *nfsattr () { return conv_handle.nfsattr (); }
void reset_conv_handle () { conv_handle.set (NULL, 0); }
void close_conv_handle () { conv_handle.close (); }