ext4 分区大小/可用空间差异

ext4 分区大小/可用空间差异

在为我的数据创建 250GiB 备份分区时,我注意到 Nautilus、gParted、df、tune2fs 等中报告的分区大小和可用空间之间存在很多差异。

起初我以为是 GiB/GB 混淆。不是

然后我认为这可能是 ext4 的保留块。不是

我完全糊涂了。以下是一些图片。以下是步骤:

  • 首先,NTFS。524288000 个扇区 x 512 字节/扇区 = 268435456000 字节 = 268.4 GB = 250 GiB。

在此处输入图片描述 在此处输入图片描述

鹦鹉螺说“总容量:250.0 GB“(尽管它实际上是 GiB,而不是 GB)。除了那个小小的标签错误之外,到目前为止一切都很好。

  • 现在,相同的分区,使用 gparted 格式化为 ext4:

在此处输入图片描述

第一个、最后一个和总扇区相同。它是相同的 250GiB 分区。已用大小为 4.11GiB(可能是保留块?)

在此处输入图片描述

不。看起来保留块是 12.7 GiB (~5%)。哎哟!)。 但...为什么总容量现在只有 246.1 GiB?。该差异(某种程度上)与 gparted 报告的 4.11 GiB 相符。但是……如果它不是来自保留块,那它是什么?为什么 gparted 没有报告已使用 12.7GiB 的空间?

$ df -h /dev/sda5
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda5             247G  188M  234G   1% /media/BACKUP

df与报告的可用空间 Nautilus 匹配。但是……只使用了 188M?难道不应该是 ~12GB 吗?而且总容量仍然不对。所以我跑去tune2fs寻找一些线索。(不相关的输出被省略)

$ sudo tune2fs -l /dev/sda5
tune2fs 1.41.12 (17-May-2010)
Filesystem volume name:   BACKUP
Filesystem UUID:          613d592e-47f5-4206-96a7-210090d340ef
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Filesystem state:         clean
Filesystem OS type:       Linux
Block count:              65536000
Reserved block count:     3276800
Free blocks:              64459851
First block:              0
Block size:               4096

65536000 个总块 * 4096 字节/块 = 268435456000 字节 = 268.4 GB = 250 GiB。它与 gparted 匹配。

3276800 个保留块 = 13421772800 字节 = 13.4 GB = 12.5 GiB。它(再次,有点)与 Nautilus 相匹配。

64459851 个可用块 = 264027549696 字节 = 264.0 GB = 245.9 GiB。为什么?难道它不应该是 250-12.5 = 237.5 (或 250-(12.5+4.11)=~233) 吗?

删除保留块:

$ sudo tune2fs -m 0 /dev/sda5
tune2fs 1.41.12 (17-May-2010)
Setting reserved blocks percentage to 0% (0 blocks)

$ sudo tune2fs -l /dev/sda5
tune2fs 1.41.12 (17-May-2010)
Filesystem volume name:   BACKUP
Filesystem UUID:          613d592e-47f5-4206-96a7-210090d340ef
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Filesystem state:         clean
Filesystem OS type:       Linux
Block count:              65536000
Reserved block count:     0
Free blocks:              64459851
Block size:               4096

正如预期的那样,块数相同,保留块为 0 个,但是......相同的空闲块我不是刚刚释放了 12.5 GiB 吗?

$ df -h /dev/sda5
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda5             247G  188M  246G   1% /media/BACKUP

在此处输入图片描述

看起来我做到了。可用空间从 233 GiB 增加到 245.9 GiB。gparted 根本不关心,显示确切地相同的信息!(发布相同的截图是没用的)

真是一片混乱!

我尝试尽可能详细地记录它...那么,有人能告诉我这里发生了什么吗?

  • NTFS -> ext4 格式中缺少的那些神秘的 4.11 GiB 是什么?
  • 为什么 gparted、Nautilus、tune2fs、df 之间存在如此大的差异?
  • 我的数学哪里错了?(本帖中以粗体标出的问题)

任何帮助都非常感谢。虽然我不知道发生了什么,但我正在认真考虑放弃 ext4,转而使用 NTFS,除了我的 / 分区。

谢谢!

答案1

这里发生了一些事情。gparted 报告实际使用/可用空间。内核将可用计数减去保留空间。删除保留空间后,可用计数没有改变,因为保留块已经是空闲的;只是非 root 用户不允许侵占该空间,以防止他们通过填满磁盘造成麻烦。gnome 数字有点不稳定,因为漏洞。它不会报告内核报告的已用空间(和 df 显示),而是通过从总数中减去可用空间来计算。这会导致它将保留空间显示为已使用。

