Calling ZwWriteFile/ZwReadFile from multiple threads?

I was hoping my question was easy enough to find the answer in the WDK
docs or on the web, but after searching for a couple of hours, I didn’t
come across anything reliable. Here is my last hope to find it out :slight_smile:

A driver creates a file (with ZwCreateFile, specifying
FILE_SYNCHRONOUS_IO_NONALERT in the CreateOptions), and also creates
several threads reading and writing to/from the file (with
ZwWriteFile/ZwReadFile).

The question is: does the driver need to synchronize access to the file
handle, or do ZwWriteFile/ZwReadFile synchronize such access internally?

Does the answer depend on the CreateOptions such as FILE_WRITE_THROUGH
and FILE_NO_INTERMEDIATE_BUFFERING?

Thank you for the advice.

A.

That depends on what you’re trying to do, really. This is a question specific to your usage at the end of the day. You can’t corrupt the I/O manager’s internal structures by doing this, but if you aren’t careful, you can screw up the contents of your file.

If you are always supplying an explicit file offset to ZwWriteFile/ZwReadFile, and you are handling any coherency issues with respect to multiple inflight writes to the contents of the file itself, you may not need to synchronize access. Similarly, if you opened the file in append mode and each file write is an independent ‘packet’, you will get atomic append behavior (two inflight writes are guaranteed not to be interleaved).

In other situations, if you are relying on the I/O manager’s implicit file offset for ZwWriteFile/ZwReadFile, you need to be careful not to corrupt your file due to the file offset being unexpectedly set by multiple read or write operations. For example, if the data that you write to the file is not specified as a single atomic unit in a call to ZwWriteFile but is interspersed across several calls, it might not be safe to assume that the implicit file offset moves sequentially forward in the face of multiple threads working on the same file handle simultaneously.

See the documentation for ZwWriteFile and the ByteOffset parameters for some further discussion.

  • S

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Andrei Belogortseff
Sent: Sunday, September 12, 2010 10:49 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Calling ZwWriteFile/ZwReadFile from multiple threads?

I was hoping my question was easy enough to find the answer in the WDK docs or on the web, but after searching for a couple of hours, I didn’t come across anything reliable. Here is my last hope to find it out :slight_smile:

A driver creates a file (with ZwCreateFile, specifying FILE_SYNCHRONOUS_IO_NONALERT in the CreateOptions), and also creates several threads reading and writing to/from the file (with ZwWriteFile/ZwReadFile).

The question is: does the driver need to synchronize access to the file handle, or do ZwWriteFile/ZwReadFile synchronize such access internally?

Does the answer depend on the CreateOptions such as FILE_WRITE_THROUGH and FILE_NO_INTERMEDIATE_BUFFERING?

Thank you for the advice.

A.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Skywing, thank you for your reply:

You can’t corrupt the I/O manager’s internal structures by doing this,

That’s comforting to know :slight_smile:

If you are always supplying an explicit file offset to ZwWriteFile/ZwReadFile,

Yes, I am.

and you are handling any coherency issues with respect to multiple inflight writes to the contents of the file itself, you may not need to synchronize
access.

OK, so if I understand you correctly, as long as the threads are
reading/writing to the regions that do not overlap, IO manager should
handle that correctly? That is, it’s OK for a thread to call ZwWriteFile
while another thread is waiting for the previous call to return, as long
as the regions they write to don’t overlap?

OTOH, if there is a possibility for two threads to write to (or read
from) regions that overlap, I should synchronize access to the file handle.

Now that someone explained it to me, it really seems obvious :slight_smile:

Thanks!
A.

> I was hoping my question was easy enough to find the answer in the WDK docs or on the web,

Actually, I think the answer to your question is so plainly obvious that it does not get into anyone’s head to document it…

