c++怎么在Linux下利用fallocate预先分配文件物理磁盘空间【底层】

幻夢星雲

幻夢星雲

2026-04-12

391人浏览

原创

fallocate默认可能仅逻辑预分配而非真正落盘物理块,因ext4等文件系统启用延迟分配(delalloc),需结合falloc_fl_zero_range与fsync或改用posix_fallocate确保物理分配落地。

c++怎么在linux下利用fallocate预先分配文件物理磁盘空间【底层】

为什么 fallocate 在 Linux 下不总是真正分配物理块

直接调用 fallocate(fd, 0, 0, size) 很可能只做“逻辑预分配”——文件大小和元数据立刻变大,但底层磁盘块并未实际落盘。这是默认行为(FALLOC_FL_KEEP_SIZE 未设,但内核仍可能走延迟分配路径),尤其在 ext4 + delalloc 模式下常见。你 ls -l 看文件变大了,df 却没少,hdparm --fibmap 查不到物理扇区,就是这个原因。

真正写入前,块可能一直挂在 page cache 里,甚至被回收;一旦系统内存紧张或 sync 延迟,首次 write() 才触发实际分配,此时才可能报 ENOSPC —— 这不是你想要的“提前失败”。

怎样强制让 fallocate 落实到物理磁盘

必须显式要求“立即分配并初始化”,靠两个关键标志组合:

  • FALLOC_FL_ALLOCATE(Linux 5.1+)或更通用的 FALLOC_FL_ZERO_RANGE(兼容旧内核)—— 强制分配并清零,绕过 delalloc
  • 配合 FALLOC_FL_KEEP_SIZE 避免改变文件长度(可选,按需)
  • 调用后立即 posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED)fsync(fd),确保页缓存刷出、块真正提交

示例代码片段:

int ret = fallocate(fd, FALLOC_FL_ZERO_RANGE, 0, size);
if (ret == 0) {
    fsync(fd); // 关键:确保分配落地
}

注意:FALLOC_FL_ZERO_RANGE 会把范围清零(即写入全 0),这本身就会触发块分配;若只想分配不写零,且内核 ≥5.1,可用 FALLOC_FL_ALLOCATE,但需确认文件系统支持(XFS 支持,ext4 尚未实现该标志)。

PyCharm 2026.2.0.1 Linux版
PyCharm 2026.2.0.1 Linux版

PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。

下载

ext4 下最稳的 fallback 方案:posix_fallocate + fsync

posix_fallocate 是 POSIX 标准接口,在 ext4 上行为比裸 fallocate 更可靠:它内部会尝试 fallocate,失败时自动回退到循环 pwrite + fsync,确保物理分配。但它仍有坑:

  • 不保证原子性:若中途 ENOSPC,文件可能已部分扩大,需自行清理
  • 慢:回退到 pwrite 时是逐块写,无并发,大文件耗时明显
  • 必须检查返回值:posix_fallocate 成功才表示物理空间真到位;返回非 0(如 errno == ENOTSUP)说明文件系统不支持,得切到手动 write 方案

调用示例:

int err = posix_fallocate(fd, 0, size);
if (err != 0) {
    // 处理 ENOTSUP / ENOSPC / EINTR ...
}

验证物理分配是否成功,别只信 ls -l

文件大小(logical size)和已分配块(physical blocks)是两回事。验证必须查底层映射:

  • filefrag -v filename:看输出中 “ext:” 行数(碎片数)和 “physical_block” 列——有真实数字才算落盘
  • stat -c "%b %B" filename:%b 是占用的 512 字节块数,%B 是 block size(通常是 4096);算出实际字节数,对比 st_size,若接近说明基本已分配
  • 极端验证:dd if=/dev/zero of=filename bs=4k count=1 conv=notrunc 后再 filefrag,若没新增 extent,说明之前已真分配

别依赖 du —— 它统计的是逻辑占用,对稀疏文件完全不准;也别只跑一次 fsync 就完事,某些场景需 sync_file_range(fd, 0, size, SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER) 更精准控制。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

linux c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

2023.08.22

1020

3

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.20

1084

5

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

2767

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

2121

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3357

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

160

15

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

2023.06.21

2669

4

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

2023.06.29

1647

10

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2023.06.30

1293

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpMyAdmin 安装文档
phpMyAdmin 安装文档

共0课时 | 0人学习

Apifox下载与安装手册
Apifox下载与安装手册

共0课时 | 0人学习

安装 Xdebug 并配置 phpstorm
安装 Xdebug 并配置 phpstorm

共1课时 | 125人学习