实际使用的缺失 4GB 是 ext4 的 fs 开销。NTFS 最初只为 MFT 分配少量空间,并根据需要增加空间。但是,ext 系列文件系统在格式化时为 inode 表(大致相当于 MFT)分配空间,并且无法增长。报告的总空间中缺失的空间是 inode 表。剩余的使用空间来自日志(通常为 128 mb)和调整 inode 大小。

答案2

首先,保留块不是用于文件系统内部管理的块。

保留块只是为了保留而保留的root,以确保使用该分区上的文件的服务不会被某些非管理员用户填满所有空间而排除空间。

即使没有保留块(-m 0),总会有一部分空间用于文件系统内部管理,我无法说有多少,我没有那么深的了解。

还,分区执行为root,因此它将保留块视为空闲。鹦鹉螺,以用户身份执行,将其视为非自由。

好的,@psusi 回答得很清楚,我没有什么可补充的。

答案3

在使用 gparted 对我的全新 8 TB 磁盘进行分区后,它报告:

  Size: 7.28 TiB
  Used: 59.76 GiB   <-- Huh?
Unused: 7.22 TiB

这就是我来到这里的原因。现在开始调查。

运行sudo fdisk /dev/sdc(其中 /dev/sdc 是我的新磁盘)显示:

Disk /dev/sdc: 7,3 TiB, 8001563222016 bytes, 15628053168 sectors
Units: sectors of 1 * 512 = 512 bytes
...
Disklabel type: gpt

注意15628053168*512=8001563222016。

从现在开始,让我们以扇区数(512 字节)为单位进行工作,并且只使用十六进制表示法。这给了我们,

fdisk (real values)
Disk size: 3a3812ab0

此外,fdisk 还为我们提供了分区表:

Device     Start         End     Sectors  Size Type
/dev/sdc1   2048 15628052479 15628050432  7,3T Linux filesystem

让我们也把它翻译成十六进制(它已经在扇区中了):

/dev/sdc1    800   3a38127ff   3a3812000  7.277378082275390625 TiB

(该 TiB 值是精确的;但以十进制表示。它显示了为什么打印 7.3)。

前 0x800 个扇区保留用于主引导记录 (MBR) 和分区表 (类型为 gpt,因为它是由 gparted 创建的,我选择在那里使用该类型)。

这个End行业包容性很强,因此

3a38127ff + 1 - 800 = 3a3812000

但为什么选择这个呢?因为 gparted 将所有内容四舍五入到 1 MiB 边界(它说),这恰好是 0x800 个扇区(十六进制为 1024 * 1024 / 512)。

然而,为什么它不选择 3a3812fff 作为最后一个扇区呢?因为这个扇区不存在,所以总磁盘大小就是我们之前看到的 3a3812ab0。

好的,所以我们需要在开头留出一点空间用于 MBR 和分区表,但只想在 0x800 边界处开始和结束分区,因此第一个扇区是 800,最后一个扇区是 3a38127ff。导致总共分区大小3a3812000 个扇区,或 7.28 TiB,如 gparted 所报告的(十进制为 8001561821184 字节)。

其上的文件系统类型是 ext4。

让我们先安装它,然后让我们在 DECIMAL 中的扇区中工作:

sudo mount -t ext4 /dev/sdc1 /mnt/newdisk
df -B512 | grep sdc1
/dev/sdc1 15502817864 102728 14721279848  1% /mnt/newdisk

因此 df 以扇区和十六进制形式报告:

df Size: 15502817864 sectors (= 7937442746368 bytes = 7.219... TiB).
df Used: 102728 sectors (= 52596736 bytes = 50.16 MiB).
df Available: 14721279848 sectors (= 7537295282176 bytes = 6.855... TiB).

因此,报告的大小为 8001561821184 - 7937442746368 = 64119074816 = 59.716 GiB较少的比 fdisk 报告的分区大小要大!

好的,那么 ext4 如何工作?

我们可以快速获取大量信息

sudo dumpe2fs -h /dev/sdc1

最重要的输出是

Inode count:              244191232
Block count:              1953506304
Reserved block count:     97675315
Free blocks:              1937839392
Free inodes:              244191221
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      558
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         4096
Inode blocks per group:   256
Flex block group size:    16
First inode:              11
Inode size:               256
Required extra isize:     32
Desired extra isize:      32
Journal size:             1024M
Journal length:           262144

