I’ve got an issue with a client application written in .NET (see https://social.msdn.microsoft.com/Forums/vstudio/en-US/0927a63e-b5c0-49c5-b68b-56f0a96cd81d/directorycreatedirectory-throws-ioexception-quotfile-or-directory-with-the-same-name-already?forum=netfxbcl) against our FSD. When running multiple threads all creating the same directory structure, the app throws an exception on 1 or more threads when a directory already exists. The API for the .NET function Directory.CreateDirectory says it shouldn’t do that, and looking at the source code for the function, I’ve pretty much determined as such (again, see link for details.)
So I monitored on the Server side and can see the STATUS_OBJECT_NAME_COLLISION being returned to the System process for mr lan man server and so that makes sense. The odd thing, however, is if I point the app to a remote NTFS drive on the same server instead of a drive backed by our FSD, I can see the exact same error behavior, BUT, I can see the client ask for the attributes of the directory immediately after it. Again, looking at the source code for the function, that makes sense, it tries to determine if its a directory.
Eventually I tried disabling the SMB2 redirector cache FileInfoCacheLifetime (set to 0) and the problem has gone away. With it disabled, the client asks for the directory attributes immediately after the error and when it determines its a directory, the function succeeds.
The odd thing is that if you look at the source code of the function (https://referencesource.microsoft.com/#mscorlib/system/io/directory.cs,e3885fef9f6af9de), the only way it should return that error is really if there is a FILE and not a DIRECTORY at that same path. I’ve look at that code through and through and that’s the only code path that would produce that. So it implies that our FSD is returning that its a FILE. I’ve analyze this through hundreds of test runs and nowhere is our FSD ever returning attributes on these entries that say they are a file. So even if the redirector is caching attributes for that entry, it should be telling the client app that its a directory, right?
There is one glaring difference between NTFS and our FSD; the former supports oplocks on directories and we do not. We took the path that CDFS has and just return STATUS_INVALID_PARAMETER if its a directory. Could that be what is causing the client’s redirectory to not refresh the entry’s metadata on that directory?
Finally, can someone can explain why lanmanserver would use FSCTL_REQUEST_OPLOCK with NTFS and FSCTL_REQUEST_OPLOCK_LEVEL_2 with our FSD?