fdisk が時々半キビバイトを追加するのはなぜですか?

fdisk が時々半キビバイトを追加するのはなぜですか?

fdisk(util-linux、v2.31.1)を使用して 1440 KiB のフロッピー ディスク イメージをパーティション分割しようとしています。

しかし、このツールは、どの単位を使用しても512バイトのセクターを追加しているようで、なぜ


私がやったことは以下の通りです:

Created a new DOS disklabel [...]

Command (m for help): n
[...]
First sector (1-2879, default 1): 2048
Last sector, +sectors or +size{K,M,G,T,P} (63-2879, default 2879): +1K

Created a new partition 1 of type 'Linux' and of size 1.5 KiB.

うわあ!1.5 キロバイト!?

セクター数を使用してみましたが、同じ結果が得られました。

Last sector, +sectors [...]: +2

Created a new partition 1 of type 'Linux' and of size 1.5 KiB.

さて、十分に大きなファイルを使用すると、fdisk最初の表記とは異なる動作になります。

First sector (2048-131071, default 2048): 2048
Last sector, [...]: +1K

Created a new partition 1 of type 'Linux' and of size 1 KiB.

2 番目はそうではありません:

Last sector, +sectors [...]: +2

Created a new partition 1 of type 'Linux' and of size 1.5 KiB.

これは想定された動作ですか? 想定されていると思いますが、なぜでしょうか?

答え1

ただし、どの単位を使用しても、ツールは 512 バイトのセクターを追加しているように見えます
...
ここで、十分に大きなファイルを使用すると、fdisk は最初の表記とは異なる動作をします:
...
これは予想される動作ですか?

どうやらその通りで、これは「プラス 1」の種類のバグのようです。
に「+N」または「+」(絶対セクター番号の代わりに) を指定するとlast sector、ユーティリティはこの数量を新しいパーティションのセクター数 (またはサイズ) として利用し、この数値を開始セクター番号に追加します。

言い換えれば、正しい計算は

<last sector> = <start sector> + <sector count> - 1  

しかし、どうやらこの電力会社は、調整するためにこの合計から1つのセクターを差し引くことを怠っているようだ。カウント変位

新しいパーティションのサイズが小さい場合 (つまり、2 つのセクターだけの場合)、この「プラス 1」バグは非常に明白です。
デバイスの使用可能なサイズに相関関係/依存関係がある理由を判断するには、実際のソース コードを検査する必要があります。

この明らかなバグを回避するには、セクター番号を使用して最後のセクターを明示的に指定します。
たとえば、開始セクターが 2048 で、パーティション サイズが 1K バイトの場合、最後のセクターを 2049 に指定します。


この「余分な」セクターは新しいパーティションの最後にあるため、この問題はパーティションのアラインメントとは無関係です。
パーティションのアラインメント (およびガード シリンダ/トラック/セクター) は、新しいパーティションの開始を変更するために適用されます。
つまり、セクターは新しいパーティションの「前」に予約され、どのパーティションにも含まれません。
これらのセクターは割り当てられず、基本的に無駄になり、(どのファイル システムでも) 使用できません。
アラインメントは新しいパーティションのサイズには影響しません。
説明されている問題はパーティションのサイズに関係しており、アラインメントには関係ありません。


1440 KiBのフロッピーディスクイメージをパーティション分割しようとしています

フロッピー ディスクはパーティション分割されません。ブート セクターのみがあります。MBR
とパーティション テーブルはハード ディスク (および SSD) 用です。


付録

どうやらコードがあるようだutil-linux-2.31.1/libfdisk/src/dos.cパーティションの終わりを調整して、パーティションが整列されます!

static int add_partition(struct fdisk_context *cxt, size_t n,
             struct fdisk_partition *pa)
{
    ...

    if (isrel && stop - start < (cxt->grain / fdisk_get_sector_size(cxt))) {
        /* Don't try to be smart on very small partitions and don't align so small sizes */
        isrel = 0;
        if (stop > start)
            stop -= 1;
        DBG(LABEL, ul_debug("DOS: don't align end of tiny partition [start=%ju, stop=%ju, grain=%lu]",
            (uintmax_t)start,  (uintmax_t)stop, cxt->grain));
    }

    if (stop < limit && isrel && alignment_required(cxt)) {
        /* the last sector has not been exactly requested (but
         * defined by +size{K,M,G} convention), so be smart and
         * align the end of the partition. The next partition
         * will start at phy.block boundary.
         */
        stop = fdisk_align_lba_in_range(cxt, stop, start, limit);
        if (stop > start)
            stop -= 1;
        if (stop > limit)
            stop = limit;
        DBG(LABEL, ul_debug("DOS: aligned stop: %ju", (uintmax_t) stop));
    }

デバッグ出力 (つまり、デバッグが有効になっているユーティリティのバージョン) があれば、何が起こっているのかが明確になります。

関連情報