This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Error accessing mapped drive >2TB?


In this thread there appears to be a small amount of misunderstanding of
what a reparse point is and how it should be used.

A reparse point can be thought of as a special form of extended
attribute on a file system object (directory or file) that can stored a
single {tag-value, opaque-data} pair.  In general, applications are not
expected to understand the meaning of the opaque-data nor should they
need to know what all of the registered tag-values are.

The reparse data is meant for the file system to interpret.  Some of the
opaque data structures necessary to interpret tag-values registered for
NTFS are included in the Windows DDK ntifs.h header.   For example, the
structures for the IO_REPARSE_TAG_SYMLINK (0xA000000CL) tag and
IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) tag are included in the struct
_REPARSE_DATA_BUFFER.  But there are nearly a dozen other Microsoft
registered tag values and dozens on non-Microsoft registered tag values
for which the data structures are not published.

The high bits of the tag-value convey information.  There is a Microsoft
bit (0x80000000L) and a Surrogate bit (0x20000000).  If the Surrogate
bit is set in the tag value then the directory entry is a placeholder
for another object.  Examples, a junction has the surrogate bit set to
indicate that the target of the junction is the root directory of
another file system.   A symlink has the surrogate bit set to indicate
that the target is a different file or directory that might or might not
be in a different file system.

In this thread a statement was made that the Explorer Shell does not pay
attention to reparse points.  Actually, the Explorer Shell maintains a
cache of all objects and in particular where there reparse points are.
Each surrogate reparse point is a potential bridge to a new file system.
 That means that volume information queries must be evaluated on the
target side of the reparse point.   There was a long standing bug in
this caching that has only been fixed in Windows 10.

The CreateFile() API when applied to a reparse point will by default
allocate a handle to the reparse point target.  In order to obtain a
handle to the object on which the reparse point attribute is set the
FILE_FLAG_OPEN_REPARSE_POINT flag must be set.

The GetFileAttributes() and GetFileAttributesEx() API calls set the
FILE_FLAG_OPEN_REPARSE_POINT flag which is why GetFileAttributesEx()
returns the size of the reparse point data and not the size of the
target object.  This is a point of confusion especially when working
with NTFS Symlinks because .NET and Java are unaware of Symlinks and use
the wrong size when parse the target data stream.

Lets discuss what is going on in this particular case.   Apple
constructs their file namespace as the machine name representing a
virtual directory containing mount points to partitions and end user
folders.

Apple's SMB security requires that an authenticated connection be
established before viewing the available shares.   I have created a
drive letter mapping of R: to one of the partitions.

For example:

]net view \\172.16.16.xx
Shared resources at \\172.16.16.xx


Share name                        Type  Used as  Comment

-------------------------------------------------------------------------------
BOOTCAMP                          Disk
jaltman                           Disk
Jeffrey Altman's Public Folder    Disk
Macintosh HD                      Disk  R:
The command completed successfully.

Apple's SMB file namespace (as is also true for the /afs file namespace)
permits the crossing of mount points without the use of a DFS referral
to a share representing the root directory of the target.  As a result
the Apple SMB server does expose the existence of the mount point via
the use of the RP file attribute.

]getfileattrs.exe r:\
Attribute: 0x410
        Directory
        Reparse Point

]getfileattrsex.exe  r:\
Attribute: 0x410
        Directory
        Reparse Point
Size:      0x0:0

Note that the size of the reparse data is zero.  There is no reparse
data to read.  This is a UNIX mount point not an NTFS junction.

]getfileinfobyhandle.exe r:\
Attribute: 0x410
        Directory
        Reparse Point
ReparseTag: 0xa0000003 Microsoft Surrogate
Size:      0x0:0
EOF:       0x0:0
Links:     1
Delete?    no
Directory? yes

Apple should have registered with Microsoft their own reparse point tag.
 Instead they broke the rules and used Microsoft's
IO_REPARSE_TAG_MOUNT_POINT which can lead to confusion except for the
fact that the SMB server is clearly indicating that there is no reparse
data to read by setting the size to 0.  The error status
STATUS_NOT_A_REPARSE_POINT (0xC0000275L) is what is generated when there
is no reparse data to read.

]getvolumeinfobyhandle.exe r:\
File System: NTFS
Volume Name: Macintosh HD
Serial: 0
Max Component Length: 255
System Flags: 0x40086
        Case Preservation
        Named Streams
        Supports Reparse Points
        Unicode on Disk

Apple also broke the rules by reusing the IO_REPARSE_TAG_SYMLINK tag
since they do not expose the reparse data for symlinks.

]dir r:\

 Directory of  R:\*

10/23/2015   9:21    <JUNCTION>    . [R:\.]
10/23/2015   9:21    <JUNCTION>    .. [R:\..]
10/01/2015  18:56    <JUNCTION>    afs [R:\afs]
10/22/2015  18:53         <DIR>    Applications
 7/21/2011  22:15         <DIR>    Incompatible Software
10/22/2015  14:04         <DIR>    Library
10/22/2015  14:06         <DIR>    System
 9/30/2015   8:33         <DIR>    Users
 1/24/2011  23:27     <SYMLINK>    User Guides And Information
[\Library\Documentation\User Guides and Information.localized]
                 0 bytes in 1 file and 8 dirs
    60,172,144,640 bytes free


]getfileinfobyhandle.exe  "r:\User Guides And Information"
Attribute: 0x420
        Archive
        Reparse Point
ReparseTag: 0xa000000c Microsoft Surrogate
Size:      0x0:0
EOF:       0x0:0
Links:     1
Delete?    no
Directory? no


You might also not that Apple does not expose volume serial numbers.  So
the serial number on either side of a mount point will always be zero.

]getvolumeinfobyhandle.exe r:\afs\
File System: NTFS
Volume Name: Macintosh HD
Serial: 0
Max Component Length: 255
System Flags: 0x40086
        Case Preservation
        Named Streams
        Supports Reparse Points
        Unicode on Disk

Therefore, applications cannot rely on the serial numbers to distinguish
between devices.  Instead, the applications must do as the Explorer
Shell does and track the locations of the RP attributes in paths as they
are encountered.

Remember that there is no requirement that SMB servers expose reparse
points at all nor is there any requirement that they expose volume
information.

While Apple's design choices do not fit with the expectations of Cygwin
they are not necessarily wrong.

I hope this e-mail is helpful.

Jeffrey Altman





Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]