mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-03-02 13:05:42 +08:00
* mount.cc (class fs_info_cache): New class to cache filesystem
information. (fs_info::update): Check FileFsVolumeInformation against filesystem cache and use it, if filesystem is already available. Add filesystem to cache, if not. Only request FileFsObjectIdInformation if FILE_SUPPORTS_OBJECT_IDS is set in filesystem flags. * ntdll.h (struct _FILE_FS_VOLUME_INFORMATION): Add pragma pack so the structure size is matching the OS expectations. Add __dummy member used in filesystem cache.
This commit is contained in:
parent
67a9307898
commit
f65c5a0a2b
@ -1,3 +1,15 @@
|
|||||||
|
2010-09-10 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* mount.cc (class fs_info_cache): New class to cache filesystem
|
||||||
|
information.
|
||||||
|
(fs_info::update): Check FileFsVolumeInformation against filesystem
|
||||||
|
cache and use it, if filesystem is already available. Add filesystem
|
||||||
|
to cache, if not. Only request FileFsObjectIdInformation if
|
||||||
|
FILE_SUPPORTS_OBJECT_IDS is set in filesystem flags.
|
||||||
|
* ntdll.h (struct _FILE_FS_VOLUME_INFORMATION): Add pragma pack so the
|
||||||
|
structure size is matching the OS expectations. Add __dummy member
|
||||||
|
used in filesystem cache.
|
||||||
|
|
||||||
2010-09-10 Corinna Vinschen <corinna@vinschen.de>
|
2010-09-10 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* security.cc (get_file_sd): Add bool parameter justcreated. Use
|
* security.cc (get_file_sd): Add bool parameter justcreated. Use
|
||||||
|
@ -105,6 +105,64 @@ struct smb_extended_info {
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#define MAX_FS_INFO_CNT 32
|
||||||
|
class fs_info_cache
|
||||||
|
{
|
||||||
|
static muto fsi_lock;
|
||||||
|
uint32_t count;
|
||||||
|
struct {
|
||||||
|
fs_info fsi;
|
||||||
|
uint32_t hash;
|
||||||
|
} entry[MAX_FS_INFO_CNT];
|
||||||
|
|
||||||
|
uint32_t genhash (PFILE_FS_VOLUME_INFORMATION);
|
||||||
|
|
||||||
|
public:
|
||||||
|
fs_info_cache () : count (0) { fsi_lock.init ("fsi_lock"); }
|
||||||
|
fs_info *search (PFILE_FS_VOLUME_INFORMATION, uint32_t &);
|
||||||
|
void add (uint32_t, fs_info *);
|
||||||
|
};
|
||||||
|
|
||||||
|
static fs_info_cache fsi_cache;
|
||||||
|
muto NO_COPY fs_info_cache::fsi_lock;
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
fs_info_cache::genhash (PFILE_FS_VOLUME_INFORMATION pffvi)
|
||||||
|
{
|
||||||
|
uint32_t hash = 0;
|
||||||
|
const uint16_t *p = (const uint16_t *) pffvi;
|
||||||
|
const uint16_t *end = (const uint16_t *)
|
||||||
|
((const uint8_t *) p + sizeof *pffvi
|
||||||
|
+ pffvi->VolumeLabelLength - sizeof (WCHAR));
|
||||||
|
pffvi->__dummy = 0; /* This member can have random values! */
|
||||||
|
while (p < end)
|
||||||
|
hash = *p++ + (hash << 6) + (hash << 16) - hash;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_info *
|
||||||
|
fs_info_cache::search (PFILE_FS_VOLUME_INFORMATION pffvi, uint32_t &hash)
|
||||||
|
{
|
||||||
|
hash = genhash (pffvi);
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
if (entry[i].hash == hash)
|
||||||
|
return &entry[i].fsi;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fs_info_cache::add (uint32_t hashval, fs_info *new_fsi)
|
||||||
|
{
|
||||||
|
fsi_lock.acquire ();
|
||||||
|
if (count < MAX_FS_INFO_CNT)
|
||||||
|
{
|
||||||
|
entry[count].fsi = *new_fsi;
|
||||||
|
entry[count].hash = hashval;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
fsi_lock.release ();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
||||||
{
|
{
|
||||||
@ -172,11 +230,23 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sernum = 0;
|
||||||
status = NtQueryVolumeInformationFile (vol, &io, &ffvi_buf.ffvi,
|
status = NtQueryVolumeInformationFile (vol, &io, &ffvi_buf.ffvi,
|
||||||
sizeof ffvi_buf,
|
sizeof ffvi_buf,
|
||||||
FileFsVolumeInformation);
|
FileFsVolumeInformation);
|
||||||
sernum = NT_SUCCESS (status) ? ffvi_buf.ffvi.VolumeSerialNumber : 0;
|
uint32_t hash = 0;
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
fs_info *fsi = fsi_cache.search (&ffvi_buf.ffvi, hash);
|
||||||
|
if (fsi)
|
||||||
|
{
|
||||||
|
*this = *fsi;
|
||||||
|
if (!in_vol)
|
||||||
|
NtClose (vol);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sernum = ffvi_buf.ffvi.VolumeSerialNumber;
|
||||||
|
}
|
||||||
status = NtQueryVolumeInformationFile (vol, &io, &ffdi, sizeof ffdi,
|
status = NtQueryVolumeInformationFile (vol, &io, &ffdi, sizeof ffdi,
|
||||||
FileFsDeviceInformation);
|
FileFsDeviceInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
@ -253,9 +323,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||||||
#define FS_IS_WINDOWS_FAT TEST_GVI(flags (), WIN_FAT_FLAGS)
|
#define FS_IS_WINDOWS_FAT TEST_GVI(flags (), WIN_FAT_FLAGS)
|
||||||
|
|
||||||
/* This always fails on NT4. */
|
/* This always fails on NT4. */
|
||||||
status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
|
if ((flags () & FILE_SUPPORTS_OBJECT_IDS)
|
||||||
FileFsObjectIdInformation);
|
&& NT_SUCCESS (NtQueryVolumeInformationFile (vol, &io, &ffoi,
|
||||||
if (NT_SUCCESS (status))
|
sizeof ffoi,
|
||||||
|
FileFsObjectIdInformation)))
|
||||||
{
|
{
|
||||||
smb_extended_info *extended_info = (smb_extended_info *)
|
smb_extended_info *extended_info = (smb_extended_info *)
|
||||||
&ffoi.ExtendedInfo;
|
&ffoi.ExtendedInfo;
|
||||||
@ -355,6 +426,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||||||
|
|
||||||
if (!in_vol)
|
if (!in_vol)
|
||||||
NtClose (vol);
|
NtClose (vol);
|
||||||
|
fsi_cache.add (hash, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,14 +751,17 @@ typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
|
|||||||
WCHAR FileSystemName[1];
|
WCHAR FileSystemName[1];
|
||||||
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
|
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
|
||||||
|
|
||||||
|
#pragma pack(push,4)
|
||||||
typedef struct _FILE_FS_VOLUME_INFORMATION
|
typedef struct _FILE_FS_VOLUME_INFORMATION
|
||||||
{
|
{
|
||||||
LARGE_INTEGER VolumeCreationTime;
|
LARGE_INTEGER VolumeCreationTime;
|
||||||
ULONG VolumeSerialNumber;
|
ULONG VolumeSerialNumber;
|
||||||
ULONG VolumeLabelLength;
|
ULONG VolumeLabelLength;
|
||||||
BOOLEAN SupportsObjects;
|
BOOLEAN SupportsObjects;
|
||||||
|
BOOLEAN __dummy;
|
||||||
WCHAR VolumeLabel[1];
|
WCHAR VolumeLabel[1];
|
||||||
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
|
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef struct _FILE_FS_SIZE_INFORMATION
|
typedef struct _FILE_FS_SIZE_INFORMATION
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user