* syscalls.cc (NT_TRANSACTIONAL_ERROR): Define.
(stop_transaction): Take "trans" HANDLE by reference and set it to NULL after closing it. (unlink_nt): If NtOpenFile fails due to a transactional error, stop transaction and retry NtOpenFile. Simplify check for having to call stop_transaction. (rename): If NtOpenFile fails due to a transactional error, stop transaction and retry NtOpenFile in both affected cases. Simplify check for having to call stop_transaction and add comment from unlink_nt.
This commit is contained in:
parent
c28222be54
commit
f51db32d8c
@ -1,3 +1,15 @@
|
|||||||
|
2013-12-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* syscalls.cc (NT_TRANSACTIONAL_ERROR): Define.
|
||||||
|
(stop_transaction): Take "trans" HANDLE by reference and set it to
|
||||||
|
NULL after closing it.
|
||||||
|
(unlink_nt): If NtOpenFile fails due to a transactional error, stop
|
||||||
|
transaction and retry NtOpenFile. Simplify check for having to call
|
||||||
|
stop_transaction.
|
||||||
|
(rename): If NtOpenFile fails due to a transactional error, stop
|
||||||
|
transaction and retry NtOpenFile in both affected cases. Simplify check
|
||||||
|
for having to call stop_transaction and add comment from unlink_nt.
|
||||||
|
|
||||||
2013-12-11 Corinna Vinschen <corinna@vinschen.de>
|
2013-12-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* mount.cc (fs_info::update): Fix formatting.
|
* mount.cc (fs_info::update): Fix formatting.
|
||||||
|
@ -8,3 +8,8 @@ Bug Fixes
|
|||||||
- Signals should no longer hang when they occur within a low-level
|
- Signals should no longer hang when they occur within a low-level
|
||||||
Windows DLL.
|
Windows DLL.
|
||||||
Fixes: http://cygwin.com/ml/cygwin/2013-12/threads.html#00151
|
Fixes: http://cygwin.com/ml/cygwin/2013-12/threads.html#00151
|
||||||
|
|
||||||
|
- If it turns out that transactions don't work during unlink(2) or rename(2),
|
||||||
|
despite the fact that the filesystem claims to handle them, stop transaction
|
||||||
|
and try again without.
|
||||||
|
Fixes: http://cygwin.com/ml/cygwin/2013-12/msg00119.html
|
||||||
|
@ -185,6 +185,11 @@ dup3 (int oldfd, int newfd, int flags)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Define macro to simplify checking for a transactional error code. */
|
||||||
|
#define NT_TRANSACTIONAL_ERROR(s) \
|
||||||
|
(((ULONG)(s) >= (ULONG)STATUS_TRANSACTIONAL_CONFLICT) \
|
||||||
|
&& ((ULONG)(s) <= (ULONG)STATUS_LOG_GROWTH_FAILED))
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
start_transaction (HANDLE &old_trans, HANDLE &trans)
|
start_transaction (HANDLE &old_trans, HANDLE &trans)
|
||||||
{
|
{
|
||||||
@ -204,7 +209,7 @@ start_transaction (HANDLE &old_trans, HANDLE &trans)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline NTSTATUS
|
static inline NTSTATUS
|
||||||
stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE trans)
|
stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE &trans)
|
||||||
{
|
{
|
||||||
RtlSetCurrentTransaction (old_trans);
|
RtlSetCurrentTransaction (old_trans);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
@ -212,6 +217,7 @@ stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE trans)
|
|||||||
else
|
else
|
||||||
status = NtRollbackTransaction (trans, TRUE);
|
status = NtRollbackTransaction (trans, TRUE);
|
||||||
NtClose (trans);
|
NtClose (trans);
|
||||||
|
trans = NULL;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +708,7 @@ unlink_nt (path_conv &pc)
|
|||||||
if (wincap.has_transactions ()
|
if (wincap.has_transactions ()
|
||||||
&& (pc.fs_flags () & FILE_SUPPORTS_TRANSACTIONS))
|
&& (pc.fs_flags () & FILE_SUPPORTS_TRANSACTIONS))
|
||||||
start_transaction (old_trans, trans);
|
start_transaction (old_trans, trans);
|
||||||
|
retry_open:
|
||||||
status = NtOpenFile (&fh_ro, FILE_WRITE_ATTRIBUTES, &attr, &io,
|
status = NtOpenFile (&fh_ro, FILE_WRITE_ATTRIBUTES, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, flags);
|
FILE_SHARE_VALID_FLAGS, flags);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
@ -718,8 +724,18 @@ unlink_nt (path_conv &pc)
|
|||||||
pc.init_reopen_attr (&attr, fh_ro);
|
pc.init_reopen_attr (&attr, fh_ro);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
debug_printf ("Opening %S for removing R/O failed, status = %y",
|
debug_printf ("Opening %S for removing R/O failed, status = %y",
|
||||||
pc.get_nt_native_path (), status);
|
pc.get_nt_native_path (), status);
|
||||||
|
if (NT_TRANSACTIONAL_ERROR (status) && trans)
|
||||||
|
{
|
||||||
|
/* If NtOpenFile fails due to transactional problems, stop
|
||||||
|
transaction and go ahead without. */
|
||||||
|
stop_transaction (status, old_trans, trans);
|
||||||
|
debug_printf ("Transaction failure. Retry open.");
|
||||||
|
goto retry_open;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (pc.is_lnk_symlink ())
|
if (pc.is_lnk_symlink ())
|
||||||
{
|
{
|
||||||
status = NtQueryInformationFile (fh_ro, &io, &fsi, sizeof fsi,
|
status = NtQueryInformationFile (fh_ro, &io, &fsi, sizeof fsi,
|
||||||
@ -984,11 +1000,8 @@ try_again:
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
/* Stop transaction if we started one. */
|
/* Stop transaction if we started one. */
|
||||||
if ((access & FILE_WRITE_ATTRIBUTES)
|
if (trans)
|
||||||
&& wincap.has_transactions ()
|
|
||||||
&& (pc.fs_flags () & FILE_SUPPORTS_TRANSACTIONS))
|
|
||||||
stop_transaction (status, old_trans, trans);
|
stop_transaction (status, old_trans, trans);
|
||||||
|
|
||||||
syscall_printf ("%S, return status = %y", pc.get_nt_native_path (), status);
|
syscall_printf ("%S, return status = %y", pc.get_nt_native_path (), status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -2421,6 +2434,14 @@ retry:
|
|||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (NT_TRANSACTIONAL_ERROR (status) && trans)
|
||||||
|
{
|
||||||
|
/* If NtOpenFile fails due to transactional problems, stop
|
||||||
|
transaction and go ahead without. */
|
||||||
|
stop_transaction (status, old_trans, trans);
|
||||||
|
debug_printf ("Transaction failure. Retry open.");
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2542,6 +2563,7 @@ retry:
|
|||||||
Fortunately nothing has happened yet, so the atomicity of the
|
Fortunately nothing has happened yet, so the atomicity of the
|
||||||
rename functionality is not spoiled. */
|
rename functionality is not spoiled. */
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
|
retry_reopen:
|
||||||
status = NtOpenFile (&fh, DELETE,
|
status = NtOpenFile (&fh, DELETE,
|
||||||
oldpc.get_object_attr (attr, sec_none_nih),
|
oldpc.get_object_attr (attr, sec_none_nih),
|
||||||
&io, FILE_SHARE_VALID_FLAGS,
|
&io, FILE_SHARE_VALID_FLAGS,
|
||||||
@ -2550,6 +2572,14 @@ retry:
|
|||||||
? FILE_OPEN_REPARSE_POINT : 0));
|
? FILE_OPEN_REPARSE_POINT : 0));
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
|
if (NT_TRANSACTIONAL_ERROR (status) && trans)
|
||||||
|
{
|
||||||
|
/* If NtOpenFile fails due to transactional problems, stop
|
||||||
|
transaction and go ahead without. */
|
||||||
|
stop_transaction (status, old_trans, trans);
|
||||||
|
debug_printf ("Transaction failure. Retry open.");
|
||||||
|
goto retry_reopen;
|
||||||
|
}
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2571,7 +2601,8 @@ retry:
|
|||||||
out:
|
out:
|
||||||
if (fh)
|
if (fh)
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
if (wincap.has_transactions () && trans)
|
/* Stop transaction if we started one. */
|
||||||
|
if (trans)
|
||||||
stop_transaction (status, old_trans, trans);
|
stop_transaction (status, old_trans, trans);
|
||||||
syscall_printf ("%R = rename(%s, %s)", res, oldpath, newpath);
|
syscall_printf ("%R = rename(%s, %s)", res, oldpath, newpath);
|
||||||
return res;
|
return res;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user