Discussion:
NTFS transaction using native functions in user mode
(too old to reply)
Corinna Vinschen
2008-04-25 10:48:59 UTC
Permalink
Hi,

probably I'm bad at reading documents, but I sadly can't figure out how
I do a NTFS transaction when the manipulated files are opened with
ZwCreateFile.

Ok, so I have a transaction handle. How do I tell NTFS that the
operations on the file opened with ZwCreateFile should be running
within this transaction?


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Johannes Passing
2008-04-26 07:03:30 UTC
Permalink
Have a look at how kernel32!CreateFileTransactedW is implemented - it
basically calls ntdll!RtlSetCurrentTransaction and then delegates to
kernel32!CreateFileW.

So RtlSetCurrentTransaction should be the routine you are looking for.

--Johannes
Post by Corinna Vinschen
Hi,
probably I'm bad at reading documents, but I sadly can't figure out how
I do a NTFS transaction when the manipulated files are opened with
ZwCreateFile.
Ok, so I have a transaction handle. How do I tell NTFS that the
operations on the file opened with ZwCreateFile should be running
within this transaction?
Corinna
--
Johannes Passing - http://int3.de/
Corinna Vinschen
2008-04-26 09:20:05 UTC
Permalink
Hi Johannes,
Post by Johannes Passing
Have a look at how kernel32!CreateFileTransactedW is implemented - it
basically calls ntdll!RtlSetCurrentTransaction and then delegates to
kernel32!CreateFileW.
So RtlSetCurrentTransaction should be the routine you are looking for.
I examined CreateFileTransactedW but that means I'm on undocumented
territory *again*. I hoped there's some documented approach available. I'm
wondering why the transaction functions like ZwCreateTransaction etc. are
documented, but not the RtlSetCurrentTransaction/RtlGetCurrentTransaction
required to actually use transactions from user space. Sigh.


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Pavel Lebedinsky [MSFT]
2008-04-27 07:45:27 UTC
Permalink
Post by Corinna Vinschen
I examined CreateFileTransactedW but that means I'm on undocumented
territory *again*. I hoped there's some documented approach available.
I'm
wondering why the transaction functions like ZwCreateTransaction etc. are
documented, but not the RtlSetCurrentTransaction/RtlGetCurrentTransaction
required to actually use transactions from user space. Sigh.
Some of the reasons are mentioned here:

http://www.codeproject.com/KB/vista/VistaKTM.aspx

