64ZiB ほしい!

SCSI プロトコルでは、デバイスの容量を取得するために、READ CAPACITY(10) や READ CAPACITY(16) を提供している。 これらのコマンドは、Logical Block Address(LBA) とロジカルブロックのバイト数でのサイズを返すことができる。 (10) と (16) の違いは、それぞれ返せる LBA の最大サイズが、4バイトか8バイトかの違いである。

さて Linux では最大 4096 バイトのブロックサイズに対応している。 そのため、READ CAPACITY(16) を使えば、最大で 0xffffffffffffffff000 バイト、すなわち 64ZiB までのデバイスカーネルに提供することができる。

TCMU では SCSI コマンドはパススルーでユーザーランドに渡されてくるのでこのようなありえないぐらい大きなサイズのデバイスを作ることができる。

雑に実装して見たところ、カーネルはめでたく 64ZiB のデバイスを認識してくれた。

[ 5857.003525] sd 4:0:0:0: [sdb] 18446744073709551615 4096-byte logical blocks: (75.6 ZB/64.0 ZiB)
[ 5857.004058] sd 4:0:0:0: [sdb] Write Protect is off
[ 5857.004060] sd 4:0:0:0: [sdb] Mode Sense: 17 00 10 00
[ 5857.004833] sd 4:0:0:0: [sdb] Write cache: enabled, read cache: enabled, supports DPO and FUA
[ 5857.011876] sd 4:0:0:0: [sdb] Attached SCSI disk

しかしながら lsblk でみると、16 EiB のブロックデバイスとして認識される。

$ lsblk | grep sdb                                                                                                                                                         
sdb              8:16   0    16E  0 disk

これは Linuxシステムコールなどが loff_t を使っており、64bit 環境ではそのサイズに制限されるためだ。 したがって残念ながら、通常の使い方では 64ZiB のブロックデバイスをユーザーランドに提供することはできない。