There is just no need to synchronize an access to file handle per se ( unless your code is stupid enough to allow thread X to close a handle while thread Y still uses it, of course). What has to be synchronized is an access to shared resources that result from operations on file handle(for example, ensuring that two concurrent writers don’t render file data inconsistent), and the only one who can do it is underlying FSD - after all, you are just a client so that, as far as FSD is concerned, you are in exactly the same position as UM code that calls ReadFile() and WriteFile()…

Anton Bassov

I think it’s a perfectly reasonable question. Biting people’s head off for asking reasonable questions doesn’t really yield anything productive in my experience.

  • S

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Sunday, September 12, 2010 3:16 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Calling ZwWriteFile/ZwReadFile from multiple threads?

I was hoping my question was easy enough to find the answer in the WDK docs or on the web,

Actually, I think the answer to your question is so plainly obvious that it does not get into anyone’s head to document it…

There is just no need to synchronize an access to file handle per se ( unless your code is stupid enough to allow thread X to close a handle while thread Y still uses it, of course). What has to be synchronized is an access to shared resources that result from operations on file handle(for example, ensuring that two concurrent writers don’t render file data inconsistent), and the only one who can do it is underlying FSD - after all, you are just a client so that, as far as FSD is concerned, you are in exactly the same position as UM code that calls ReadFile() and WriteFile()…

Anton Bassov


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Yes, if you have multiple threads writing to the same byte range in the file at the same time, you’re liable to see a mess as far as the file contents go. (Merely putting a synchronization mechanism around the writes doesn’t necessarily solve the problem – depending on the situation – if you need a specific ordering of which write should ‘win’, of course. You’ll have to examine what you’re doing and decide how best to solve that.)

  • S

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Andrei Belogortseff
Sent: Sunday, September 12, 2010 2:53 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Calling ZwWriteFile/ZwReadFile from multiple threads?

Skywing, thank you for your reply:

You can’t corrupt the I/O manager’s internal structures by doing this,

That’s comforting to know :slight_smile:

If you are always supplying an explicit file offset to
ZwWriteFile/ZwReadFile,

Yes, I am.

and you are handling any coherency issues with respect to multiple
inflight writes to the contents of the file itself, you may not need
to synchronize
access.

OK, so if I understand you correctly, as long as the threads are reading/writing to the regions that do not overlap, IO manager should handle that correctly? That is, it’s OK for a thread to call ZwWriteFile while another thread is waiting for the previous call to return, as long as the regions they write to don’t overlap?

OTOH, if there is a possibility for two threads to write to (or read
from) regions that overlap, I should synchronize access to the file handle.

Now that someone explained it to me, it really seems obvious :slight_smile:

Thanks!
A.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

> I think it’s a perfectly reasonable question. Biting people’s head off for asking reasonable

questions doesn’t really yield anything productive in my experience. - S

Relax, Ken - no one is saying that this question is “unreasonable”, let alone “biting off someone’s head”…

Yes, if you have multiple threads writing to the same byte range in the file at the same time, you’re
liable to see a mess as far as the file contents go.

Well, as long as FSD maintains locking scheme properly there will be no “mess” as far as file contents are concerned. The only thing that one cannot foresee is the order in which these writes will actually take place, but file contents will remain consistent - after all, this is what disk file’s main resource is for. You can check FastFat sample to see how this kind of thing normally gets handled.

OTOH, if the OP wants to handle separate write operations atomically without anyone getting in between two(or more) operation he, indeed, needs to maintain his own synch scheme

Anton Bassov

> handle, or do ZwWriteFile/ZwReadFile synchronize such access internally?

Will synchronize internally.

Does the answer depend on the CreateOptions such as FILE_WRITE_THROUGH
and FILE_NO_INTERMEDIATE_BUFFERING?

No, only about FILE_SYNCHRONOUS_IO_xxx


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>In other situations, if you are relying on the I/O manager’s implicit file offset for

ZwWriteFile/ZwReadFile, you need to be careful not to corrupt your file due to the file offset being
unexpectedly set by multiple read or write operations.

IO manager synchronizes itself if FILE_SYNCHRONOUS_IO_xxx was provided in file creation.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com