6

既存の dm-linear、dm-snapshot、dm-cache などを参照して、デバイス マッパー ターゲットを実装しようとしています。私の実装では、特定のセクター範囲で読み取り/変更/書き込み操作を実行する必要があります。デバイス マッパーはブロック レイヤーと直接対話するため、メモリ内のセクターを読み取り、バッファーを変更して別のセクター範囲に書き戻すために使用するデータ構造/関数がわかりません。アプリケーション レベルには syscall があり、その下には vfs_read/vfs_write があります。デバイスマッパーレイヤーに似たものはありますか? 私はここで非常に長い間立ち往生しています。どんな助けでも大歓迎です。

4

1 に答える 1

10

注: 3.14 以降の API はわずかに変更されているため、私の回答はカーネル バージョン < 3.14 に関連しています。

カーネルでは、特定のセクターを で読み書きしstruct bioます。この構造体は、すべてのブロック レベルの I/O に使用されます。包括的なドキュメントはカーネルlwnにあります。これらは、この構造のいくつかの最も重要なメンバーです。

  • bio->bi_sector- ブロック I/O 要求の最初のセクター
  • bio->bi_size- I/O リクエストのサイズ
  • bio->bi_bdev- 読み書きするデバイス
  • bio->bi_end_io- リクエストの最後にカーネルが呼び出すコールバック

デバイス マッパー ターゲットで行うことは、マップの着信bioです。デバイス マッパー ターゲットを作成するときは、少なくとも 2 つのコールバックを指定します:ctrmap。たとえば、最も単純なデバイス マッパー ターゲットdm-zeroは、そのコールバックを次のように宣言します。

static struct target_type zero_target = {
         .name   = "zero",
         .version = {1, 1, 0},
         .module = THIS_MODULE,
         .ctr    = zero_ctr,
         .map    = zero_map,
};

mapはキー コールバックです。これは、すべてのデバイス マッパー ターゲットの心臓部です。map着信を受信bioし、それで何でもできます。たとえば、dm-linear はbio、事前に定義されたオフセットによってすべての着信のセクターをシフトするだけです。コードを参照してください。

static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
{
        struct linear_c *lc = ti->private;

        return lc->start + dm_target_offset(ti, bi_sector);
}

static void linear_map_bio(struct dm_target *ti, struct bio *bio)
{
        struct linear_c *lc = ti->private;

        bio->bi_bdev = lc->dev->bdev;
        if (bio_sectors(bio))
                bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
}

static int linear_map(struct dm_target *ti, struct bio *bio)
{
        linear_map_bio(ti, bio);

        return DM_MAPIO_REMAPPED;
}

マップはポインターを受け取るためbio、そのポインターの下で値を変更できます。それだけです。

これが、I/O 要求をマップする方法です。独自のリクエストを作成したい場合は、割り当てbio、そのセクター、デバイス、サイズを埋め、コールバックを終了し、読み書きするバッファを追加する必要があります。基本的に、それはほんの数ステップです:

  • bio_alloc を呼び出して bio を割り当てます。
  • セットbio->bi_bdev, bio->bi_sector, bio->bi_size,bio->bi_end_io
  • 経由でページを追加しますbio_add_page
  • コールしsubmit_bioます。
  • bio->bi_end_ioコールバックで結果とエラーを処理する

例は、関数の dm-cryptターゲットにありcrypt_alloc_bufferます。

于 2014-06-16T08:18:57.490 に答える