web-dev-qa-db-ja.com

4096の物理セクターサイズのハードドライブがUSBブリッジの背後で512と報告されている

新しい(2017年に)4 TBハードドライブを購入したので、4096の物理セクターサイズであると予想しました。実際、

_$ hdparm -I /dev/sdh
  ...
  Logical  Sector size:                   512 bytes
  Physical Sector size:                  4096 bytes
  Logical Sector-0 offset:                  0 bytes
  device size with M = 1000*1000:     4000787 MBytes (4000 GB)
_

ただし、partedでパーティションを作成しようとすると、512の物理ブロックサイズが得られました。

_$ parted /dev/sdh print
Model:   (scsi)
Disk /dev/sdh: 4001GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
_

ドライブは、USBブリッジ(_152d:0561_、JMicron JMS55チップセット)の後ろのドッキングステーション(iTec)のUSB 3ポートにあります。

ブロックレイヤーのサイズも間違っているようです:

_$ cat /sys/block/sdh/queue/physical_block_size
512
$ cat /sys/block/sdh/queue/minimum_io_size 
512
_

READ CAPACITY (16) SCSIコマンドも間違ったサイズを報告します:

_$ Sudo sg_readcap --16 /dev/sdh
Read Capacity results:
  Protection: prot_en=0, p_type=0, p_i_exponent=0
  Logical block provisioning: lbpme=0, lbprz=0
  Last logical block address=7814037167 (0x1d1c0beaf),
  Number of logical blocks=7814037168
  Logical block length=512 bytes
  Logical blocks per physical block exponent=0
  Lowest aligned logical block address=0
_

の代わりに(別のドライブから)

_  Logical blocks per physical block exponent=3 [so physical block length=4096 bytes]
_

一方、blockdev

_$ blockdev --report /dev/sdh
RO    RA   SSZ   BSZ   StartSec            Size   Device
rw   256   512  4096          0   4000787030016   /dev/sdh
_

Googlingは、「4k/512セクターエミュレーション、大容量のハードディスクにMBRパーティションテーブルを許可する」USBブリッジに関する漠然とした情報を見つけますが、これを正しく理解していれば、これらのブリッジの論理セクターサイズは4096になるはずです。私の橋の場合。

正確には何が起こっているのでしょうか?そして、どうすれば修正できますか?つまり、このドライブに4096バイトのサイズの物理ブロックがあることをカーネルに納得させますか? _physical_block_size_および_minimum_io_size_属性は書き込み不可です。

考えられる理由の1つは、ブリッジのファームウェアにバグがあり、READ CAPACITY (16)応答の最初の12バイトをコピーするだけで、バイト13の指数がゼロになることです。しかし、その場合は、なんとかしてバグを回避したい。


編集

別の(古い)USBエンクロージャでテストしました。 eSATAに接続すると、すべてが意図したとおりに機能し、READ CAPACITY (16)は4096バイトの物理セクターサイズを報告します。 USB経由での接続(_04fc:0c25_ Sunplus SATALink SPIF225A)は、READ CAPACITY (16)はサポートされていない(したがって、物理セクターサイズはサポートされていません)と文句を言いますが、READ CAPACITY (10)はサポートされています。

これにより、少なくともSunplusブリッジでは、SCSIコマンドが勝手に転送されないことが確認され、JMicron USBブリッジのファームウェアにバグがあり、READ CAPACITY (16)応答がゼロになる可能性が高くなります。

しかし、私はまだそのバグを回避する方法を知る必要があります。

5
dirkt

man blockdev

   --setbsz bytes
          Set blocksize. Note that the block size is specific to the  cur‐
          rent  file descriptor opening the block device, so the change of
          block size only persists for as long as blockdev has the  device
          open, and is lost once blockdev exits.

block/ioctl.c で:

case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
    return put_int(arg, block_size(bdev));
case BLKSSZGET: /* get block device logical block size */
    return put_int(arg, bdev_logical_block_size(bdev));
case BLKPBSZGET: /* get block device physical block size */
    return put_uint(arg, bdev_physical_block_size(bdev));

したがって、blockdevによって報告されるBSZは、論理ブロックサイズでも物理ブロックサイズでもありません。 「ソフトブロックサイズ」です。

このコードを見ると、ソフトブロックサイズに関するファイル記述子に固有の部分は、意味をなさないように見えます。また、ブロック(固定サイズの512バイトセクターのみ)に関して文書化されている他のオプションがないことを考えると、blockdevでそれを設定する必要はありません。

私自身のテストでは、実際に発生するのは、anyプロセスがブロックデバイスを開いている限り、BSZが保持されることです。最後のclose()でリセットされるようです。

Partedはこれも数年前に混乱しました

それをビレイ。 BLKBSZGETは、デバイスにアクセスするために使用するカーネルで選択されたブロックサイズです(通常のディスクの場合、これは1kであることがわかります。ata_ramの場合、これは4kです)。これは、基礎となるディスクの論理ブロックサイズではありません。 : したがって、カーネルから正しい値を取得するには、別のioctl()が必要になる可能性があります。新しいioctl()がディスクの物理セクターサイズをエクスポートする間、BLKSSZGETはディスクの論理ブロックサイズになる可能性があります。

---(別の癖:

2003年4月9日水曜日の06:53:17 PM +0200に、Rob van Nieuwkerkは次のように書いています。

私のシステム(RH 2.4.18-27.7.xカーネル)のいくつかのアンマウントされたパーティションでBLKBSZGETで4096を取得します。 1024を与えるものもあります。たぶん、最初にそれらをマウントし、テストのためにアンマウントしたためでしょうか?

それが最も可能性の高い答えです。アンマウントするとき、ファイルシステムがset_blocksize(get_hardsect_size(dev))に煩わしいとは思わない。

1
sourcejedi