異なるセクターサイズのディスクで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 のページ境界に合わせるのは適切ではないようです。

さて、2 番目の部分ですが、2 番目のドライブのパーティションを (fdisk を使用して) 512 バイトのサイズで作成しましたか。ただし、最近のほとんどのディスクが OS に通知するセクター サイズは 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 であるため、mmap IO はそれに合わせて調整する必要があるからです。私のラップトップでは、ブロック サイズと物理セクター サイズは同じです。

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

$ sudo blockdev --getbsz /dev/sda
4096

IO は、セクター サイズではなくブロック サイズのコンテキストで発生します。物理セクター サイズが原因で FS に問題が発生した場合、非常に驚​​きます。ただし、VFS はそこまでは至りません。VFS は、IO を発行するアプリケーションと実際のファイル システムの間にあります。ここで説明しているのは、VFS レイヤーの下です。

関連情報