両方とも前のリビジョン
前のリビジョン
次のリビジョン
|
前のリビジョン
|
blog:2014:2014-11-09 [2014-11-11 11:14] Decomo |
blog:2014:2014-11-09 [2020-12-03 16:10] (現在) Decomo |
| |
===== ギャングブロック ===== | ===== ギャングブロック ===== |
<align right> | <WRAP rightalign> |
//[[https://github.com/illumos/illumos-gate/blob/6f834bc197c703a6568554c889157fb345bac079/usr/src/uts/common/fs/zfs/zio.c|zio.cのGang Blocks]] より// | //[[https://github.com/illumos/illumos-gate/blob/6f834bc197c703a6568554c889157fb345bac079/usr/src/uts/common/fs/zfs/zio.c|zio.cのGang Blocks]] より// |
</align> | </WRAP> |
| |
ギャングブロックは、DMUのような1つの大きなブロックを模倣した、小さなブロックの集合体です。 | ギャングブロックは、DMUのような1つの大きなブロックを模倣した、小さなブロックの集合体です。 |
プールが殆ど満杯だったり深刻な断片化が原因で、<ilcode>zio_dva_allocate()</ilcode>が要求サイズのブロックを見つけられなかった時、それは小さなフラグメントからブロックを構築するために<ilcode>zio_write_gang_block()</ilcode>を呼びます。 | プールが殆ど満杯だったり深刻な断片化が原因で、''zio_dva_allocate()''が要求サイズのブロックを見つけられなかった時、それは小さなフラグメントからブロックを構築するために''zio_write_gang_block()''を呼びます。 |
| |
ギャングブロックは、1つのギャングヘッダ(<ilcode>zio_gbh_phys_t</ilcode>)と最大3つ(<ilcode>SPA_GBH_NBLKPTRS</ilcode>)のギャングメンバーから構成されます。 | ギャングブロックは、1つのギャングヘッダ(''zio_gbh_phys_t'')と最大3つ(''SPA_GBH_NBLKPTRS'')のギャングメンバーから構成されます。 |
ギャングヘッダは丁度インダイレクトブロックのようなもので、ブロックポインタの配列です。 | ギャングヘッダは丁度インダイレクトブロックのようなもので、ブロックポインタの配列です。 |
ギャングヘッダは1セクタしか消費しません。それ故に、断片化にかかわらず確保可能です。 | ギャングヘッダは1セクタしか消費しません。それ故に、断片化にかかわらず確保可能です。 |
| |
ギャングブロックは、SHA256チェックサムの一意性を保証するための検証値にbpのvdev, offset, txgを用いた自己チェックサムを行います。 | ギャングブロックは、SHA256チェックサムの一意性を保証するための検証値にbpのvdev, offset, txgを用いた自己チェックサムを行います。 |
重要なのは、そのギャングブロックのbpの<ilcode>blk_cksum</ilcode>はデータのチェックサムであり、ギャングヘッダのものではないという事です。 | 重要なのは、そのギャングブロックのbpの''blk_cksum''はデータのチェックサムであり、ギャングヘッダのものではないという事です。 |
これは、データブロックシグネチャ(重複排除に必要)の物理的な格納状態に依存しない事を保証します。 | これは、データブロックシグネチャ(重複排除に必要)の物理的な格納状態に依存しない事を保証します。 |
| |
ギャングツリーの根はギャングリーダーと呼ばれます。 | ギャングツリーの根はギャングリーダーと呼ばれます。 |
| |
ギャングブロックへのあらゆる操作(読み込み、書き込み、解放、要求)遂行のため、<ilcode>zio_gang_assemble()</ilcode>はまず、ギャングリーダーとその下の全てのギャングヘッダーを再帰的に読むことにより、オリジナルの論理I/Oの<ilcode>io_gang_tree</ilcode>フィールドにギャングツリーを組み立てます(データリーフを除く)。 | ギャングブロックへのあらゆる操作(読み込み、書き込み、解放、要求)遂行のため、''zio_gang_assemble()''はまず、ギャングリーダーとその下の全てのギャングヘッダーを再帰的に読むことにより、オリジナルの論理I/Oの''io_gang_tree''フィールドにギャングツリーを組み立てます(データリーフを除く)。 |
これは、全てのギャングヘッダとその全てのギャングブロックを構成するためのbpを含む、コア内ツリー(in-core tree)を生成します。 | これは、全てのギャングヘッダとその全てのギャングブロックを構成するためのbpを含む、コア内ツリー(in-core tree)を生成します。 |
| |
今しがた組み立てられたギャングツリーで、<ilcode>zio_gang_issue()</ilcode>はそのギャングツリーを走査し、各bpのコールバックを呼びます。 | 今しがた組み立てられたギャングツリーで、''zio_gang_issue()''はそのギャングツリーを走査し、各bpのコールバックを呼びます。 |
ギャングブロックの解放のために、<ilcode>zio_gang_issue()</ilcode>は<ilcode>zio_free_gang()</ilcode>─<ilcode>zio_free()</ilcode>のちょっとしたラッパー</ilcode>を各bpに対して呼びます。 | ギャングブロックの解放のために、''zio_gang_issue()''は''zio_free_gang()''─''zio_free()''のちょっとしたラッパーを各bpに対して呼びます。 |
<ilcode>zio_claim_gang()</ilcode>は、同様に<ilcode>zio_claim()</ilcode>のラッパーを提供します。 | ''zio_claim_gang()''は、同様に''zio_claim()''のラッパーを提供します。 |
<ilcode>zio_read_gang()</ilcode>は、ギャングヘッダの読み込みを除く<ilcode>zio_read()</ilcode>のラッパーです。なぜならば、それらは<ilcode>io_gang_tree</ilcode>で既に持っているからです。 | ''zio_read_gang()''は、ギャングヘッダの読み込みを除く''zio_read()''のラッパーです。なぜならば、それらは''io_gang_tree''で既に持っているからです。 |
<ilcode>zio_rewrite_gang()</ilcode>は、上述したようなギャングヘッダの<ilcode>blk_cksum</ilcode>を更新するために、データの<ilcode>zio_rewrite</ilcode>を、あるいはギャングヘッダについては、ギャングヘッダの<ilcode>zio_reqrite()</ilcode>とデータの<ilcode>zio_checksum_compute()</ilcode>を実行します。 | ''zio_rewrite_gang()''は、上述したようなギャングヘッダの''blk_cksum''を更新するために、データの''zio_rewrite''を、あるいはギャングヘッダについては、ギャングヘッダの''zio_reqrite()''とデータの''zio_checksum_compute()''を実行します。 |
| |
two-phase assemble/issueモデルは部分的失敗の問題─もし、ギャングブロックの一部を読んでいた時に、別の部分へのギャングヘッダが読めなかったらどうなるでしょうか?─を解決します。 | two-phase assemble/issueモデルは部分的失敗の問題─もし、ギャングブロックの一部を読んでいた時に、別の部分へのギャングヘッダが読めなかったらどうなるでしょうか?─を解決します。 |
いったんギャングツリーが組み立てられれば、解放と確保はメモリに対する操作となり、失敗する事はありません。 | いったんギャングツリーが組み立てられれば、解放と確保はメモリに対する操作となり、失敗する事はありません。 |
| |
ギャング書き込み失敗イベントでは、全ての確保済み領域を直ちに解放(すなわち空き領域マップの後ろに追加)するために、<ilcode>zio_dva_unallocate()</ilcode>がギャングツリーを走査します。 | ギャング書き込み失敗イベントでは、全ての確保済み領域を直ちに解放(すなわち空き領域マップの後ろに追加)するために、''zio_dva_unallocate()''がギャングツリーを走査します。 |
これは、あてにならないデバイス(flaky device)が原因のサスペンド・レジュームが繰り返されている間に、<ilcode>ENOSPC</ilcode>を受け取らない事を保証します。 | これは、あてにならないデバイス(flaky device)が原因のサスペンド・レジュームが繰り返されている間に、''ENOSPC''を受け取らない事を保証します。 |
| |
ギャングの再書き込みはsync-to-convergenceの間にだけ発生します。 | ギャングの再書き込みはsync-to-convergenceの間にだけ発生します。 |
ギャングツリーを組み立てられなかった場合、そのブロックが変更される事はありません。従って、その解放は安全に保留する事が出来ます。(知っての通りブロックはまだ無傷です。) | ギャングツリーを組み立てられなかった場合、そのブロックが変更される事はありません。従って、その解放は安全に保留する事が出来ます。(知っての通りブロックはまだ無傷です。) |
ギャングツリーを組み立てる事が出来た場合、たとえ再書き込みのうちの幾つかが失敗しても、<ilcode>zio_dva_unallocate()</ilcode>は構成要素の各bpを解放し、次の同期パスで新しいブロックを確保する事が出来ます。 | ギャングツリーを組み立てる事が出来た場合、たとえ再書き込みのうちの幾つかが失敗しても、''zio_dva_unallocate()''は構成要素の各bpを解放し、次の同期パスで新しいブロックを確保する事が出来ます。 |
| |
全てのケースにおいて、ギャングツリーは部分的失敗からの完全な復旧に対応します。 | 全てのケースにおいて、ギャングツリーは部分的失敗からの完全な復旧に対応します。 |
| |