免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2437 | 回复: 5
打印 上一主题 下一主题

[Linux] 这样的情况会出现文件空洞不 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-11 00:18 |只看该作者 |倒序浏览
本帖最后由 homerzhou 于 2013-05-16 15:39 编辑
  1. int fd = open("123",O_RDWR)
  2. while(1)
  3. {       
  4.         write(fd,"hello world",12)
  5.         sleep(1)
  6. }
复制代码
很简单的程序,每隔一秒  向123  这个文件 写hello world   

现在我开另外一个终端,打开123 这个文件,将123 中已写的内容删掉,这样以后  123文件 就会一直 显示是空的了,可是 那个程序并没有退出,难道没有往里面写?


还是说写了,可是有文件空洞,因为我删除内容时 将文件的长度减少,而那个程序并不知晓,还是按照原来的偏移量,这样应该就产生文件空洞
可是  od -c并没有显示空洞,不解
求高手解答~

论坛徽章:
0
2 [报告]
发表于 2013-05-15 20:51 |只看该作者
读写不是原子操作的吗?    你删除内容同时会修改文件inode的属性

论坛徽章:
0
3 [报告]
发表于 2013-05-16 15:39 |只看该作者
顶起来,版主帮帮忙~

论坛徽章:
4
白羊座
日期:2013-09-17 21:59:30技术图书徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40双子座
日期:2013-12-17 18:26:39
4 [报告]
发表于 2013-05-17 23:18 |只看该作者
以下只是个人分析,若有错误之处,希望能得到指正。谢谢!

我使用vim编辑器编辑也有和你一样的结果。
strace vim后发现vim是这样操作的。(以下只是示意,与实际输出有差别)
打开时:
  1. open("test",O_RDONLY) = 3;
  2. read(3);
  3. close(3);
复制代码
写时:
  1. unlink("test~");
  2. rename("test","test~");
  3. open("test", O_WRONLY|O_CREAT|O_TRUNC) = 3;
  4. write(3);
  5. close(3);
  6. unlink("test~");
复制代码
对于unlink,SUSV3的unlink页有这样一段话:
  1. If one or more processes have the file open when the last link is removed, the link shall be removed before unlink() returns, but the removal of the file contents shall be postponed until all references to the file are closed.
复制代码
对于rename,SUSV3的rename页有这样一段话用来说明新的文件名:
  1. If one or more processes have the file open when the last link is removed, the link shall be removed before rename() returns, but the removal of the file contents shall be postponed until all references to the file are closed.
复制代码
但是对于旧文件名没有说明,而我自己系统的man -s 2 rename页有这样一段话(系统为:3.6.11-4.fc16.i686 GNU/Linux,c语言库为glibc-2.14.90-24.fc16.9.i686):
  1. Open file descriptors for oldpath are also unaffected.
复制代码
对于以上都没有在系统上验证,认为文档与实现是相符的。

通过以上的资料,我是这样认为的:
程序先写部分数据到文件,然后vim读取数据到缓存,删除数据,然后rename原文件,程序中打开的文件描述符无影响,但指向中间文件(文件名多了一个~),vim将删除后的数据写入原文件名新文件中,再unlink中间文件,这将导致中间文件从目录项中删除,而程序中的文件描述符指向临时文件(这与APUE中介绍的自己调用unlink产生临时文件效果一样)。所以你看到文件一直为空。实际此时如果用df命令查看磁盘空间可以发现临时文件的空间还被占用着,当文件描述符关闭后,磁盘空间才会释放。




论坛徽章:
0
5 [报告]
发表于 2013-05-20 20:38 |只看该作者
回复 4# 井蛙夏虫

高手呀,你说的 对,确实 是已经被删除了,而且指向的路径转到123~  就是你说的 那个中间文件了,厉害呀,佩服,对了,你从什么地方看到VI的实现的,能分享不,我发觉 我遇到的 好多问题 都和我 很肆无忌惮的使用VI有一定关系,遇到好几次了


谢谢~
   

QQ截图20130520203659.png (1.97 KB, 下载次数: 30)

/proc/111305/fd

/proc/111305/fd

论坛徽章:
4
白羊座
日期:2013-09-17 21:59:30技术图书徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40双子座
日期:2013-12-17 18:26:39
6 [报告]
发表于 2013-05-20 23:48 |只看该作者
回复 5# homerzhou
我没有看vim的实现,而是使用strace命令跟踪vim的系统调用。比如使用
  1. strace -f -o strace_vim.txt vim test.txt
复制代码
就可以将vim操作调用的系统调用输出到文件strace_vim.txt中


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP