I make many concurrent robocopy calls to copy files from one network share to one directory. Since the files are read only, I tell robocopy to disable the read-only attribute in the target directory via / A -: R. It seems that on some many main machines (12 or more) the target directory! locks up to 16 seconds.
This problem occurs when parallel MSBuild tasks are executed, and the CopyFile task is executed in read-only files. This also happens when robocopy runs to load dependencies for building TFS in parallel with a network share. Since all these problems point to kernel32 CopyFile (or its private implementation), I suspect that the problem is related to the way Windows copies files.
This does not seem to be a common problem in the kernel, as the temporary folder lives because directory access is possible in parallel. But the user mode implementation inside kernel32.dll CopyFile seems erroneous.
Update 2 When playing below, this happens regardless of whether the file is read-only or not.
Update 3 This registry also shows the same problem in Windows 8.
Traces of the procmon stack have shown that magic happens in kernel32.dll inside PrivCopyFileExW, which seems pretty undocumented. IRP_MJ_CREATE opens there to open the directory, and a little later the directory is closed. This, apparently, is the main cause of the race condition, when many concurrent robocopy processes try to copy files to a single directory.
Here are some procmon to deduce how this problem looks.
Why does PrivCopyFileExW actually manage to lock the directory? The file system must support copying files to a single directory. I am using Windows Server 2008 R2 and some of the latest multi-core machines with RAID arrays, solid state drives, etc.
This is similar to reporting problems with CopyFile in the kernel32.dll file that have not yet been resolved. I can exclude antivirus scanners because this also happens on computers that don't have them.
Update 1
Another robocopy process seems to be trying to copy the file to the destination directory, which opens the directory
Date & Time: 20.03.2012 08:30:06 Event Class: File System Operation: CreateFile Result: SUCCESS Path: C:\temp\dest TID: 11672 Duration: 0.0000150 Desired Access: Read Data/List Directory, Write Data/Add File, Write EA, Read Attributes, Write Attributes, Delete, Synchronize Disposition: OpenIf Options: Directory, Synchronous IO Non-Alert, Open For Backup Attributes: D ShareMode: None <
Another robocopy wants to check if the file already exists and calls FindFirstFile, which leads to the opening of the directory, as well as in full use.
Date & Time: 20.03.2012 08:30:06 Event Class: File System Operation: CreateFile Result: SHARING VIOLATION Path: C:\temp\dest TID: 8280 Duration: 0.0000099 Desired Access: Read Data/List Directory, Synchronize Disposition: Open Options: Directory, Synchronous IO Non-Alert Attributes: n/a ShareMode: Read, Write, Delete <
I can reproduce this easily on Windows 7. You only need to copy read-only files from two parallel robocopy calls to the same directory in a loop and wait until this happens (about 30 seconds).
for /L %i in (1,1,1000) do robocopy /E /XO /COPY:DAT /A-:RC:\ReadOnlySource1 c:\temp\dest for /L %i in (1,1,1000) do robocopy /E /XO /COPY:DAT /A-:RC:\ReadOnlySource2 c:\temp\dest
You can only put one read-only file in the source directories to get a quick copy and many directories accessed simultaneously. Is this a known limitation of Windows to not allow access to a directory when a file is copied to it?
My uneducated opinion is that this is a mistake, and it can become quite unpleasant if you want a reliable way to share files.