I bought a new (in 2017) 4 TB harddrive, so I expected it to have a 4096 physical sector size. Indeed,
$ 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)
However, when I tried to partition it with parted
, I got a physical block size of 512:
$ parted /dev/sdh print
Model: (scsi)
Disk /dev/sdh: 4001GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
The drive is on an USB 3 port in a dockingstation (iTec) behind a USB bridge (152d:0561
, JMicron JMS55 chipset).
The block layer seems to have the wrong size, too:
$ cat /sys/block/sdh/queue/physical_block_size
512
$ cat /sys/block/sdh/queue/minimum_io_size
512
An READ CAPACITY (16)
SCSI commands reports the wrong size, too:
$ 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
instead of (from another drive)
Logical blocks per physical block exponent=3 [so physical block length=4096 bytes]
On the other hand, blockdev
reports
$ blockdev --report /dev/sdh
RO RA SSZ BSZ StartSec Size Device
rw 256 512 4096 0 4000787030016 /dev/sdh
Googling finds vague information about USB bridges that do "4k/512 sector emulation, to allow large harddisks to have a MBR partition table", but if I understand this correctly, then the logical sector size should be 4096 for these bridges, which is not the case for my bridge.
So what exactly is going on? And how can I fix it, i.e. convince the kernel that this drive has physical blocks of 4096 bytes size? The physical_block_size
and minimum_io_size
attributes are not writeable.
One possible explanation is that there's a bug in the firmware of the bridge, and it just copies the first 12 bytes of the READ CAPACITY (16)
response, zeroing out the exponent in byte 13. But in that case, I'd still like to work around the bug somehow.
Edit
I now tested it in a different (older) USB enclosure. Connecting with eSATA, everything works as intended, and READ CAPACITY (16)
reports 4096 bytes physical sector size. Connecting via USB (04fc:0c25
Sunplus SATALink SPIF225A) complains that READ CAPACITY (16)
is not supported (so no physical sector size), but READ CAPACITY (10)
is.
That confirms that at least for the Sunplus bridge, SCSI commands are not arbitrarily forwarded, and makes it seem more likely that the JMicron USB bridge has a bug in the firmware, zeroing out the READ CAPACITY (16)
response.
But I still need to know how to work around that bug.
Best Answer
man blockdev
In block/ioctl.c:
So BSZ reported by
blockdev
is neither logical nor physical block size. It is the "soft block size".Looking at this code, the part about soft block size being specific to the file descriptor does not appear to make sense. Nor does wanting to set that with
blockdev
, given that no other option is documented in terms of blocks (only fixed-size 512 byte sectors).In my own tests, what actually happens is that BSZ is preserved for as long as any process holds the block device open. It looks like it gets reset on the last close().
Parted got confused by this too some years ago
Another quirk: