EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Split transactions to avoid deadlock?

Also by EldoS: SecureBlackbox
200+ components and classes for digital security, signing, encryption and secure networking.
Posted: 10/05/2012 12:06:10
by Rich Van Gaasbeck (Standard support level)
Joined: 12/07/2010
Posts: 11

In the documentation it says:
The implementor of callback handlers should be aware of the following:

the callback handler procedure must avoid using any file operations in buffered mode (both explicit and implicit). All files, access to which is done from callbacks, should be opened with FILE_FLAG_NO_BUFFERING flag.
no APC (asynchronous procedure calls) should be performed.
Failure to follow the above restrictions will cause the system-wide dead-lock.
We suggest that the application performs all operations asynchronously, i.e. maintains it's own cache and performs all reading/writing to the actual file system outside of the callback procedures. "

For writes, I can see how one would cache the write data, queue it to pass it along to another thread or application that could then use buffered I/O later (or other unallowed operation), meanwhile the callback could return.

With the current API, I don't see how to do this for reads. If you put a cache in front of the part of the application that does buffered I/O, how do you handle a cache miss? It would seem that on a miss that the callback would still need to wait for the backend. If the backend is doing one of the unallowed operations and the callback is holding some semaphore related to that operations, you would still have deadlock. Am I being clear?

It would seem that to allow the application to do operations that are not allowed within the callback the reads need to have two steps. The API would have a read initiation, which would be queued by the application, and then return. The application would then do the operations that are not allowed. Then, when the data is available the application would call into callbackDisk (or if that direction isn't allowed, the callbackDisk would need to poll the application periodically). This second call would be what completes the OS read.

My understanding of the current read callback is that the data is required to be returned during the completion of that callback. This makes it impossible to defer unallowed operations to outside of the callback.
Posted: 10/05/2012 12:14:22
by Eugene Mayevski (EldoS Corp.)

CallbackDisk (as well other our Callback* products) does the thing which was never designed or even thought about by OS developers. Instead of handling the request the kernel-mode driver sends it back to user mode. However, when kernel-mode driver receives the request from the OS, the OS itself is in quite unstable state, with certain global objects locked.

That is one side of the problem. Another side of the problem is that the driver must either complete the operation or report failure. It can not postpone the operation - the OS was not designed for this. Consequently the callback *must* complete the operation, either successfully or with error. You can't split it to two parts.

In general, I don't see why the requirement of non-buffered IO constitutes such a big problem for you. Network operations are allowed, and so are non-buffered local disk IO operations. It's just buffered local disk operations that are not allowed cause they will cause the deadlock.

Sincerely yours
Eugene Mayevski
Posted: 10/05/2012 12:42:16
by Rich Van Gaasbeck (Standard support level)
Joined: 12/07/2010
Posts: 11

My application is already written and I'm now considering adapting it to CBDisk. It is large, complicated and does file I/O in many places and in different ways. I'd like to determine if fixing the buffered I/O is going to avoid all deadlocks before I undertake the changes.

My worry is that my application may need to do something that requires grabbing a lock for one of those "certain global objects" you mentioned.

I'm not familiar with the windows driver environment. In other kernels, it is generally possible to queue a request while waiting for an external event (like physical I/O to complete) and release locks such that other I/O requests can be processed. My suggestion presumed that something similar was possible in Windows.
Posted: 10/05/2012 13:01:49
by Eugene Mayevski (EldoS Corp.)

For some drivers it's so (requests can be rescheduled) but for in our particular case it's not always so - sector reading is synchronous and in some cases it can't be postponed.

Without knowing your application it's hard to tell if it's worth redesigning, i.e. whether removal of buffered IO would be enough (because some operation which you consider to be safe now can do something armful behind the scenes).

You need to realize that CallbackDisk was developed for relatively narrow class of tasks, and in most cases Callback File System is much better suited. It can be that Callback File System would work well in your scenario. Callback File System doesn't have so strict limitations as CallbackDisk has (though certain limits exist as well).

Sincerely yours
Eugene Mayevski



Topic viewed 3162 times

Number of guests: 1, registered members: 0, in total hidden: 0


Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!