Harddrive com tamanho do setor físico de 4096 relatado como 512 atrás da ponte USB

3

Eu comprei um disco rígido de 4 TB novo (em 2017), então eu esperava que ele tivesse um tamanho de setor físico de 4096. De fato,

$ 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)

No entanto, quando tentei particioná-lo com parted , obtive um tamanho de bloco físico de 512:

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

A unidade está em uma porta USB 3 em uma dockingstation (iTec) atrás de uma ponte USB ( 152d:0561 , chipset JMicron JMS55).

A camada de bloco também parece ter o tamanho errado:

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

Um comando READ CAPACITY (16) SCSI também informa o tamanho errado:

$ 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

em vez de (de outra unidade)

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

Por outro lado, blockdev relatórios

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

Googling encontra informações vagas sobre pontes USB que fazem "emulação do setor 4k / 512, para permitir que grandes discos rígidos tenham uma tabela de partições MBR", mas se eu entendi corretamente, o tamanho do setor lógico deve ser 4096 para essas pontes, o que não é o caso da minha ponte.

Então, o que exatamente está acontecendo? E como posso consertá-lo, ou seja, convencer o kernel de que essa unidade possui blocos físicos de tamanho de 4096 bytes? Os atributos physical_block_size e minimum_io_size não são graváveis.

Uma possível explicação é que há um bug no firmware da bridge, e apenas copia os primeiros 12 bytes da resposta READ CAPACITY (16) , zerando o expoente no byte 13. Mas, nesse caso, eu ainda gostaria de contornar o bug de alguma forma.

Editar

Eu agora testei em um gabinete USB diferente (mais antigo). Conectando com eSATA, tudo funciona conforme planejado e READ CAPACITY (16) informa o tamanho do setor físico de 4096 bytes. A conexão via USB ( 04fc:0c25 Sunplus SATALink SPIF225A) reclama que READ CAPACITY (16) não é suportado (portanto, nenhum tamanho de setor físico), mas READ CAPACITY (10) é.

Isso confirma que, pelo menos para a ponte Sunplus, os comandos SCSI não são arbitrariamente encaminhados e faz parecer mais provável que a ponte USB JMicron tenha um bug no firmware, zerando a resposta READ CAPACITY (16) .

Mas ainda preciso saber como contornar esse bug.

    
por dirkt 11.11.2017 / 16:42

1 resposta

1

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.

Em bloco / 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));

Portanto, o BSZ relatado por blockdev não é nem de lógica nem de tamanho de bloco físico. É o "tamanho do bloco de software".

Olhando para este código, a parte sobre o tamanho do bloco de software sendo específico para o descritor de arquivo não parece fazer sentido. Também não quer definir isso com blockdev , dado que nenhuma outra opção é documentada em termos de blocos (apenas setores de 512 bytes de tamanho fixo).

Em meus próprios testes, o que realmente acontece é que o BSZ é preservado enquanto o processo any mantém o dispositivo de bloco aberto. Parece que é redefinido no último fechamento ().

Parted ficou confuso com isso também há alguns anos

belay that. BLKBSZGET is the kernel's chosen block size it will use to access the device (for normal disks turns out this is 1k, for ata_ram this is 4k), which is not the underlying disk's logical block size. :-( So we will likely need another ioctl() to get the right value from the kernel, and BLKSSZGET may wind up being the disks's logical block size, while a new ioctl() exports the disk's physical sector size. ugh.

Outra peculiaridade:

On Wed, Apr 09, 2003 at 06:53:17PM +0200, Rob van Nieuwkerk wrote:

I get 4096 with BLKBSZGET on several unmounted partitions on my system (RH 2.4.18-27.7.x kernel). Some give 1024 .. Maybe it is because I had them mounted first and unmounted them for the test ?

     

Essa seria a resposta mais provável. Quando você desmonta, eu não acredito   O sistema de arquivos incomoda a set_blocksize (get_hardsect_size (dev)).

    
por 11.11.2017 / 17:40