接続とファイル構造のロック

ロックの目的で、次の 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 テーブルの排他ロック

最終決定

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構造) で待機しているすべてのユーザーのブロックを解除します。