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.
|
||||
IO_REPARSE_TAG_SYMLINK types are always symlinks. We don't know
|
||||
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)
|
||||
{
|
||||
DWORD ret = DT_UNKNOWN;
|
||||
uint8_t ret = DT_UNKNOWN;
|
||||
IO_STATUS_BLOCK io;
|
||||
HANDLE reph;
|
||||
UNICODE_STRING subst;
|
||||
|
@ -2016,32 +2016,19 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|||
de->d_type = DT_REG;
|
||||
}
|
||||
|
||||
/* Check for directory reparse point. These are potential volume mount
|
||||
points which have another inode than the underlying directory. */
|
||||
/* Check for directory reparse point. These may be treated as a posix
|
||||
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))
|
||||
== (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))
|
||||
{
|
||||
HANDLE reph;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
OBJECT_ATTRIBUTES oattr;
|
||||
|
||||
InitializeObjectAttributes (&attr, fname, pc.objcaseinsensitive (),
|
||||
InitializeObjectAttributes (&oattr, fname, pc.objcaseinsensitive (),
|
||||
get_handle (), NULL);
|
||||
de->d_type = readdir_check_reparse_point (&attr);
|
||||
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);
|
||||
}
|
||||
}
|
||||
de->d_type = readdir_check_reparse_point (&oattr);
|
||||
}
|
||||
|
||||
/* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the
|
||||
|
|
Loading…
Reference in New Issue