Почему fdisk иногда добавляет полкибибайта?

Почему fdisk иногда добавляет полкибибайта?

Я пытаюсь разбить на разделы образ дискеты размером 1440 КБ с помощью fdisk(util-linux, v2.31.1).

Однако, судя по всему, инструмент добавляет сектор размером 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.

Со вторым вариантом все не так:

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

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

Ожидаемое ли это поведение? Думаю, да, но почему?

решение1

Однако, судя по всему, инструмент добавляет сектор размером 512 байт, независимо от того, какие единицы измерения я использую,
...
Теперь, если я использую достаточно большой файл, fdisk ведет себя по-другому с первой записью:
...
Это ожидаемое поведение?

Видимо, да, и, похоже, это ошибка типа "плюс один".
Когда вы указываете "+N" или "+" (вместо абсолютного номера сектора) для last sector, утилита, похоже, использует это количество как количество секторов в (или размер) нового раздела и добавляет это число к начальному номеру сектора.

Другими словами, правильный расчет должен быть

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

Но, по-видимому, коммунальное предприятие забывает вычесть один сектор из этой суммы, чтобы скорректироватьсчитатьксмещение.

Когда размер нового раздела невелик (т.е. всего два сектора), то эта ошибка "плюс один" совершенно очевидна.
Необходимо проверить фактический исходный код, чтобы определить, почему существует корреляция/зависимость от доступного размера устройства.

Обходной путь для этой очевидной ошибки — явно указать последний сектор, используя номер сектора.
Например, если начальный сектор — 2048, а размер раздела должен быть 1 Кбайт, то укажите последний сектор как 2049.


Поскольку этот «дополнительный» сектор находится в конце нового раздела, эта проблема не будет связана с выравниванием раздела.
Выравнивание раздела (и защитный цилиндр/дорожка/секторы) будет применено для изменения начала нового раздела.
То есть секторы будут зарезервированы «перед» новым разделом и не будут частью какого-либо раздела.
Эти сектора будут нераспределенными, по сути, потраченными впустую и не могут быть использованы (никакой файловой системой).
Выравнивание не влияет
на размер нового раздела. Описанная вами проблема касается размера раздела, а не его выравнивания.


Я пытаюсь разбить на разделы образ дискеты размером 1440 КиБ.

Дискеты не должны быть разделены. Есть только загрузочный сектор.
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));
    }

Некоторые отладочные данные (например, версия утилиты с включенной отладкой) помогли бы прояснить ситуацию.

Связанный контент