2

While doing performance analysis on some source code, I noticed both CreateFile and fopen to be taking an unusually long time to complete on remote files.

Digging in further with wireshark, I discovered that when either of the two functions are used to open a file for reading, the entire contents of the file (up to approximately 4MB) are being read. Let me also note that neither function returns until the SMB2 read operations are completed (which takes up approximately 99% of the elapsed call time).

Is there anyway to prevent this behavior? Can anyone explain what's going here?

.. ..

Example:

HANDLE h = ::CreateFile( "\\\\Server1\\Data0\\CRUISE_DATA.bin", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL );

From Wireshark:

SMB2 426 Create Request File: Jim\Data0\CRUISE_DATA.bin

SMB2 386 Create Response File: Jim\Data0\CRUISE_DATA.bin

SMB2 171 Read Request Len:65536 Off:0 File:Jim\Data0\ CRUISE_DATA.bin

SMB2 1434 Read Response

...

...

SMB2 171 Read Request Len:65536 Off:3735552 File: Jim\Data0\CRUISE_DATA.bin

SMB2 1434 Read Response

2 Answers2

1

It was definitely scanning for something... virus scanning actually. Once I turned off my virus scanner and repeated the test, the behavior went away. Apparently the real-time protection scans every file as it is opened within a given process. The least it could have done is updated the local cache ;)

This issue has stumped us for a while now. It figures that the day after I post the question, the answer falls in our laps. Anyway, I hope this helps someone else.

0

You could try some of the CreateFile flag options: FILE_FLAG_RANDOM_ACCESS and/or FILE_FLAG_OPEN_NO_RECALL. FILE_FLAG_NO_BUFFERING might also help but it requires sector aligned I/O.

Newer versions of Visual Studio maps R in the fopen mode string to FILE_FLAG_RANDOM_ACCESS.

Anders
  • 97,548
  • 12
  • 110
  • 164
  • It might also be worth trying `FILE_FLAG_OVERLAPPED` (but be aware that it significantly changes the I/O semantics). – Harry Johnston Jul 17 '17 at 23:16
  • Thanks for the suggestions! I tried all of these options and I still get the same behavior. Interesting to note..... First, the SMB2 packets show it reading the first 64k data block of the file, proceeded by the *last* 64k block, then jumping back to data block 2*64k and progressing through till 4MB range. Its almost as if it's scanning for something. Second, after the CreateFile call, I performed a ReadFile call for the first 1k block of data in the file. Guess what? Still throws an SMB2 read command. In other words, if it was reading into a cache, why did it go over the wire again? – James Bretz Jul 18 '17 at 17:28