接続とファイル構造のロック
ロックのために、2 つのレベルの参照テーブルが使用されます。
SRV_CALL と NET_ROOT 構造体に関するデバイス オブジェクトごとのテーブル (プレフィックス テーブル)
FCB 構造体に関する NET_ROOT 構造体ごとのテーブル (FCB テーブル)
これらの個別のテーブルを使うと、接続が確立された後は、異なる NET_ROOT 構造体に対するディレクトリ操作はほぼ完全に干渉されなくなります。 ただし、同じ NET_ROOT 構造体に対するディレクトリ操作は若干干渉します。 次の表では、特定の操作に必要なロックについて説明します。
操作 | データ型 | 必要なロック |
---|---|---|
作成または最終処理 |
SRV_CALL NET_ROOT V_NET_ROOT | NetName テーブルに対する排他的ロック (RxContext->RxDeviceObject->pRxNetNameTable の TableLock フィールド)。 |
参照、逆参照、または検索 |
SRV_CALL NET_ROOT V_NET_ROOT | NetName テーブルに対する共有ロックまたは排他的ロック (RxContext->RxDeviceObject->pRxNetNameTable の TableLock フィールド)。 |
作成または最終処理 |
FCB SRV_OPEN FOBX | FCB テーブルに対する排他的ロック (NET_ROOT->FcbTable の TableLock フィールド)。 |
参照、逆参照、または検索 |
FCB SRV_OPEN FOBX | FCB テーブルに対する共有ロックまたは排他的ロック (NET_ROOT->FcbTable の TableLock フィールド)。 |
現在、SRV_OPEN と FOBX データ構造体の操作には、FCB データ構造体の操作に必要なものと同じロックが必要であることに注意してください。 これは単にメモリ節約のためです。 Windows の将来のバージョンでは、この制限をなくし、共有リソースのセットを使って競合の可能性を許容できる低いレベルまで下げられるよう、FCB レベルで別のリソースが追加される可能性があります。
両方のロック (FinalizeNetFcb など) が必要な場合は、最初に NetName テーブルをロックしてから、FCB テーブルをロックする必要があります。 ロックの解除は、逆の順序で行う必要があります。
SRV_CALL、NET_ROOT、V_NET_ROOT の作成と終了処理のプロセスは、NetName テーブルに対する RDBSS ロックの取得と解放によって管理されます。
FCB の作成と終了処理のプロセスは、NET_ROOT 構造体に関連付けられている NetName テーブルに対するロックの取得と解放によって制御されます。
FOBX と SRVOPEN の作成と終了処理のプロセスは、FCB テーブルに対するロックの取得と解放によって管理されます。
次の表は、さまざまなデータ構造体の作成と最終処理について、ロックとロックを取得する必要があるモードをまとめたものです。
演算の種類 | SRV_CALL | NET_ROOT | FCB | SRV_OPEN | FOBX |
---|---|---|---|---|---|
作成 |
NetName テーブルの排他的ロック |
NetName テーブルの排他的ロック |
FCB テーブルの排他的ロック |
FCB テーブルの排他的ロック |
FCB テーブルの排他的ロック |
Finalize |
NetName テーブルの排他的ロック |
NetName テーブルの排他的ロック |
FCB テーブルの排他的ロック |
FCB テーブルの排他的ロック |
FCB テーブルの排他的ロック |
これらのデータ構造体の参照と逆参照は、特定の規則にも従う必要があります。
いずれかのデータ構造体に関連付けられている参照カウントが 1 に低下した場合 (ほとんどの場合、名前テーブルによって保持されている参照のみ)、そのデータ構造体は最終処理の候補になる可能性があります。 データ構造体は、すぐに最終処理することも、清掃対象としてマークすることもできます。 これらの方法はどちらも RDBSS に実装されています。 逆参照の間にロックの要件が満たされると、データ構造体は直ちに最終処理されます。 これに対する 1 つの例外は、遅延操作の最適化が実装されている場合です (FCB 構造体の逆参照など)。 それ以外の場合、データ構造体は清掃対象としてマークされます。
ネットワーク ミニ リダイレクターが最終処理ルーチンを呼び出すためには、NetName テーブルに対する排他的ロックを持っている必要があります。
これらのデータ構造体のいずれかで作成を実行するには、ネットワーク ミニ リダイレクター ドライバーは次のような処理を行う必要があります。
getshared();lookup();
if (failed) {
release(); getexclusive(); lookup();
if ((failed) { create(); }
}
deref();
release();
ロックの取得に成功したら、ノードをテーブルに挿入し、ロックを解除して、サーバーが使用可能かどうか調べます。 サーバーが使用可能な場合は、残りの情報を設定し、同じサーバー (SRV_CALL または NET_ROOT 構造体) で待機しているすべてのユーザーのブロックを解除します。