I'm not an expert on this but I think that allowing non-transaction-aware
code to be called from within a transaction would open the door for
really subtle, hard to debug problems. For example, existing code could
depend on some transaction-like invariants (e.g, registry key X can only
exist if registry key Y also exists). A function might create Y directly,
and
if that succeeds, call into another process that would create X. Now if
that function is called as part of an implicit transaction that is
eventually
aborted, it would be possible to break the invariant, because X would
persist (since it wasn't part of the transaction) and Y wouldn't.
--
This posting is provided "AS IS" with no warranties, and confers no
rights.
Corinna Vinschen
2008-04-27 19:10:05 UTC
Permalink
Post by Pavel Lebedinsky [MSFT]
Post by Corinna Vinschen
I examined CreateFileTransactedW but that means I'm on undocumented
territory *again*. I hoped there's some documented approach available.
I'm
wondering why the transaction functions like ZwCreateTransaction etc. are
documented, but not the RtlSetCurrentTransaction/RtlGetCurrentTransaction
required to actually use transactions from user space. Sigh.
http://www.codeproject.com/KB/vista/VistaKTM.aspx
I'm not an expert on this but I think that allowing non-transaction-aware
code to be called from within a transaction would open the door for
really subtle, hard to debug problems. For example, existing code could
depend on some transaction-like invariants (e.g, registry key X can only
exist if registry key Y also exists). A function might create Y directly,
and
if that succeeds, call into another process that would create X. Now if
that function is called as part of an implicit transaction that is
eventually
aborted, it would be possible to break the invariant, because X would
persist (since it wasn't part of the transaction) and Y wouldn't.
Well, sure, I can understand the explicit approach and how it helps to
keep people from doing the wrong thing by encapsulating. But why does
that also imply to remove the more flexible implicit approach from the
coder's eyes? Explicit functions cover *most* cases, but only the
implicit approach allows to implement *all* cases. Wouldn't it be better
to allow programmers to understand the concept better by documenting how
it's used under the Win32 hood and also to allow to use it for the
cases not covered by the explicit approach?

For instance, one of my problems is to implement the POSIX function
rename(2). I did that already but there's a problem. If the target
file exists, it gets replaced with the renamed file atomically. This is
also supposed to work for (empty) directories. Plus a couple of border
conditions. Apart from the fact that I'm using native functions to
implement this as POSIXy as possible, I don't see how I could implement
an atomic rename with explicit Win32 TxF functions, if the target is an
existing directory. I can't do that atomically on pre-Vista anyway, but
TxF allows me to do that at least starting with Vista... using
RtlGetCurrentTransaction/ RtlSetCurrentTransaction.


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Corinna Vinschen
2008-04-27 19:25:53 UTC
Permalink
Post by Corinna Vinschen
I can't do that atomically on pre-Vista anyway, but
TxF allows me to do that at least starting with Vista... using
RtlGetCurrentTransaction/ RtlSetCurrentTransaction.
Two minutes after I sent the posting I realized how this is a bad
argument. Of course it's possible to do that with Win32 TxF functions,
it would just be very different and probably visibly slower than the
current code.


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-04-28 06:17:18 UTC
Permalink
Hi Corinna,

Do you still need any help on this issue? If I did not misunderstand you,
your current concern is how to implement NTFS transaction pre-Vista since
there are no TxF functions.

As I know, there are no user-mode support for this before Vista. I will
consult the File System team to confirm this. I will get back to you ASAP,
thanks.

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.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Corinna Vinschen
2008-04-28 08:20:16 UTC
Permalink
Hi Jeffrey,
Post by Jeffrey Tan[MSFT]
Hi Corinna,
Do you still need any help on this issue? If I did not misunderstand you,
your current concern is how to implement NTFS transaction pre-Vista since
there are no TxF functions.
no, you got that wrong. I know that transactional NTFS is only available
with Vista/Longhorn. As I pointed out, functions to maintain a transaction
in conjunction with native NT functions are available and documented.

What's not documented are the functions to *use* transactions in
conjunction with native NT functions, namely RtlGetCurrentTransaction
and RtlSetCurrentTransaction. I'd like to ask if there's a chance to
add these functions to the official documentation. Otherwise, projects
using native NT functions to access files are somewhat stuck in the
undocumented realm again.


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-04-28 09:13:13 UTC
Permalink
Hi Corinna,

Thank you for correcting me and feedback your key concern.

I do not think I can help you to ask the NTFS team to mark these APIs as
officially documented. Anyway, I will try my best to obtain some
information from them. Thanks for your understanding.

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.
Jeffrey Tan[MSFT]
2008-04-29 02:17:42 UTC
Permalink
Hi Corinna,

Sorry for letting you wait.

Our NTFS team confirmed that reasons for not documenting these APIs are the
same as the ones mentioned by "Pavel Lebedinsky [MSFT]". We don't want to
expose the "implicit" model as it is error-prone. It looks like you can use
the explicit Win32 APIs in this case but the key concern is that it'll be
"slower". Can you help to explain this concern? Do you perform performance
profiling and get this conclusion? Our NTFS team is open to hear your
feedback.

Thanks.

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.
Corinna Vinschen
2008-04-29 11:30:47 UTC
Permalink
Hi Jeffrey,
Post by Jeffrey Tan[MSFT]
Hi Corinna,
Sorry for letting you wait.
Our NTFS team confirmed that reasons for not documenting these APIs are the
same as the ones mentioned by "Pavel Lebedinsky [MSFT]". We don't want to
expose the "implicit" model as it is error-prone.
Which kind of implies that the kernel32 programmers, who have to use the
implicit model anyway, are more capable than other programmers to
understand the implict transaction model and to use it correctly. I
don't understand this approach. If a programmer is not careful in using
*anything*, it's all her own fault. With the same reasoning you could
avoid documenting DeleteFile, since using it on the wrong files is
error-prone.
Post by Jeffrey Tan[MSFT]
It looks like you can use
the explicit Win32 APIs in this case but the key concern is that it'll be
"slower". Can you help to explain this concern? Do you perform performance
profiling and get this conclusion? Our NTFS team is open to hear your
feedback.
I don't have figures, sorry. It's not all about speed, it's also the
fact that, by not documenting these functions, you're excluding code
which is streamlined to work with OBJECT_ATTRIBUTES and the matching
native NT functions from using transactions. This is for instance the
case for the latest Cygwin code. If you want to see how POSIX rename(2)
is implemented, see
http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/syscalls.cc?rev=1.490&content-type=text/x-cvsweb-markup&cvsroot=src
starting at line 1464.

This code works fine on all platforms since NT4. It just lacks the
atomicity of the POSIX specs in certain circumstances. Using
Rtl[GS]etCurrentTransaction, rename(2) (*) could stay as is, just
with an additional thin transaction layer when running on Vista or
later. Not having available these functions means, either never to be
able to use TxF transactions, or to implement two entirely separate code
paths, one for pre-Vista, one for Vista and later. I guess you will
understand that I'm rather leaning towards reusing the same code.

Along these lines I'm also curious how Interix programmers are supposed
to implement atomic functionality, given that they don't use Win32
functions at all...


Corinna


(*) unlink(2) is another candidate, same source file as above, starting
at line 512.
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-04-30 08:18:56 UTC
Permalink
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.
Corinna Vinschen
2008-04-30 09:56:20 UTC
Permalink
Hi Jeffrey,

first of all, thanks for the detailed reply.
Post by Jeffrey Tan[MSFT]
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.
Ok, that's an important point. If the transaction cost is really that
high, it might not be worth using it in terms of performance.
Post by Jeffrey Tan[MSFT]
[...]
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
[...]
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");?
This is fortunately not an issue. The POSIX rename operation does not
require cross-volume operations and historically only few implementations
really supported it. Linux, for instance, doesn't. The typical return
value is EXDEV, "Invalid cross-device link". See
http://www.opengroup.org/onlinepubs/009695399/functions/rename.html
Coreutils mv(1) does cross-device moves by copying the file(s) and
removing on the source end afterwards.
Post by Jeffrey Tan[MSFT]
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.
A lot, many thanks to all of you. I do understand the implications.

However, there's still this one point left, which I'm wondering should
be packed into a transaction if possible. What still bugs me in
Cygwin's rename implementation are the calls to unlink in two cases:

- The file to rename is a directory and the target is an existing
empty directory.

- The target file has the permissions set so that an admin can't
replace it atomically with FileRenameInformation.

In both cases an unlink operation is done, *then* a rename. If the
rename worked, all is fine. If not, I have an inconsistent state:

- The source is not renamed, but the previously existing target has been
deleted.

Of course I could avoid that problem by *not* unlinking the file,
but instead by just moving it to the recycler (like unlink_nt already
does in case of files in use) and to move it back if the rename failed,
which I'll certainly do at one point.

- But worse, in the time between the unlink and the rename, another process
could create a file in the targets place, thus having a failed rename
and having an unexpected existing target. Now trying to move the
original target back to its original place fails, too.

That's the situation which I was thinking deserves a bit of transaction,
along these lines:

Do I have to unlink for one reason or another?
Yes -> Start transaction
unlink
rename
Did I start a transaction?
Yes -> Did the rename work?
No -> Rollback
Yes -> Commit

The two big advantages of this approach would be that the transaction
would only be started if absolutely necessary and that the unlink/rename
operation would be atomic from the outside perspective. What do you
say? Do I miss something?


Thanks,
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-05-02 03:15:27 UTC
Permalink
Hi Corinna,

Thanks for your feedback.

I assume the user you are running is the Admin account. We can think of
your problem in two ways:
1. The NTFS ACL permission issue
2. The read-only bit is set for the target.

For #1, you can acquire SE_RESTORE_PRIVILEGE first to handle the
permissions issue, since you are running as admin you can acquire it.
That's a better way of implementing the semantic than rolling back a
transaction.
For #2, it occurs before the ACL checking of #1, so it can be a problem
even we have SE_RESTORE_PRIVILEGE. Yes it is odd behavior in NTFS indeed to
not let restore access through for read-only attribute , but it's
presumably there for DOS attribute compatibility reasons. So you can
simply fail in the read-only attribute case. If this is the problem, you
can simply clear the read-only bit and retry it again with
SE_RESTORE_PRIVILEGE.

Hope this helps.

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.
Corinna Vinschen
2008-05-02 19:29:58 UTC
Permalink
Hi Jeffrey,
Post by Jeffrey Tan[MSFT]
Hi Corinna,
Thanks for your feedback.
I assume the user you are running is the Admin account. We can think of
?!? Sorry, but this issue is about a generic POSIX rename implementation.
It has nothing to do with a specific account, in is supposed to run under
any account.
Post by Jeffrey Tan[MSFT]
1. The NTFS ACL permission issue
2. The read-only bit is set for the target.
For #1, you can acquire SE_RESTORE_PRIVILEGE first to handle the
permissions issue, since you are running as admin you can acquire it.
That's a better way of implementing the semantic than rolling back a
transaction.
*Iff* it's runing under an admin account, it already has the restore
priviledge enabled. However, that doesn't help non-admin users.
Post by Jeffrey Tan[MSFT]
For #2, it occurs before the ACL checking of #1, so it can be a problem
even we have SE_RESTORE_PRIVILEGE. Yes it is odd behavior in NTFS indeed to
not let restore access through for read-only attribute , but it's
presumably there for DOS attribute compatibility reasons. So you can
simply fail in the read-only attribute case. If this is the problem, you
can simply clear the read-only bit and retry it again with
SE_RESTORE_PRIVILEGE.
Hope this helps.
I don't know yet. Somehow I'm missing the context.


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-05-05 02:35:58 UTC
Permalink
Hi Corinna,

Thanks for your feedback.

We assume we are talking about the Admin account permission because of this
statement from your last reply:
"- The file to rename is a directory and the target is an existing empty
directory.
- The target file has the permissions set so that an admin can't replace
it atomically with FileRenameInformation."

By discussing with NTFS team, we have some points:
1. Should you be using Txf? This is a tradeoff between POSIX compliance,
perf, complexity, etc. We don't believe it's a good idea, but ultimately,
it's your decision.
2. If you really wants to use Txf, is it feasible for you to use Win32?
This is not only supported, but will save a lot of hacky grief (eg.
Copy/delete cases.)

Sorry, this is the information I can get now. Since we do not have official
channel to feedback or influence the design/choice of OS team, I think
you'd better contact Microsoft CSS if you have strong concern over the
current design.

Thanks for your understanding.

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.
Corinna Vinschen
2008-05-07 12:04:56 UTC
Permalink
Hi Jeffrey,
Post by Corinna Vinschen
Post by Jeffrey Tan[MSFT]
Hi Corinna,
Thanks for your feedback.
I assume the user you are running is the Admin account. We can think of
?!? Sorry, but this issue is about a generic POSIX rename implementation.
It has nothing to do with a specific account, in is supposed to run under
any account.
Post by Jeffrey Tan[MSFT]
1. The NTFS ACL permission issue
2. The read-only bit is set for the target.
For #1, you can acquire SE_RESTORE_PRIVILEGE first to handle the
permissions issue, since you are running as admin you can acquire it.
That's a better way of implementing the semantic than rolling back a
transaction.
*Iff* it's runing under an admin account, it already has the restore
priviledge enabled. However, that doesn't help non-admin users.
Post by Jeffrey Tan[MSFT]
For #2, it occurs before the ACL checking of #1, so it can be a problem
even we have SE_RESTORE_PRIVILEGE. Yes it is odd behavior in NTFS indeed to
not let restore access through for read-only attribute , but it's
presumably there for DOS attribute compatibility reasons. So you can
simply fail in the read-only attribute case. If this is the problem, you
can simply clear the read-only bit and retry it again with
SE_RESTORE_PRIVILEGE.
Hope this helps.
I don't know yet. Somehow I'm missing the context.
sorry for the crude response, I was on vacation when I replied and I was
missing a few bits.

I'm still not quite sure if I understand you right. The problem I was
referring to when I mentioned the admin account is this:

Usually, if the destination file of a rename operation exists, it gets
deleted and replaced by the renamed source file. However, this requires
that the account has delete permission on the destination file. If the
permissions don't allow deleting the destination, the rename operation
fails with an "access denied".

And here's the problem: Even if the active account has backup/restore
rights, and even if these rights are enabled in the user token, and even
though the handle to the source file of the rename operation is opened
with FILE_OPEN_FOR_BACKUP_INTENT, this flag don't apply to the
*destination* of the rename operation, apparently. As a result, a
privileged user can't rename a file to an existing file, if the ACL of
the existing file doesn't allow the privileged user to delete it.

That's the case I'm trying to solve by explicit deleting the existing
destination file (since the handle used for that can be opened with
FILE_OPEN_FOR_BACKUP_INTENT), and then to repeat the rename.

And that's why I don't see how your above reply might help. The
SE_RESTORE_PRIVILEGE is already active for the privileged user, but it
doesn't help to avoid that unfortunate delete operation.


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-05-08 10:00:30 UTC
Permalink
Hi Corinna,

Thank you for the further explanation.

Yes, I see your point now. I will clarify this to the NTFS team, I hope
they can provide further comment. Thanks.

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.
Jeffrey Tan[MSFT]
2008-05-09 03:14:42 UTC
Permalink
Hi Corinna,

Sorry for letting you wait.

Oh, based on the feedback from NTFS team, they believe this is something
that needs to be fixed in our FS, i.e. the restore privilege not applying
to the target file path of a rename. They will file that as a request to
the NTFS(allow the restore privilege to apply to the target as well).
That's for future of course.

Currently, the workaround may be using the full-fledged transaction in a
simple rename of one file to another.

Hope it helps.

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.
Corinna Vinschen
2008-05-09 11:24:01 UTC
Permalink
Hi Jeffrey,
Post by Jeffrey Tan[MSFT]
Hi Corinna,
Sorry for letting you wait.
Oh, based on the feedback from NTFS team, they believe this is something
that needs to be fixed in our FS, i.e. the restore privilege not applying
to the target file path of a rename. They will file that as a request to
the NTFS(allow the restore privilege to apply to the target as well).
That's for future of course.
Very nice. I really didn't expect that this behaviour is treated
as a bug, but it was certainly weird when I stumbled over it. I'm
glad that this will be changed at one point.
Post by Jeffrey Tan[MSFT]
Currently, the workaround may be using the full-fledged transaction in a
simple rename of one file to another.
Cool, so my idea how to use TxF transactions for this special case
wasn't that wrong. Of course, the RtlGetCurrentTransaction/
RtlSetCurrentTransaction functions I'd need for that are still
undocumented. I guess I just have to be brave and use them anyway ;-)
Post by Jeffrey Tan[MSFT]
Hope it helps.
It does. Thanks very much for your help!


Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Jeffrey Tan[MSFT]
2008-05-10 08:00:52 UTC
Permalink
Hi Corinna,

You are welcome. I also learned a lot during discussion with you :-).

If you need any further help, please feel free to post, thanks.

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.
Corinna Vinschen
2008-05-15 18:04:49 UTC
Permalink
Post by Corinna Vinschen
Post by Jeffrey Tan[MSFT]
[...]
Currently, the workaround may be using the full-fledged transaction in a
simple rename of one file to another.
Cool, so my idea how to use TxF transactions for this special case
wasn't that wrong. Of course, the RtlGetCurrentTransaction/
RtlSetCurrentTransaction functions I'd need for that are still
undocumented. I guess I just have to be brave and use them anyway ;-)
Done.

For the curious, the source code of the latest Cygwin rename(2) can be
found here:

http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/syscalls.cc?rev=1.492&content-type=text/x-cvsweb-markup&cvsroot=src

Starting at line 1465 is the function to start a transaction, the next
one is to end the transaction with commit or rollback depending on the
last status code. The rename function starts right after that at line
1495.

I tried to keep transactions as slim as possible. Only three special
cases are handled using transactions if the underlying filesystems
supports them:

- The destination file is an existing directory.
- The destination file has the R/O DOS attribute set.
- The destination file exists and does not grant the user DELETE access.

Feel free to comment and/or criticise.


Have fun,
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
Loading...