logical sector size changes depending on whether it is attached via USB or direct SATA

I have a 3TB WD disk (in a My Book Essential external drive.) I used parted under Linux to partition it with a GPT disklabel and loaded it up with data from my laptop through the USB cable. Then I cracked it open and switched to be an internal SATA drive on a different computer (a desktop).

Linux (Fedora 14 on both computers) did not recognize the disk. parted said unrecognised disk label. It also reported the logical sector size as 512 bytes: "Sector size (logical/physical): 512 bytes / 4096 bytes. When I had it hooked up to my laptop via USB, it was reported as 4096/4096.

I attempted to repartition it by multiplying all sector offsets by 8, but it still didn't recognize the data. (Not that I'm terribly surprised.)

If I switch to the USB connection on the desktop machine, it switches back to 4096 byte logical sectors. So it appears that it's the USB controller board that makes it use 4096 byte logical sectors. Honestly, 4096 makes more sense to me, given that it's the hardware sector size, but is there a way to make either USB or SATA use the other value?


It's a little late, but I had a similar problem after the USB port of my IOMEGA hard disk case broke off. I switched to another USB-2-SATA case just to discover, that I could not mount the EXT4 partition. For some reason the IOMEGA case reported the logical sector size to be 4096, but my new case said it was only 512 bytes. This screws up the MS-DOS partitioning table.

It was driving me nuts, because with the help of testdisk I was able to access the partition, when changing the sector size, but I found no way to change the sector size system-wide. It turns out, that's not necessary, because EXT4 does not care for sector size, you just have to find the beginning of the partition you'd like to access.

Quick fix: Use a loopback device to shift to the correct position of the partition.

Permanent fix: Rewrite partition table, accordingly.

In my case the affected drive was /dev/sdb.

My quick fix was relatively easy, since I had only one partition beginning at sector 63.

$ sudo sfdisk -d /dev/sdb
# partition table of /dev/sdb
unit: sectors

/dev/sdb1 : start=       63, size=623708785, Id=83

Now we have to calculate the partition's position, when sector size still was 4096 bytes:

63 sectors * 4096 bytes = 258048 bytes

And use that with losetup:

$ sudo losetup /dev/loop0 /dev/sdb -o 258048
$ sudo mount /dev/loop0 /mnt

Your partition should now be mounted at /mnt.

For the longterm fix I used sfdisk to dump the partition layout:

$ sudo sfdisk -d /dev/sdb > sdb.partitions.sfdisk.text

Fixing the partition table by multiplying with the beginning sector with 8 where appropriate -- here I realized my partition table was kinda screwed from the beginning.

I edited the partition table dump with nano sdb.partitions.sfdisk.text:

/dev/sdb1 : start=       63, size=623708785, Id=83

to:

/dev/sdb1 : start=      504, size=623708785, Id=83

and later on extended the partition to use all available space (which I determined by other means):

/dev/sdb1 : start=      504, size=625141944, Id=83

Last step is to write back the partition table with:

$ sudo sh -c 'cat sdb.partitions.sfdisk.text | sfdisk /dev/sdb'

One more way (in fact improved the mentioned one here) to get the temporary access is to use losetup and kpartx. Here what I've done:

losetup -f /dev/sdl
kpartx -a /dev/loop2

Now we can use /dev/mapper/loop2pX instead of /dev/sdlX.