* syscalls.cc (rename): Limit retry loop in case of sharing violation

to about a second.
This commit is contained in:
Corinna Vinschen 2010-09-10 19:55:26 +00:00
parent 396561aa0b
commit f7dea7f233
2 changed files with 15 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2010-09-10 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (rename): Limit retry loop in case of sharing violation
to about a second.
2010-09-10 Corinna Vinschen <corinna@vinschen.de> 2010-09-10 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (fstatat): Call stat_worker directly from here. * syscalls.cc (fstatat): Call stat_worker directly from here.

View File

@ -2009,6 +2009,8 @@ rename (const char *oldpath, const char *newpath)
|| (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY)))) || (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY))))
start_transaction (old_trans, trans); start_transaction (old_trans, trans);
int retry_count;
retry_count = 0;
retry: retry:
/* DELETE is required to rename a file. At least one cifs FS (Tru64) needs /* DELETE is required to rename a file. At least one cifs FS (Tru64) needs
FILE_READ_ATTRIBUTE, otherwise the FileRenameInformation call fails with FILE_READ_ATTRIBUTE, otherwise the FileRenameInformation call fails with
@ -2026,7 +2028,7 @@ retry:
{ {
debug_printf ("status %p", status); debug_printf ("status %p", status);
if (status == STATUS_SHARING_VIOLATION if (status == STATUS_SHARING_VIOLATION
&& WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0) && WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
{ {
/* Typical BLODA problem. Some virus scanners check newly generated /* Typical BLODA problem. Some virus scanners check newly generated
files and while doing that disallow DELETE access. That's really files and while doing that disallow DELETE access. That's really
@ -2036,9 +2038,13 @@ retry:
scanner and the application fails to create the target file. scanner and the application fails to create the target file.
This kludge tries to work around that by yielding until the This kludge tries to work around that by yielding until the
sharing violation goes away, or a signal arrived. */ sharing violation goes away, or a signal arrived, or after
yield (); about a second, give or take. */
goto retry; if (++retry_count < 40)
{
yield ();
goto retry;
}
} }
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
goto out; goto out;