请注意,块计数显示满的分区大小。一个块为 4096 字节,因此有 1953506304 * 4096 = 8001561821184。

显然,我们正在寻找不可用的块。根据df报告的可用数据(7537295282176 / 4096 = 1840159981 个可用块),有 113346323 个块不可用。

该日志存在 262144 个块,因此...还剩 113346323 - 262144 = 113084179 个块。

我们有 558 个保留的 GDT 块……还需使用 113083621 个块。

fs 上的“组”数为‘inode 总数’/‘每组的 inode 数’ = 244191232/4096 = 59617。

大小为 256 字节的 inode 占 244191232 * 256 / 4096 = 15261952 个块,因此还需处理 113083621 - 15261952 = 97821669 个块。

我们这里没有选择,显然保留块数也不可用,即 97675315 .. 因此剩下 97821669 - 97675315 = 146354 个不可用块,我们尚未解释。这仍然是 571.7 MiB,或每组约 2.455 个块,但与我们必须解释的 59.76 GiB 相比,并不是那么多。

运行以下命令:

cat /proc/fs/ext4/sdc1/mb_groups | sed -e 's/^#.*://' | sort | uniq -c | sort -rn | sed -e 's/^\(..............\).*/\1/' | grep -v free

我们得到有 N 个空闲块(第二列)的组的数量(第一列):

  55860  32768
   3724  28640
     22  31743
      8  0    
      1  8958 
      1  28639
      1  27609

显然,每个组的最大可用块数为 32768(大部分),这也是dumpe2fs报告的(每个组的块数)。

因此,让我将此表转换为以字节为单位的“已使用”,方法是从 32768 中减去第二列,然后乘以 4096 字节。然后我得到

   3724  16908288
     22  4198400
      8  134217728
      1  97525760
      1  16912384
      1  21131264

并且 3724 * 16908288 + 22 * 4198400 + 8 * 134217728 + 97525760 + 16912384 + 21131264 = 64268140544 或 59.85 GiB。

概括

Unavailable blocks      Reason
97675315                Reserved block count (5%)
15261952                inodes (0.78%)
262144                  journal (0.013%)
146354                  Unexplained (0.007%)
558                     Reserved GDT blocks (0%)

让我们首先将保留块数更改为 0,因为此 HDD 用于长期存储,我真的不关心如果它已满会发生什么(我会关心,但我的系统仍能完美运行)。

sudo umount /dev/sdc1
sudo tune2fs -r 0 /dev/sdc1

dumpe2fs 现在报告:

Reserved block count:     0

但更重要的是,

df -B512 | grep sdc1
/dev/sdc1 15502817864 102728 15502682368   1% /mnt/newdisk

又名

df Available: 15502682368 sectors (= 7937373372416 bytes = 7.22... TiB)!

我们也可以减少 inode 的数量,但只有当您确定不需要它们时,这样做才是明智的;例如,当您只在磁盘上存储大文件时。inode 的数量大致等于您可以在磁盘上存储的文件 + 目录的数量。因此,拥有 244191232 个 inode 可以让我存储文件平均的此磁盘上的大小为 32kB(32504 字节)。相反,我打算在其中存储大约 1 到 2 GB 大小的文件...所以,是的,我认为我可以安全地将 inode 数量减少 10 倍。

因此,我决定重新格式化我的分区(拧紧 gparted,我需要的只是一个分区表,而不是文件系统):

sudo mkfs.ext4 -b 4096 -e remount-ro -i 325040 -j -L '/opt/verylarge' -m 0 -t ext4 -T big -U 48c6a937-aea3-42a0-a69c-c24d0dc65179

之后我得到了

Inode count:              24800672
Block count:              1953506304
Reserved block count:     0
Free blocks:              1951529866
Free inodes:              24800661
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      1024
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         416
Inode blocks per group:   26
Flex block group size:    16
First inode:              11
Inode size:               256
Required extra isize:     32
Desired extra isize:      32
Journal size:             1024M
Journal length:           262144

df -H
Filesystem  Size  Used Avail Use% Mounted on
/dev/sdc1   8,0T   97M  8,0T   1% /mnt/newdisk

我不知道那 1% 从何而来,但我对我的 8.0 TB 感到满意 :)

答案4

尝试使用 gparted 将分区大小减少几兆字节,然后再将其增加到原始大小。这可能会导致其他应用程序正确读取大小。我最近用这种方法纠正了一个 50Gb 的错误!

相关内容