为什么 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 KiB!?

我尝试使用扇区数,得到了相同的结果:

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,分区大小为 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));
    }

一些调试输出(即启用了调试的实用程序版本)将有助于弄清正在发生的事情。

相关内容