dir*_*rkt 5 hard-disk usb-drive block-device
我买了一个新的(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)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用 对其进行分区时parted
,我得到了 512 的物理块大小:
$ parted /dev/sdh print
Model: (scsi)
Disk /dev/sdh: 4001GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Run Code Online (Sandbox Code Playgroud)
该驱动器位于 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
Run Code Online (Sandbox Code Playgroud)
一个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
Run Code Online (Sandbox Code Playgroud)
而不是(来自另一个驱动器)
Logical blocks per physical block exponent=3 [so physical block length=4096 bytes]
Run Code Online (Sandbox Code Playgroud)
另一方面,blockdev
报道
$ blockdev --report /dev/sdh
RO RA SSZ BSZ StartSec Size Device
rw 256 512 4096 0 4000787030016 /dev/sdh
Run Code Online (Sandbox Code Playgroud)
谷歌搜索发现有关执行“4k/512 扇区模拟,以允许大硬盘具有 MBR 分区表”的 USB 桥接器的模糊信息,但如果我理解正确,那么这些桥接器的逻辑扇区大小应为 4096,这不是我的桥的情况。
那么究竟是怎么回事呢?我该如何修复它,即让内核相信该驱动器具有 4096 字节大小的物理块?在physical_block_size
和minimum_io_size
属性是不可写。
一种可能的解释是桥接器的固件中存在错误,它只是复制READ CAPACITY (16)
响应的前 12 个字节,将字节 13 中的指数归零。但在这种情况下,我仍然想解决这个错误不知何故。
编辑
我现在在不同的(较旧的)USB 外壳中对其进行了测试。与 eSATA 连接,一切正常,并READ CAPACITY (16)
报告 4096 字节的物理扇区大小。通过 USB 连接(04fc:0c25
Sunplus SATALink SPIF225A)抱怨READ CAPACITY (16)
不支持(因此没有物理扇区大小),但支持READ CAPACITY (10)
。
这证实了至少对于凌阳桥而言,SCSI 命令不会被任意转发,并且看起来更有可能是 JMicron USB 桥在固件中存在错误,从而将READ CAPACITY (16)
响应归零。
但我仍然需要知道如何解决这个错误。
man blockdev
--setbsz bytes\n Set blocksize. Note that the block size is specific to the cur\xe2\x80\x90\n rent file descriptor opening the block device, so the change of\n block size only persists for as long as blockdev has the device\n open, and is lost once blockdev exits.\n
Run Code Online (Sandbox Code Playgroud)\n\n在块/ioctl.c中:
\n\ncase BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */\n return put_int(arg, block_size(bdev));\ncase BLKSSZGET: /* get block device logical block size */\n return put_int(arg, bdev_logical_block_size(bdev));\ncase BLKPBSZGET: /* get block device physical block size */\n return put_uint(arg, bdev_physical_block_size(bdev));\n
Run Code Online (Sandbox Code Playgroud)\n\n因此 BSZ 报告的blockdev
既不是逻辑块大小也不是物理块大小。它是“软块大小”。
查看此代码,有关特定于文件描述符的软块大小的部分似乎没有意义。blockdev
考虑到没有以块形式记录其他选项(仅固定大小的 512 字节扇区),也不想使用 来设置它。
在我自己的测试中,实际发生的情况是,只要任何进程保持块设备打开,BSZ 就会被保留。看起来它在最后一次 close() 时被重置。
\n\n\n\n\n\n\n\n\n保护那个。BLKBSZGET 是内核选择的块大小,它将用于访问设备(对于普通磁盘,这是 1k,对于 ata_ram,这是 4k),这不是底层磁盘的逻辑块\ n 尺寸。:-( 因此,我们可能需要另一个 ioctl() 来从内核获取正确的值,并且 BLKSSZGET 可能最终成为磁盘的逻辑块大小,而新的 ioctl() 会导出磁盘\的物理扇区大小。呃。
\n
\n\n2003 年 4 月 9 日星期三下午 06:53:17 +0200,Rob van Nieuwkerk 写道:
\n\n\n\n\n我在系统\n(RH 2.4.18-27.7.x 内核)上的几个未安装分区上使用 BLKBSZGET 得到 4096。有些给出 1024 .. 也许是因为我先安装了它们,然后为了测试而卸载了它们?
\n这将是最有可能的答案。当您卸载时,我不相信文件系统会费心设置_blocksize(get_hardsect_size(dev))。
\n