Hi Corinna,
Thanks for your feedback. It is hard for me to provide the internal
implementation details of Interix. Anyway, I have discussed your concern
with the NTFS team.
One architect believes that if we are worried about performance, we
shouldn't be using transactions, not due to the implicit issue, for much
bigger issues. Rename for NTFS is atomic unless the target exists in which
case there is a very small race. He doesn't think it is worth doing a
'transacted rename' for that case. The cost is pretty high.
Another NTFS senior developer added the following comment:
"
The reason for RtlSetCurrentTransaction etc in kernel32 is not because
those developers are more capable; it is more a historic accident. I have
plenty of respect for Corrina and his work. That said, kernel32 developers
have the advantage of (in theory) knowing *exactly* what they will call;
this is very rarely true above kernel32.
I can see why there is a temptation to use RtlSetCurrentTransaction in a
posix rename function - as I mentioned, I've been tempted by it before.
The reasons that convinced me to not do this were primarily related to
cross volume renames (ie., the copy/delete path.) In those cases, there is
a 2x2 matrix of Txf support - either the source or destination may or may
not have txf support. This leads to complexity because you can start a few
transacted operations, then need to abort the transaction and fall back to
a non-transacted path to complete the operation. Urgh. The other case was
being called to perform a rename when a transaction was already active, and
using savepoints (rather than transactions) to deliver atomicity in those
cases (we don't have nested transactions.) Double-Urgh.
Looking through the cygwin code below, I don't believe this is handled
today. FileRenameInformation renames a file within the same volume; it
does not attempt to perform a copy/delete across volumes. That
functionality is handled by MoveFile*. Specifically, MoveFile() always
assumes MOVEFILE_COPY_ALLOWED; and the old versions of the code used
MoveFile() (as opposed to MoveFileEx()), which is how the cross-volume
support worked.
I believe rename() will still need to support cross-volume support; the
POSIX approach (AFAIK) was for rename() to work seamlessly across volumes,
and keep file descriptors valid across this operation. Cygwin used to
support volume mount points. What will happen if I call
rename("/home/malx/foo","/cygdrive/a/bar");?
If rename() needs to add copy/delete support, then perhaps we should wait
until after that's done before deciding how Txf can be used to make it more
atomic. It will definitely look more complex than it does today.
"
Hope this makes sense to you.
Best regards,
Jeffrey Tan
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
***@microsoft.com.
This posting is provided "AS IS" with no warranties, and confers no rights.