临时ext3镜像文件挂载后fs4::available_space返回值与预期不符
问题描述
我用Rust编写了一段代码,通过dd命令创建大小为100*1000字节的临时镜像文件,将其格式化为ext3文件系统并挂载到指定目录。但使用fs4::available_space获取该挂载目录的可用空间时,返回值与预期的100000字节不匹配,执行代码后断言失败。相关代码、输出及依赖配置如下:
代码实现
use std::process::Command; const TMP_DIR: &str = "/tmp/memory_check_test/"; fn init() { let _ = Command::new("dd") .args(["if=/dev/zero", "of=mem_check_file", "bs=1000", "count=100"]) .output() .expect("failed to create empty file"); let _ = Command::new("mkfs.ext3") .arg("mem_check_file") .output() .expect("failed to format mem_check_file with ext3 filesystem"); let _ = Command::new("mkdir") .arg("-p") .arg(TMP_DIR) .output() .expect(&format!("failed to create directory {}", TMP_DIR)); let _ = Command::new("mount") .arg("-o") .args(["loop", "mem_check_file", TMP_DIR]) .output() .expect(&format!("failed to mount file to {} directory", TMP_DIR)); let _ = Command::new("chmod") .arg("-R") .args(["777", TMP_DIR]) .output() .expect(&format!("failed to change permissions for {} directory", TMP_DIR)); } fn teardown() { let _ = Command::new("umount") .arg(TMP_DIR) .output() .expect(&format!("failed to unmount {} directory", TMP_DIR)); let _ = Command::new("rmdir") .arg(TMP_DIR) .output() .expect(&format!("failed to remove {} directory", TMP_DIR)); let _ = Command::new("rm") .arg("mem_check_file") .output() .expect("failed to remove mem_check_file"); } fn main() { init(); let available_space = fs4::available_space(TMP_DIR).expect("Failed to retrieve available memory space"); println!("{}", available_space); teardown(); assert_eq!(available_space, 100000); }
运行输出
thread 'main' panicked at src/main.rs:57:5: assertion `left == right` failed left: 100000 right: 839506960384 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Cargo.toml配置
[package] name = "mem_check" version = "0.1.0" edition = "2024" [dependencies] fs4 = "0.13.1"
问题分析与解决
核心原因
- 挂载操作未实际成功:代码仅检查命令是否能执行,未验证命令的退出状态码。大概率
mount命令执行失败(比如权限不足、镜像过小无法挂载),导致fs4::available_space读取的是/tmp所在系统分区的可用空间,而非挂载的镜像文件。 - ext3文件系统元数据开销:即使挂载成功,ext3需要预留空间存储超级块、inode等元数据,100KB的小镜像中,元数据占比极高,实际可用空间远小于100000字节。
- 权限不足:
mkfs.ext3和mount通常需要root权限,普通用户执行会直接失败。
修复方案
1. 严格校验命令执行结果
所有系统命令执行后必须检查退出状态,确保操作真的完成。以mount为例,修改代码如下(其他命令同理):
let output = Command::new("mount") .arg("-o") .args(["loop", "mem_check_file", TMP_DIR]) .output() .expect(&format!("failed to run mount command for {}", TMP_DIR)); assert!(output.status.success(), "mount failed: {}", String::from_utf8_lossy(&output.stderr));
这样挂载失败时会直接打印错误信息,快速定位问题。
2. 调整镜像大小与预期值
ext3有最小空间要求,过小的镜像(100KB)无法正常格式化和挂载。建议创建更大的镜像(比如10MB):
// 修改dd命令参数 .args(["if=/dev/zero", "of=mem_check_file", "bs=1M", "count=10"])
挂载后用df -B1 /tmp/memory_check_test/查看实际可用字节数,再将断言的预期值替换为该实际数值。
3. 以root权限运行代码
执行mkfs.ext3和mount需要root权限,运行代码时加上sudo:
sudo cargo run
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

