在具有不同扇区大小的磁盘上使用 dd

在具有不同扇区大小的磁盘上使用 dd

我想将分区移动到新驱动器。旧驱动器的扇区大小为 512 字节,而新驱动器的扇区大小为 4096 字节。我尝试对整个磁盘执行 dd,但失败了,因为旧驱动器上的分区未与 4K 边界对齐。因此,我改为使用 fdisk 在新驱动器上从头创建一个分区,然后使用 dd 将该分区复制到磁盘之间。最后,我使用 resize2fs 扩展了新驱动器上的文件系统。这似乎有效,因为我可以挂载新分区(到目前为止是只读的)并查看文件,并且 fsck 说它是干净的。

但我仍然怀疑这样做是否安全。例如,FS 是否会关心扇区大小,从而导致这样做会造成破坏,还是 VFS 层或 HD 本身会保护它不受扇区大小的影响?

答案1

您还没有告诉我们您最初尝试的失败的 dd 命令是什么。不过,我花了一些时间检查 dd 命令的源代码(来自 coreutils 包),看起来我们这里遇到了问题。

1852   /* Some devices require alignment on a sector or page boundary
1853      (e.g. character disk devices).  Align the input buffer to a
1854      page boundary to cover all bases.  Note that due to the swab
1855      algorithm, we must have at least one byte in the page before
1856      the input buffer;  thus we allocate 2 pages of slop in the
1857      real buffer.  8k above the blocksize shouldn't bother anyone.
1858 
1859      The page alignment is necessary on any Linux kernel that supports
1860      either the SGI raw I/O patch or Steven Tweedies raw I/O patch.
1861      It is necessary when accessing raw (i.e. character special) disk
1862      devices on Unixware or other SVR4-derived system.  */

如果您给出错误消息,我可以进一步搜索。但对我来说,这就是我们遇到的问题。也就是说,将 512 字节页面边界与 4 KiB 页面边界对齐似乎不正确。

现在,进入第二部分,您是否创建了第二个驱动器的分区(使用 fdisk)为 512 字节大小。但是,大多数现代磁盘向操作系统公布的扇区大小是 1 MiB,即 4096 KiB。

在 fdisk.c 的 update_sector_offset 函数中你会看到

/*
             * Align the begin of partitions to:
             *
             * a) topology
             *  a2) alignment offset
             *  a1) or physical sector (minimal_io_size, aka "grain")
             *
             * b) or default to 1MiB (2048 sectrors, Windows Vista default)
             *
             * c) or for very small devices use 1 phy.sector
             */
            sector_t x = 0;

            if (fdisk_dev_has_topology(cxt)) {
                    if (cxt->alignment_offset)
                            x = cxt->alignment_offset;
                    else if (cxt->io_size > 2048 * 512)
                            x = cxt->io_size;
            }
            /* default to 1MiB */
            if (!x)
                    x = 2048 * 512;

            sector_offset = x / cxt->sector_size;

*cxt 是 fdisk 结构的描述符。

所以,这部分我不清楚。也就是说,如果你的新磁盘宣传扇区大小为 4096 KiB 或 512 字节。

现在进入最后一部分。

不,文件系统实际上并不关心扇区大小。只要块大小为 4 KiB,一切就都没问题,因为虚拟页面大小(在 mm 上下文中)为 4 KiB,因此 mmaped IO 需要与之对齐。在我的笔记本电脑中,块大小和物理扇区大小相同。

$ sudo blockdev --getpbsz /dev/sda
[sudo] password for chakraborty: 
4096

$ sudo blockdev --getbsz /dev/sda
4096

IO 发生在块大小的上下文中,而不是扇区大小。如果由于物理扇区大小 FS 遇到任何问题,我会感到非常惊讶。但是,VFS 并没有走那么远。VFS 位于发出 IO 的应用程序和实际文件系统之间。我们正在讨论的是 VFS 层之下。

相关内容