运行在内核为6.2.12-1-default的Tumbleweed上
使用_GNU_SOURCE定义应该允许使用SEEK_DATA作为lseek的whence值。
根据手册页,这应该适用于一系列文件系统。我已经在btrfs和ext4上测试了这段代码,得到了相同的结果。
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
void test(char *filepath) {
int write_value = 0x22;
int fh = open(filepath, O_CREAT | O_TRUNC | O_RDWR);
int os = lseek(fh, 10, SEEK_SET);
int wret = write(fh, &write_value, sizeof(int));
int os2 = lseek(fh, 0, SEEK_DATA);
printf("os: %d os2: %d wret %d\n", os, os2, wret);
close(fh);
}
给定上面的代码,我希望SEEK_DATA在偏移量10处找到第一个写入的值,并且os 2 == os,但lseek返回0。
文件确实按预期写入,od -x给出以下输出:
0000000 0000 0000 0000 0000 0000 0022 0000
有什么建议吗?我是否对预期行为做了错误的假设…
1条答案
按热度按时间ccrfmcuu1#
稀疏文件是特定于实现的。我们可以假设孔粒度取决于文件系统I/O块大小。
我修改了你的程序来做一些测试:
文件系统块大小通常为:
结果:
分析:
写入偏移10:
| data |
0块孔,1块数据。数据块从开头开始:os2 == 0。
写入偏移4095:
| data | data |
0块孔,2块数据。数据块从开头开始:os2 == 0。
写入偏移4096:
| hole | data |
1个孔块,1个数据块。数据块从秒开始,os 2 == 4096。
写入偏移量8191:
| hole | data | data |
1块孔,2块数据。数据块从秒开始,os 2 == 4096
写入偏移8192:
| hole | hole | data |
2块孔,1块数据。数据块从第三个开始,os 2 == 8192
写入偏移量8193:和8192一样。
观察结果符合预期。