readdir() with mount point dentry, return mount point INO
This patch fixes a minor compatibility issue w/ cygwin mount point handling in readdir(), compared to equivalent behavior of Linux and MacOS. dentry.d_ino should indicate the INO of the mount point itself, not the target volume root folder. Changed return type from readdir_check_reparse_point to uint8_t, to avoid unnecessarily being implicitly cast to and from a signed int. Renamed a related local variable "attr" to "oattr" that was eclipsing a member variable with the same name. Joe L.
This commit is contained in:
parent
35cd6863fb
commit
0a9edd73e3
@ -178,10 +178,10 @@ path_conv::isgood_inode (ino_t ino) const
|
|||||||
are directory mount points, which are treated as symlinks.
|
are directory mount points, which are treated as symlinks.
|
||||||
IO_REPARSE_TAG_SYMLINK types are always symlinks. We don't know
|
IO_REPARSE_TAG_SYMLINK types are always symlinks. We don't know
|
||||||
anything about other reparse points, so they are treated as unknown. */
|
anything about other reparse points, so they are treated as unknown. */
|
||||||
static inline int
|
static inline uint8_t
|
||||||
readdir_check_reparse_point (POBJECT_ATTRIBUTES attr)
|
readdir_check_reparse_point (POBJECT_ATTRIBUTES attr)
|
||||||
{
|
{
|
||||||
DWORD ret = DT_UNKNOWN;
|
uint8_t ret = DT_UNKNOWN;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
HANDLE reph;
|
HANDLE reph;
|
||||||
UNICODE_STRING subst;
|
UNICODE_STRING subst;
|
||||||
@ -2016,32 +2016,19 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|||||||
de->d_type = DT_REG;
|
de->d_type = DT_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for directory reparse point. These are potential volume mount
|
/* Check for directory reparse point. These may be treated as a posix
|
||||||
points which have another inode than the underlying directory. */
|
symlink, or as mount point, so need to figure out whether to return
|
||||||
|
a directory or link type. In all cases, returning the INO of the
|
||||||
|
reparse point (not of the target) matches behavior of posix systems.
|
||||||
|
*/
|
||||||
if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
|
if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
|
||||||
== (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
|
== (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
|
||||||
{
|
{
|
||||||
HANDLE reph;
|
OBJECT_ATTRIBUTES oattr;
|
||||||
OBJECT_ATTRIBUTES attr;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
|
|
||||||
InitializeObjectAttributes (&attr, fname, pc.objcaseinsensitive (),
|
InitializeObjectAttributes (&oattr, fname, pc.objcaseinsensitive (),
|
||||||
get_handle (), NULL);
|
get_handle (), NULL);
|
||||||
de->d_type = readdir_check_reparse_point (&attr);
|
de->d_type = readdir_check_reparse_point (&oattr);
|
||||||
if (de->d_type == DT_DIR)
|
|
||||||
{
|
|
||||||
/* Volume mountpoints are treated as directories. We have to fix
|
|
||||||
the inode number, otherwise we have the inode number of the
|
|
||||||
mount point, rather than the inode number of the toplevel
|
|
||||||
directory of the mounted drive. */
|
|
||||||
if (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, &attr, &io,
|
|
||||||
FILE_SHARE_VALID_FLAGS,
|
|
||||||
FILE_OPEN_FOR_BACKUP_INTENT)))
|
|
||||||
{
|
|
||||||
de->d_ino = pc.get_ino_by_handle (reph);
|
|
||||||
NtClose (reph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the
|
/* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user