물리적 섹터 크기가 4096인 하드 드라이브는 USB 브리지 뒤에 512를 보고합니다.

물리적 섹터 크기가 4096인 하드 드라이브는 USB 브리지 뒤에 512를 보고합니다.

새(2017) 4TB 하드 드라이브를 구입했기 때문에 물리적 섹터 크기가 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

152d:0561드라이브는 USB 브리지(JMicron JMS55 칩셋) 뒤 도킹 스테이션(iTec)의 USB 3 포트에 있습니다.

블록 레이어의 크기도 잘못된 것 같습니다.

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

SCSI 명령 READ CAPACITY (16)도 잘못된 크기를 보고합니다.

$ 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

인터넷 검색에서 "MBR 파티션 테이블이 있는 대형 하드 드라이브를 허용하는 4k/512 섹터 에뮬레이션"을 수행하는 USB 브리지에 대한 모호한 정보를 찾았지만 올바르게 이해했다면 이 브리지의 논리적 섹터 크기는 4096이어야 합니다. 내 브리지가 아닙니다. .

그럼 정확히 무슨 일이 일어났나요? 이 문제를 어떻게 해결합니까? 즉, 커널이 드라이브에 4096바이트 크기의 물리적 블록이 있다고 믿게 만들 수 있습니까? 및 physical_block_size속성 minimum_io_size은 쓸 수 없습니다.

한 가지 가능한 설명은 브리지 펌웨어에 버그가 있다는 것입니다. 버그는 단순히 READ CAPACITY (16)응답의 처음 12바이트를 복사하고 바이트 13의 지수를 지웁니다. 하지만 이 경우에도 어떻게든 오류를 해결하고 싶습니다.


편집하다

이제 다른 (구) USB 인클로저에서 테스트했습니다. eSATA를 연결하면 모든 것이 예상대로 작동하고 READ CAPACITY (16)4096바이트의 물리적 섹터 크기를 보고합니다. USB( 04fc:0c25Sunplus SATALink SPIF225A) 를 통해 연결하면 READ CAPACITY (16)지원되지 않는다는 불만이 표시되지만(물리적 섹터 크기 없음) READ CAPACITY (10)지원됩니다.

이는 적어도 Sunplus 브리지의 경우 SCSI 명령이 임의로 전달되지 않으며 응답을 0으로 만드는 JMicron USB 브리지 펌웨어에 버그가 있을 가능성이 더 높다는 것을 확인합니다 READ CAPACITY (16).

하지만 여전히 이 오류를 해결하는 방법을 알아야 합니다.

답변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.

존재하다블록/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));

따라서 BSZ는 blockdev논리적 블록 크기나 물리적 블록 크기를 보고하지 않습니다. "소프트 블록 크기"입니다.

이 코드를 보면 파일 설명자별 소프트 블록 크기에 대한 부분이 이해가 되지 않는 것 같습니다. blockdev다른 옵션은 블록(고정 크기 512바이트 섹터만)으로 문서화되어 있지 않으므로 둘 중 하나를 사용하여 설정하고 싶지 않습니다.

내 테스트에서 실제로 일어나는 일은 BSZ가 매우 오랫동안 제자리에 남아 있다는 것입니다.어느이 프로세스는 블록 장치를 열린 상태로 유지합니다. 마지막 close()에서 재설정된 것 같습니다.

Parted도 몇 년 전에 이것에 대해 혼란스러워했습니다.

그것을 보호하십시오. BLKBSZGET는 장치에 액세스하기 위해 커널이 선택한 블록 크기입니다(일반 디스크의 경우 1k, ata_ram의 경우 4k). 이는 기본 디스크의 논리적 블록 크기가 아닙니다. :-( 따라서 커널에서 올바른 값을 얻으려면 또 다른 ioctl()이 필요할 수 있으며 BLKSSZGET는 결국 디스크의 논리적 블록 크기가 될 수 있지만 새로운 ioctl()은 디스크의 물리적 섹터 크기를 파생합니다. 윽.

또 다른 특이한 점:

2003년 4월 9일 수요일 오후 6시 53분 17초 +0200에 Rob van Nieuwkerk는 다음과 같이 썼습니다.

내 시스템(RH 2.4.18-27.7.x 커널)의 마운트되지 않은 여러 파티션에서 BLKBSZGET을 사용하면 4096이 표시됩니다. 일부는 1024를 제공합니다. 아마도 먼저 설치한 다음 테스트를 위해 제거했기 때문일까요?

이것이 가장 가능성 있는 대답일 것입니다. 마운트를 해제할 때 파일 시스템이 set_blocksize(get_hardsect_size(dev))를 방해한다고 생각하지 않습니다.

관련 정보