我创建了一个 5 GB 的分区 -> /dev/sdd2,
然后创建了一个文件系统sudo mke2fs -N 700 -t ext4 -L test2 /dev/sdd2
,并将根保留空间设置为 0sudo tune2fs -r 0 /dev/sdd2
sudo dumpe2fs -h /dev/sdd2
显示:
Filesystem volume name: test2
Last mounted on: <not available>
Filesystem UUID: 64f07e45-910b-4e65-92ba-3ce7fdf1242f
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags: signed_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 1216
Block count: 1220864
Reserved block count: 0
Overhead clusters: 21320
Free blocks: 1199538
Free inodes: 1205
First block: 0
Block size: 4096
Fragment size: 4096
Group descriptor size: 64
Reserved GDT blocks: 596
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 32
Inode blocks per group: 2
Flex block group size: 16
Filesystem created: Sun Jun 16 11:26:49 2024
Last mount time: n/a
Last write time: Sun Jun 16 11:30:12 2024
Mount count: 0
Maximum mount count: -1
Last checked: Sun Jun 16 11:26:49 2024
Check interval: 0 (<none>)
Lifetime writes: 2417 kB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 9ce4737d-6beb-437d-a2fe-adaaa6142d11
Journal backup: inode blocks
Checksum type: crc32c
Checksum: 0x7b46d4d5
Journal features: (none)
Total journal size: 64M
Total journal blocks: 16384
Max transaction length: 16384
Fast commit length: 0
Journal sequence: 0x00000001
Journal start: 0
df /dev/sdd2
显示:
/dev/sdd2 4798176 24 4781768 1% /media/lithium/test2
4798176−4781768=16408
16 MB 在哪里?df 如何计算可用空间 - 公式?为什么 inode 是 1216,我定义为 700?
有人能帮助我吗?
特别感谢 Marcus Müller。
对吗?我尝试了分区统计以更好地了解文件系统,保存为 dfe,由于 dumpe2fs 信息
用法而需要 sudo,例如:dfe --help or sudo dfe /dev/sdd2
#!/usr/bin/bash
declare -a df_ARR
declare dumpFS df_output FSvolumeName FSuuid FSfeatures FStype FSosType partition mounted unit=M\
journalSize inodeTableSize partitionSize overheadISize overheadIISize rootReservedSize usedSize freeSize availableSize GDTreservedSize\
DP usedPercent useablePercent availablePercent fullReservedPercent\
C1=$'\e[38;2;0;200;0m' C2=$'\e[38;2;200;200;0m' C3=$'\e[38;2;120;180;220m' C4=$'\e[38;2;220;110;120m'\
declare -i inodeCount inodeSize inodesFree partitionBlocks blockSize freeBlocks usedBlocks journalBlocks rootReservedBlocks GDTreservedBlocks\
inodeTableBlocks overheadIBlocks overheadIIBlocks df_1kBlocks availableBlocks nUserUseableBlocks\
max_blockNumber_L max_SizeNumber_L\
blocksPerGroup inodesPerGroup groupDescriptorSize
DP=$(locale decimal_point)
divide_INTtoFLOAT ()
{
local -n LOC_var="$1"; local LOC_c; local -i LOC_a=$2 LOC_b=$3 LOC_d=$4+1 LOC_e=-$4
(( LOC_c=LOC_a*10**LOC_d/LOC_b))
LOC_a=${LOC_c: -1}; LOC_c=${LOC_c:0:-1}
((LOC_a>4 ? LOC_c++ : 0))
LOC_b=${#LOC_c}; for ((LOC_a=LOC_d;LOC_a>LOC_b;LOC_a--)); do LOC_c="0$LOC_c"; done
LOC_var="${LOC_c:0: LOC_e}$DP${LOC_c: LOC_e}"
}
calculate_SizeInUnits ()
{
local -n var=$1; local value unitSTR; local -i i l lN;
case $unit in
"K") value=$2;unitSTR="KB";;
"M") value=$(($2/1000));unitSTR="MB";;
"G") value=$(($2/1000**2));unitSTR="GB";;
"k") value=$(($2*1000/1024));unitSTR="kiB";;
"m") value=$(($2*1000/1024**2));unitSTR="MiB";;
"g") value=$(($2*1000/1024**3));unitSTR="GiB";;
esac
lN=${value: -1}; value=${value:0:-1}
if ((lN>4)); then ((value++)); fi
l=${#value}; for ((i=3;i>l;i--)); do value="0$value"; done
var="${value:0:-2},${value: -2} $unitSTR"
}
assign_Values ()
{
local -n var=$1; local value;
[[ $dumpFS =~ "$2"[^$'\n']* ]]; value=${BASH_REMATCH[0]}; value=${value#*:}
var=${value##*( )}
}
if [[ $1 == "--help" ]]; then
echo -e "\e[38;2;123;183;51m\e[1;4mUsage:\e[39m\e[22;24;4:0m dfe [\e[38;2;240;240;0m\e[3mOPTION...\e[39m\e[23m] [\e[38;2;240;240;0m\e[3mDEVICE\e[39m\e[23m]"
echo -e "prints disk usage and partition info!\n"
echo -e "\e[38;2;123;183;51m\e[1;4mDepends On:\e[39m\e[22;24;4:0m commands - df, dumpe2fs\n"
echo -e "\e[38;2;123;183;51m\e[1;4mOptions:\e[39m\e[22;24;4:0m"
echo -e "\t-u \e[38;2;240;240;0m\e[3munit \e[39m\e[23m \e[38;2;103;134;250mCHAR\e[39m ... K, M, G for KB, MB, GB - k, m, g for KiB, MiB, GiB - Standard: M"
echo -e "\t-v \e[38;2;240;240;0m\e[3mversion\e[39m\e[23m ... output version information and exit."
exit
fi
while getopts "u:v" "option"; do
case $option in
"u") unit=$OPTARG;;
"v") echo "df(e)xtended - version: 1.00 - 2024"; exit;;
"?") exit 2;;
esac
done
shift $((OPTIND-1))
shopt -s extglob
dumpFS=$(dumpe2fs -h "$1" 2> /dev/null)
if [[ $dumpFS == *"Couldn't find valid filesystem superblock"* ]]; then echo "Couldn't find valid filesystem superblock!" 1>&2; exit 5; fi
assign_Values "FSvolumeName" "volume name" ; assign_Values "FSuuid" "UUID"; assign_Values "FSfeatures" "features"; assign_Values "FSosType" "OS type";
assign_Values "inodeCount" "Inode count"; assign_Values "inodeSize" "Inode size"; assign_Values "inodesFree" "Free inodes"
assign_Values "partitionBlocks" "Block count"; assign_Values "blockSize" "Block size"; assign_Values "freeBlocks" "Free blocks"; #assign_Values "gdtReservedBlocks" "GDT blocks"
assign_Values "journalBlocks" "Total journal blocks"; assign_Values "GDTreservedBlocks" "GDT"
assign_Values "rootReservedBlocks" "Reserved block count"
assign_Values "blocksPerGroup" "Blocks per group"; assign_Values "inodesPerGroup" "Inodes per group"; assign_Values "groupDescriptorSize" "descriptor size"
df_output=$(df -T "$1"); df_output=${df_output#*$'\n'}; df_ARR=($df_output)
partition=${df_ARR[0]}; FStype=${df_ARR[1]}; df_1kBlocks=${df_ARR[2]}; usedBlocks=${df_ARR[3]}; availableBlocks=${df_ARR[4]}; mounted=${df_ARR[6]}
((usedBlocks=usedBlocks/4,\
availableBlocks=availableBlocks/4,\
inodeTableBlocks=inodeSize*inodeCount/4096,\
df_1kBlocks=df_1kBlocks/4,\
overheadIBlocks=partitionBlocks-(journalBlocks+inodeTableBlocks+df_1kBlocks+GDTreservedBlocks),\
overheadIIBlocks=df_1kBlocks-(rootReservedBlocks+usedBlocks+availableBlocks),\
nUserUseableBlocks=availableBlocks+usedBlocks ))
calculate_SizeInUnits "partitionSize" "$((partitionBlocks*4096))"
calculate_SizeInUnits "journalSize" "$((journalBlocks*4096))"
calculate_SizeInUnits "inodeTableSize" "$((inodeTableBlocks*4096))"
calculate_SizeInUnits "GDTreservedSize" "$((GDTreservedBlocks*4096))"
calculate_SizeInUnits "overheadISize" "$((overheadIBlocks*4096))"
calculate_SizeInUnits "overheadIISize" "$((overheadIIBlocks*4096))"
calculate_SizeInUnits "rootReservedSize" "$((rootReservedBlocks*4096))"
calculate_SizeInUnits "usedSize" "$((usedBlocks*4096))"
calculate_SizeInUnits "freeSize" "$((freeBlocks*4096))"
calculate_SizeInUnits "availableSize" "$((availableBlocks*4096))"
calculate_SizeInUnits "nUserUseableSize" "$((nUserUseableBlocks*4096))"
max_blockNumber_L=${#partitionBlocks}; max_SizeNumber_L=${#partitionSize}
echo -n "$C1" >/dev/tty; echo -n "Partition:"; echo -n $'\e[39m '>/dev/tty; echo $'\t'"$partition - $FSosType file system $FStype"
echo -n "$C1" >/dev/tty; echo -n "Volume Name:";echo -n $'\e[39m '>/dev/tty; echo $'\t'"$FSvolumeName"
echo -n "$C1" >/dev/tty; echo -n "UUID: "; echo -n $'\e[39m '>/dev/tty; echo $'\t'"$FSuuid"
echo -n "$C1" >/dev/tty; echo -n "Features:"; echo -n $'\e[39m '>/dev/tty; echo $'\t'"$FSfeatures"
echo -n "$C1" >/dev/tty; echo -n "Mounted on:"; echo -n $'\e[39m '>/dev/tty; echo $'\t'"$mounted"
echo -n "$C1" >/dev/tty; echo -n "Groups:"; echo -n $'\e[39m '>/dev/tty; printf "\t%-${max_blockNumber_L}s" "$(((partitionBlocks+blocksPerGroup-1)/blocksPerGroup))"; echo " - Group descriptor size: $groupDescriptorSize bytes - Inodes per group: $inodesPerGroup - Blocks per group: $blocksPerGroup"
divide_INTtoFLOAT "usedPercent" "$(((inodeCount-inodesFree)*100))" "$inodeCount" "3"
echo -n "$C1" >/dev/tty; echo -n "Inodes:"; echo -n $'\e[39m '>/dev/tty; printf "\t%-${max_blockNumber_L}s" "$inodeCount"; echo " - Free inodes: $inodesFree (used: ${usedPercent}%) - Inode size: $inodeSize bytes - Inode ratio: 1 inode per $(((partitionBlocks+inodeCount-1)/inodeCount)) blocks"
echo -n "$C1" >/dev/tty; echo -n "Blocks:"; echo -n $'\e[39m '>/dev/tty; printf "\t%-${max_blockNumber_L}s" "$partitionBlocks"; echo " - Free blocks: $freeBlocks total - Block size: $blockSize bytes"
echo -n " Journal : "; printf "%${max_blockNumber_L}s" "$journalBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$journalSize"
echo -n " Inode table ~: "; printf "%${max_blockNumber_L}s" "$inodeTableBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$inodeTableSize"
echo -n " Other FS overhead 1 : "; printf "%${max_blockNumber_L}s" "$overheadIBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$overheadISize"
echo -n " GD table reserved : "; printf "%${max_blockNumber_L}s" "$GDTreservedBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$GDTreservedSize"
echo -n "$C3" >/dev/tty
echo -n " Other FS overhead 2 : "; printf "%${max_blockNumber_L}s" "$overheadIIBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s" "$overheadIISize"; echo $' \u2500\e[17b\u252C\u2500 df blocks: '"$df_1kBlocks - $((df_1kBlocks*4)) 1k blocks"
echo -n " Root reserved : "; printf "%${max_blockNumber_L}s" "$rootReservedBlocks";echo -n " blocks "; printf "%${max_SizeNumber_L}s" "$rootReservedSize";echo $' \e[18b\u2502'
echo -n "$C2" >/dev/tty
echo -n " Used blocks : "; printf "%${max_blockNumber_L}s" "$usedBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s" "$usedSize"; echo $' \u2500\u252C\u2500 nUser useable \u2502'
echo -n " Available blocks : "; printf "%${max_blockNumber_L}s" "$availableBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s" "$availableSize"; echo $' \u2500\u2534\u2500\e[15b\u2518'
echo -n $'\e[39m' >/dev/tty
echo " "$'\u2500\e['"$((max_blockNumber_L+max_SizeNumber_L+9))b"
divide_INTtoFLOAT "availablePercent" "$((availableBlocks*100))" "$partitionBlocks" "3"
divide_INTtoFLOAT "fullReservedPercent" "$(((partitionBlocks-availableBlocks)*100))" "$partitionBlocks" "3"
echo -n "$C4" >/dev/tty
echo -n " Partition blocks : "; printf "%${max_blockNumber_L}s" "$partitionBlocks"; echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$partitionSize (available: ${availablePercent}% - full & reserved: ${fullReservedPercent}%)"
divide_INTtoFLOAT "useablePercent" "$((nUserUseableBlocks*100))" "$partitionBlocks" "3"
echo -n "$C2" >/dev/tty
echo -n " nUser useable : "; printf "%${max_blockNumber_L}s" "$nUserUseableBlocks";echo -n " blocks "; printf "%${max_SizeNumber_L}s\n" "$nUserUseableSize (useable: ${useablePercent}%)"
echo -n $'\e[39m' >/dev/tty
因此,首先令人伤心的是:我无法详细地告诉您为什么文件系统的结构是这样的——数十年的经验、特性和错误修复都融入其中,而且内核源中的 ext2/3/4 源代码树并不小。
我仍然会尽力回答你提出的明确问题:
文件系统开销。我知道这听起来很傻,但想想块组应该如何足够独立以减少争用——一些元数据结构必须在这些块组之间复制。
此外,还有超级块备份。
根本不是。它通过
statvfs
函数(包装在 gnulib 中。如果可以避免,请不要阅读 gnulib 代码,因为它非常#ifdef
繁重)询问内核。这些值的实际含义在所有实际用途中基本上都是未定义的。因此,对于您的问题“如何计算块中的总大小?”的答案是“您必须在 Linux 内核 ext4 驱动程序源代码中查找它”。不,您定义了 700 为保留。显然,保留更多尤其是保留 700;这与您想要的兼容!
可能,对于您似乎拥有的 38 个块组,这是最小的合理大小(将块数除以每个组的块数,然后向上舍入)。而且,1216 实际上恰好是 38 · 32;我猜您不能分配任意大小的 inode 表,它们总是需要包含 2 的幂,或者文件系统上其他一些相对合理的限制。您可以自己验证:指定
-n 7000
;您应该得到 7296(= 38 · 192 = 38 · 64 · 3)。说实话,尝试构建一个包含 700 个 inode 的文件系统似乎不太好。至少,您必须减少块组的数量(我不确定 ext4 允许您这样做到什么程度);那样的话,为什么要使用 ext4?对于您在这里解决的任何工作来说,这似乎都是错误的文件系统!