已更新:FALLOC_FL_PUNCH_HOLE
最初不支持此3.0.0-17
,我认为我需要对其进行修补。
我知道linux有这个hole
功能,我想知道我是否可以在现有文件中打个洞。
具体来说,我已经通过这些代码创建了一个名为hole_test
的文件:
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <errno.h>
24
25 int main(int argc, char **argv)
26 {
27 int fd;
28 char a[7]="happy!";
30 fd = open("hole_test", O_CREAT|O_RDWR, 0666);
31 if(fd == -1)
32 printf("error, %s\n", (char *)strerror(errno));
35 // fallocate(fd, 0x02, 0,0);
36 // pwrite(fd, a, sizeof(a), 0);
37 // pwrite(fd, a, sizeof(b), 65536);
38 close(fd);
39 return 0;
40 }
首先,我使用L36
L37
来创建文件。 stat hole_test
显示:
File: `hole_test'
Size: 65540 Blocks: 16 IO Block: 4096 regular file
Device: 801h/2049d Inode: 1052101 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ bxshi) Gid: ( 1000/ bxshi)
Access: 2012-04-03 23:02:35.227664608 +0800
Modify: 2012-04-03 23:02:35.227664608 +0800
Change: 2012-04-03 23:02:35.227664608 +0800
然后我使用L35
并评论L36
L37
在我的文件中打个洞。(0x02等于FALLOC_FL_PUNCH_HOLE
,我找不到它定义的位置所以只是使用它的价值)
然后,stat hole_test
,Blocks
仍为16。
File: `hole_test'
Size: 65540 Blocks: 16 IO Block: 4096 regular file
Device: 801h/2049d Inode: 1052101 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ bxshi) Gid: ( 1000/ bxshi)
Access: 2012-04-03 23:02:35.227664608 +0800
Modify: 2012-04-03 23:02:35.227664608 +0800
Change: 2012-04-03 23:02:35.227664608 +0800
我想知道我是否可以在此hole_test
文件中删除现有数据?
我怎样才能在{0}偏移0到7的hole_test
上打洞,这样我认为Blocks
可能会变成8而我写的字符串就会消失。
希望你们能知道我说的话并给我一些建议。
答案 0 :(得分:3)
您使用fallocate(fd, FALLOC_FL_PUNCH_HOLE, offset, len)
。 (自Linux 2.6.38起支持)有关幕后详细信息和随附的修补程序,请参阅https://lwn.net/Articles/415889/。
答案 1 :(得分:0)
FALLOC_FL_PUNCH_HOLE标志必须与FALLOC_FL_KEEP_SIZE进行“或”运算 在模式;换句话说,即使在打完文件的末尾时, 文件大小(由stat(2)报告)不会改变。
At least on ext4,如果您只是通过FALLOC_FL_PUNCH_HOLE
,fallocate()
将返回Operation not supported
。
另请注意:
FALLOC_FL_ *标志是 自版本2.18以来在glibc头文件中定义。
因此,如果您使用的是支持早期版本的libc的内核,则可能需要手动定义它们:
// Constants are defined in glibc >= 2.18
#define FALLOC_FL_KEEP_SIZE 0x1
#define FALLOC_FL_PUNCH_HOLE 0x2