* 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:
parent
ab3cd88858
commit
2d355410b7
@ -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>
|
2010-09-30 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* path.cc (symlink_info::check): Remove erroneous assumption about
|
* path.cc (symlink_info::check): Remove erroneous assumption about
|
||||||
|
@ -28,7 +28,6 @@ details. */
|
|||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
#include "nfs.h"
|
|
||||||
|
|
||||||
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ details. */
|
|||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
#include "nfs.h"
|
|
||||||
#include "pwdgrp.h"
|
#include "pwdgrp.h"
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
@ -303,51 +302,51 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
|
|||||||
struct {
|
struct {
|
||||||
FILE_GET_EA_INFORMATION fgei;
|
FILE_GET_EA_INFORMATION fgei;
|
||||||
char buf[sizeof (NFS_V3_ATTR)];
|
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,
|
if (get_io_handle ())
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
fattr3 *nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
|
/* NFS stumbles over its own caching. If you write to the file,
|
||||||
+ ffei_buf.ffei.EaNameLength + 1);
|
a subsequent fstat does not return the actual size of the file,
|
||||||
buf->st_dev = nfs_attr->fsid;
|
but the size at the time the handle has been opened. Unless
|
||||||
buf->st_ino = nfs_attr->fileid;
|
access through another handle invalidates the caching within the
|
||||||
buf->st_mode = (nfs_attr->mode & 0xfff)
|
NFS client. */
|
||||||
| nfs_type_mapping[nfs_attr->type & 7];
|
if (get_access () & GENERIC_WRITE)
|
||||||
buf->st_nlink = nfs_attr->nlink;
|
FlushFileBuffers (get_io_handle ());
|
||||||
/* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
|
|
||||||
#if 0
|
fgei_buf.fgei.NextEntryOffset = 0;
|
||||||
buf->st_uid = nfs_attr->uid;
|
fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
|
||||||
buf->st_gid = nfs_attr->gid;
|
stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR);
|
||||||
#else
|
status = NtQueryEaFile (get_io_handle (), &io,
|
||||||
buf->st_uid = myself->uid;
|
&ffei_buf.ffei, sizeof ffei_buf, TRUE,
|
||||||
buf->st_gid = myself->gid;
|
&fgei_buf.fgei, sizeof fgei_buf, NULL, TRUE);
|
||||||
#endif
|
if (NT_SUCCESS (status))
|
||||||
buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
|
nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
|
||||||
nfs_attr->rdev.specdata2);
|
+ ffei_buf.ffei.EaNameLength + 1);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
debug_printf ("%p = NtQueryEaFile(%S)", status, pc.get_nt_native_path ());
|
buf->st_dev = nfs_attr->fsid;
|
||||||
return -1;
|
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
|
int __stdcall
|
||||||
|
@ -67,7 +67,6 @@
|
|||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
#include "environ.h"
|
#include "environ.h"
|
||||||
#include "nfs.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ntdll.h>
|
#include <ntdll.h>
|
||||||
#include <wchar.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)
|
if (NT_SUCCESS (status)
|
||||||
/* Check file system while we're having the file open anyway.
|
/* Check file system while we're having the file open anyway.
|
||||||
This speeds up path_conv noticably (~10%). */
|
This speeds up path_conv noticably (~10%). */
|
||||||
@ -2408,17 +2404,34 @@ restart:
|
|||||||
{
|
{
|
||||||
if (fs.is_nfs ())
|
if (fs.is_nfs ())
|
||||||
{
|
{
|
||||||
/* NFS doesn't handle FileNetworkOpenInformation when called
|
struct {
|
||||||
via NtQueryInformationFile (STATUS_INVALID_PARAMETER).
|
FILE_FULL_EA_INFORMATION ffei;
|
||||||
Since we only need FileAttributes for NFS anyway, we just
|
char buf[sizeof (NFS_V3_ATTR) + sizeof (fattr3)];
|
||||||
fetch the FileBasicInformation. */
|
} ffei_buf;
|
||||||
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
struct {
|
||||||
FileBasicInformation);
|
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))
|
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
|
else
|
||||||
{
|
{
|
||||||
|
PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
|
||||||
|
|
||||||
status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
|
status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
|
||||||
FileNetworkOpenInformation);
|
FileNetworkOpenInformation);
|
||||||
if ((status == STATUS_INVALID_PARAMETER
|
if ((status == STATUS_INVALID_PARAMETER
|
||||||
@ -2428,6 +2441,8 @@ restart:
|
|||||||
/* This occurs when accessing SMB share root dirs hosted on
|
/* This occurs when accessing SMB share root dirs hosted on
|
||||||
NT4 (STATUS_INVALID_PARAMETER), or when trying to access
|
NT4 (STATUS_INVALID_PARAMETER), or when trying to access
|
||||||
SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */
|
SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */
|
||||||
|
FILE_BASIC_INFORMATION fbi;
|
||||||
|
|
||||||
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
||||||
FileBasicInformation);
|
FileBasicInformation);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
@ -2529,6 +2544,8 @@ restart:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
|
||||||
|
|
||||||
fileattr = fdi_buf.fdi.FileAttributes;
|
fileattr = fdi_buf.fdi.FileAttributes;
|
||||||
memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi);
|
memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi);
|
||||||
/* Amazing, but true: The FILE_NETWORK_OPEN_INFORMATION
|
/* Amazing, but true: The FILE_NETWORK_OPEN_INFORMATION
|
||||||
@ -2627,7 +2644,7 @@ restart:
|
|||||||
else if (res)
|
else if (res)
|
||||||
{
|
{
|
||||||
/* A symlink is never a directory. */
|
/* A symlink is never a directory. */
|
||||||
pfnoi->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
conv_hdl.fnoi ()->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2649,7 +2666,7 @@ restart:
|
|||||||
/* If the file is on an NFS share and could be opened with extended
|
/* 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
|
attributes, check if it's a symlink. Only files can be symlinks
|
||||||
(which can be symlinks to directories). */
|
(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);
|
res = check_nfs_symlink (h);
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -12,6 +12,7 @@ details. */
|
|||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "cygheap_malloc.h"
|
#include "cygheap_malloc.h"
|
||||||
|
#include "nfs.h"
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -96,17 +97,21 @@ class path_conv_handle
|
|||||||
{
|
{
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
ACCESS_MASK acc;
|
ACCESS_MASK acc;
|
||||||
/* Identical to FILE_NETWORK_OPEN_INFORMATION. We don't want to pull in
|
union {
|
||||||
ntdll.h here, though. */
|
/* Identical to FILE_NETWORK_OPEN_INFORMATION. We don't want to pull in
|
||||||
struct {
|
ntdll.h here, though. */
|
||||||
LARGE_INTEGER CreationTime;
|
struct {
|
||||||
LARGE_INTEGER LastAccessTime;
|
LARGE_INTEGER CreationTime;
|
||||||
LARGE_INTEGER LastWriteTime;
|
LARGE_INTEGER LastAccessTime;
|
||||||
LARGE_INTEGER ChangeTime;
|
LARGE_INTEGER LastWriteTime;
|
||||||
LARGE_INTEGER AllocationSize;
|
LARGE_INTEGER ChangeTime;
|
||||||
LARGE_INTEGER EndOfFile;
|
LARGE_INTEGER AllocationSize;
|
||||||
ULONG FileAttributes;
|
LARGE_INTEGER EndOfFile;
|
||||||
} _fnoi;
|
ULONG FileAttributes;
|
||||||
|
} _fnoi;
|
||||||
|
/* For NFS. */
|
||||||
|
fattr3 _fattr3;
|
||||||
|
} attribs;
|
||||||
public:
|
public:
|
||||||
path_conv_handle () : hdl (NULL), acc (0) {}
|
path_conv_handle () : hdl (NULL), acc (0) {}
|
||||||
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
|
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
|
||||||
@ -129,7 +134,9 @@ public:
|
|||||||
inline HANDLE handle () const { return hdl; }
|
inline HANDLE handle () const { return hdl; }
|
||||||
inline ACCESS_MASK access () const { return acc; }
|
inline ACCESS_MASK access () const { return acc; }
|
||||||
inline struct _FILE_NETWORK_OPEN_INFORMATION *fnoi ()
|
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
|
class path_conv
|
||||||
@ -321,6 +328,7 @@ class path_conv
|
|||||||
HANDLE handle () const { return conv_handle.handle (); }
|
HANDLE handle () const { return conv_handle.handle (); }
|
||||||
ACCESS_MASK access () const { return conv_handle.access (); }
|
ACCESS_MASK access () const { return conv_handle.access (); }
|
||||||
struct _FILE_NETWORK_OPEN_INFORMATION *fnoi () { return conv_handle.fnoi (); }
|
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 reset_conv_handle () { conv_handle.set (NULL, 0); }
|
||||||
void close_conv_handle () { conv_handle.close (); }
|
void close_conv_handle () { conv_handle.close (); }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user