doc: winfsp-design.adoc

This commit is contained in:
Bill Zissimopoulos 2016-04-22 16:15:52 -07:00
parent 476efef806
commit 34033c1563

View File

@ -79,7 +79,7 @@ The I/O queue (internal name +FSP_IOQ+) is the main WinFsp mechanism for handlin
Let us now follow the life time of an IRP from the moment it arrives at the _Fsvol_ device up to the moment it is completed. Suppose an IRP_MJ_READ IRP arrives and the FSD determines that it needs to post it to the user mode file system for further processing (for example, it is a non-overlapped non-cached ReadFile from a user mode application). In order to do so the FSD may have to do preparatory tasks such as prepare buffers for zero copy (in the case of IRP_MJ_READ) or capture process security state or copy buffers, etc. (in other cases). This processing happens in the thread and process context that the IRP_MJ_READ was received (for example the thread and process context of the application that performed the ReadFile). The FSD then posts the IRP to the _Pending_ queue of the corresponding _Fsvol_ device and returns. However NTOS does not immediately return to the application as the ReadFile call is not completed yet, instead it waits on an event for the IRP to complete (recall that the ReadFile was non-overlapped). Let us now follow the life time of an IRP from the moment it arrives at the _Fsvol_ device up to the moment it is completed. Suppose an IRP_MJ_READ IRP arrives and the FSD determines that it needs to post it to the user mode file system for further processing (for example, it is a non-overlapped non-cached ReadFile from a user mode application). In order to do so the FSD may have to do preparatory tasks such as prepare buffers for zero copy (in the case of IRP_MJ_READ) or capture process security state or copy buffers, etc. (in other cases). This processing happens in the thread and process context that the IRP_MJ_READ was received (for example the thread and process context of the application that performed the ReadFile). The FSD then posts the IRP to the _Pending_ queue of the corresponding _Fsvol_ device and returns. However NTOS does not immediately return to the application as the ReadFile call is not completed yet, instead it waits on an event for the IRP to complete (recall that the ReadFile was non-overlapped).
The user mode file system has a thread pool where each thread attempts to get the next IRP from the _Pending_ queue by executing a special DeviceIoControl (+FSP_FSCTL_TRANSACT+). This DeviceIoControl blocks the user mode file system thread (with a timeout) until there is an IRP available. The +FSP_FSCTL_TRANSACT+ operation combines a send of any IRP responses that the user mode file system has already processed and a receive of any new IRP's that require processing. Upon receipt of the +FSP_FSCTL_TRANSACT+ code the FSD pulls the next IRP from the _Pending_ queue and then enters the Prepare_ phase for the IRP. In this phase tasks that must be performed in the context of the user mode file system process are performed (for example, in the case of an IRP_MJ_READ IRP the read buffers are mapped into the address space of the user mode file system to allow for zero copy). Once the _Prepare_ phase is complete the IRP is placed into the _Process_ table and the user mode version of the IRP called a "Request" (type +FSP_FSCTL_TRANSACT_REQ+) is marshalled to the file system process. The Request includes a "Hint" that enables the FSD to quickly locate the IRP corresponding to the Request once user mode processing is complete. The user mode file system has a thread pool where each thread attempts to get the next IRP from the _Pending_ queue by executing a special DeviceIoControl (+FSP_FSCTL_TRANSACT+). This DeviceIoControl blocks the user mode file system thread (with a timeout) until there is an IRP available. The +FSP_FSCTL_TRANSACT+ operation combines a send of any IRP responses that the user mode file system has already processed and a receive of any new IRP's that require processing. Upon receipt of the +FSP_FSCTL_TRANSACT+ code the FSD pulls the next IRP from the _Pending_ queue and then enters the _Prepare_ phase for the IRP. In this phase tasks that must be performed in the context of the user mode file system process are performed (for example, in the case of an IRP_MJ_READ IRP the read buffers are mapped into the address space of the user mode file system to allow for zero copy). Once the _Prepare_ phase is complete the IRP is placed into the _Process_ table and the user mode version of the IRP called a "Request" (type +FSP_FSCTL_TRANSACT_REQ+) is marshalled to the file system process. The Request includes a "Hint" that enables the FSD to quickly locate the IRP corresponding to the Request once user mode processing is complete.
The user mode file system now processes the newly arrived Read Request. Assuming that the Read succeeds, the file system places the results of the Read operation into the passed buffer (which recall is mapped in the address spaces of both the calling application and the file system process) and eventually performs another +FSP_FSCTL_TRANSACT+ with the response (type +FSP_FSCTL_TRANSACT_RSP+). This Response also include the Request Hint. The user mode file system now processes the newly arrived Read Request. Assuming that the Read succeeds, the file system places the results of the Read operation into the passed buffer (which recall is mapped in the address spaces of both the calling application and the file system process) and eventually performs another +FSP_FSCTL_TRANSACT+ with the response (type +FSP_FSCTL_TRANSACT_RSP+). This Response also include the Request Hint.