Connections and File Structure Locking
For locking purposes, there are two levels of lookup tables used:
A per-device object table for SRV_CALL and NET_ROOT structures (prefix table)
A table-per-NET_ROOT structure for FCB structures (FCB table)
These separate tables allow directory operations on different NET_ROOT structures to be almost completely non-interfering once the connections are established. Directory operations on the same NET_ROOT structure do interfere slightly, however. The following table describes what locks are needed for specific operations:
Operation | Data types | Lock required |
---|---|---|
Create or Finalize |
SRV_CALL NET_ROOT V_NET_ROOT | An exclusive lock on the NetName table (the TableLock field of RxContext->RxDeviceObject->pRxNetNameTable). |
Reference, Dereference, or Lookup |
SRV_CALL NET_ROOT V_NET_ROOT | A shared or exclusive lock on the NetName table (the TableLock field of RxContext->RxDeviceObject->pRxNetNameTable). |
Create or Finalize |
FCB SRV_OPEN FOBX | An exclusive lock on the FCB table (the TableLock field of NET_ROOT->FcbTable). |
Reference, Dereference, or Lookup |
FCB SRV_OPEN FOBX | A shared or exclusive lock on the FCB table (the TableLock field of NET_ROOT->FcbTable). |
Note that manipulations of SRV_OPEN and FOBX data structures currently require the same lock as needed for manipulations of FCB data structures. This is simply a memory saving idea. Future versions of Windows may add another resource at the FCB level to remove this restriction so that a set of shared resources could be used to decrease the probability of a collision to an acceptably low level.
If you require both locks (FinalizeNetFcb, for example), you must take the lock on NetName table first and then the lock on the FCB table. You must release the locks in the opposite order.
The SRV_CALL, NET_ROOT, and V_NET_ROOT creation and finalization process is governed by the acquisition and release of the RDBSS lock on the NetName table.
The FCB creation and finalization process is governed by the acquisition and release of the lock on the NetName table associated with the NET_ROOT structure.
The FOBX and SRVOPEN creation and finalization process is governed by the acquisition and release of the lock on the FCB table.
The following table summarizes the locks and the modes in which the locks need to be acquired for creation and finalization of the various data structures:
Type of Operation | SRV_CALL | NET_ROOT | FCB | SRV_OPEN | FOBX |
---|---|---|---|---|---|
Create |
Exclusive lock on NetName table |
Exclusive lock on NetName table |
Exclusive lock on FCB table |
Exclusive lock on FCB table |
Exclusive lock on FCB table |
Finalize |
Exclusive lock on NetName table |
Exclusive lock on NetName table |
Exclusive lock on FCB table |
Exclusive lock on FCB table |
Exclusive lock on FCB table |
Referencing and dereferencing these data structures must adhere to certain conventions as well.
When the reference count associated with any of the data structures drops to 1 (the sole reference being held by the name table in most cases), the data structure is a potential candidate for finalization. The data structure can be either finalized immediately or it can be marked for scavenging. Both of these methods are implemented in RDBSS. When the locking requirements are met during dereferencing, the data structures are finalized immediately. The one exception to this is when delayed operation optimization is implemented (dereferencing the FCB structure, for example). Otherwise, the data structure is marked for scavenging.
A network mini-redirector should have an exclusive lock on the NetName table in order to call a finalization routine.
To execute a Create on one of these data structures, a network mini-redirector driver should do something similar to the following:
getshared();lookup();
if (failed) {
release(); getexclusive(); lookup();
if ((failed) { create(); }
}
deref();
release();
When you have successfully acquired the lock, insert the node into the table, release the lock, and then see if the server is available. If the server is available, set up the rest of the information and unblock anyone who is waiting on the same server (the SRV_CALL or NET_ROOT structures).