テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

device-mapperにおけるWRITE SAMEとdiscardの違い

device-mapperにおけるWRITE SAMEのサポートについては昨日書いた.

WRITE SAMEもdiscardも, アドレス領域を無効化するという用途では同じようなもののように見えるが, device-mapperでの扱いは違う.

WRITE SAMEは無条件でsplitが行われるが, discardはsplitするかどうか選ぶことが出来る. なるほど, WRITE SAMEは「ゼロを書き込む」ことに意味的には等しい. 従って, write処理と同様に扱う必要がある. だからsplitされる. 一方, discardは効率だけの問題である. 上位が, その処理のあとに領域がゼロを返すことを期待するならばWRITE SAMEなりを使うべきであってdiscardを使うべきではない. discardは, 実行後に返す値については保証する場合と保証しない場合がある. device-mapperはdiscardについてどういう態度をとっているのだろうか.

discardについては, get_num_bios, is_split_required両方のメソッドが実装されている. 前者はWRITE SAMEの時と同格なので説明を省く. 後者は, もしsplit_discard_biosが0ならばsplitしないし1ならばするという動作に繋がる.

static unsigned get_num_discard_bios(struct dm_target *ti)
{
        return ti->num_discard_bios;
}

static bool is_split_required_for_discard(struct dm_target *ti)
{
        return ti->split_discard_bios;
}

dm_targetには他にも, discard_zeroes_data_unsupportedというメンバがある. これは最終的にこのコードに関わってくる.

        if (!dm_table_discard_zeroes_data(t))
                q->limits.discard_zeroes_data = 0;

いくつかのターゲットでtrue(つまり, サポートしませんということ)となっている. それにはdm-cacheも含まれる. 一体これは何だろうか.

0 device-mapper.h   <global>                      259 bool discard_zeroes_data_unsupported:1;
1 dm-cache-target.c cache_create                 1912 ti->discard_zeroes_data_unsupported = true;
2 dm-crypt.c        crypt_ctr                    1669 ti->discard_zeroes_data_unsupported = true;
3 dm-raid1.c        mirror_ctr                   1081 ti->discard_zeroes_data_unsupported = true;
4 dm-table.c        dm_table_discard_zeroes_data 1385 if (ti->discard_zeroes_data_unsupported)
5 dm-thin.c         pool_ctr                     2039 ti->discard_zeroes_data_unsupported = true;
6 dm-thin.c         thin_ctr                     2680 ti->discard_zeroes_data_unsupported = true;

ぐぐってみると(http://www.mjmwired.net/kernel/Documentation/block/queue-sysfs.txt), 「discard領域がzeroを返すか」というものらしい.

さて, dm-lcではどうしようかとコードを見てみたら, なぜかちゃっかりとtrueに設定されている. ちゃんと検討した覚えはないのだが, なぜかちゃんと実装されている. 天才か.