テストステ論

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

(dm-lc report) dm-lcのWRITE SAME対応 (2)

このレポートはWRITE SAME対応に関する考察の続きである. ここ数日, WRITE SAMEのことばかり気にしている. WRITE SAMEはかなりヤバい.

やはり, dm-lcがWRITE SAMEに対応するに当たって問題となるのは, バッファへの書き込みである.

dm-lcはキャッシュブロックサイズを4KBとしている. 問題は, 仮に, 4KB未満のデータしか持たずに, WRITE SAMEしてくださいという異常なお願いが来た場合に起こる. WRITE SAMEでは, logical block sizeのデータを繰り返すとしているが, この言葉はレイヤーによって大きさが変わってくるので, 512Bなのか4KBなのかはたまた8KBなのか判別がつかない.

例として, 今, 一つの0/1が1セクタ(512B)を表現しているとする. あるbioが3セクタ分のデータ011を持って, 4KB分書き込んでくださいとお願いしてきたとする. クライアントの要求に応えるためには, バッファ上に01101101という情報を書き込む必要がある, と思う. 「と思う」と言っているのは, 私のWRITE SAMEへの精密な理解がその程度だからである. もしかしたら別の挙動を要求するケースがあるかも知れない. その良く分からない部分になるべく依存しない, クリーンなコードを書く必要がある.

こういう時には, 実際にどういう使われ方をするかを調べるのが良い気休めになる. 以下は, WRITE SAMEを発行するための便利関数である. この関数で発行する必然性はないが, WRITE SAMEのユースケースを考えると, この関数を使わないケースは稀(kcopyd_copyが一例. ちなみにこの場合も1page分のバッファを用意している)であるように思う. この関数を見ると, 1page分の繰り返し用バッファを用意するようにお願いしているようなので, だとすると, 上記したようなあからさまな問題は回避出来る.

/**
 * blkdev_issue_write_same - queue a write same operation
 * @bdev:       target blockdev
 * @sector:     start sector
 * @nr_sects:   number of sectors to write
 * @gfp_mask:   memory allocation flags (for bio_alloc)
 * @page:       page containing data to write
 *
 * Description:
 *    Issue a write same request for the sectors in question.
 */
int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
                            sector_t nr_sects, gfp_t gfp_mask,
                            struct page *page)
{

しかし, これでも問題が残る. 例えば元のbioが, 4KBのバッファ内容を, 4KB境界でないところから繰り返すWRITE SAMEだった場合はどうするのか. mapメソッドの中では, 元のbioがどういうものだったかを知る術はない. 従って, 受け取ったbioのうちどの部分からかじるべきなのかが分からない.

だが, この理屈だと, もっとも簡単なアドレスマッピングを実装しているdm-linearですら正常に動かなくなってしまうはずである. この疑問を解くために何が必要か逆算すると, 境界に関しての何かしらの暗黙的なルールを, 元bioと, mapメソッドに送られてきたメソッドで共有していなければならないということになる. そしてそのうちもっとも妥当なのは, WRITE SAMEで使う4KBバッファは, 4KB境界にalignされて繰り返されるということである. だとすると, linearでもstripeでも, WRITE SAMEを実装出来ているのが理解出来る. しかしコードを見ると, このような境界を意識したコードが一切ない. 例えばlinearであれば, bioのアドレスを変更しているのみである.

この事実から, WRITE SAMEは, 「バッファを繰り返すことだけを定めており, そのオフセットについては何の言及もしていない」のではという仮説が立てられる. だとすると, linearもstripeのコードも理解出来る.

さて, 我々はWRITE SAMEについてLinuxカーネルコードや仕様書らしきものから, 重大な仮説を導いたわけだが, これをもってdm-lcは, WRITE SAMEへのサポートをしないことを決定する. この仮説は多くのものに依存しすぎているため全く信用出来ない. 従って, dm-lcを完全に正しく保つためには, WRITE SAMEはサポートしない決断をする他ない. そもそも, dm-lcにとって, WRITE SAMEをサポートするメリットはlinearなどと比べて大きくない. 今後, dm-lcに対してWRITE SAMEサポートを要求する声があれば検討を再開しないこともないが, それ以外の世界線では, dm-lcはWRITE SAMEを無視する.