免费注册 查看新帖 |

Chinaunix

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

系统调用close如何更新文件的属性和数据 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-04 20:42 |只看该作者 |倒序浏览
我们经常说close(fd)系统调用执行完毕后,文件的数据都会写到硬盘上。
但是通过分析2.4.0的sys_close()代码(fs/open.c),发现两个问题:
1、inode对应的ext2_inode没有同步写回磁盘;
2、文件的脏的缓冲区即inode->i_dirty_buffers中的缓冲区没有同步写回磁盘。

sys_close()的调用流程:
-->filp_close()
       -->fput()
              (如果--file->f_count == 0)
              -->dput()
                     (如果--dentry->d_count==0)并且(list_empty(&dentry->d_hash为真)
                     -->dentry_iput()  
                            -->iput()
                                   (可能是,我不太确定)
                                   -->clear_inode()
                                          -->invalidate_inode_buffers()
下面的就不写了。其中invalidate_inode_buffers()只是将inode->i_dirty_buffers指向的链表中的每一项从该链表中删除,并没有将脏的缓冲区立即写到硬盘上。

是不是我遗漏了什么?要不然两个问题如何解释?

论坛徽章:
0
2 [报告]
发表于 2010-08-05 09:48 |只看该作者
1145 int filp_close(struct file *filp, fl_owner_t id)
  1146 {
  1147     int retval = 0;
  1148
  1149     if (!file_count(filp)) {
  1150         printk(KERN_ERR "VFS: Close: file count is 0\n");
  1151         return 0;
  1152     }
  1153
  1154     if (filp->f_op && filp->f_op->flush)
  1155         retval = filp->f_op->flush(filp, id);
  1156
  1157     dnotify_flush(filp, id);
  1158     locks_remove_posix(filp, id);
  1159     fput(filp);
  1160     return retval;
  1161 }

第1155行调用flush,不就是把数据同步到硬盘吗?

论坛徽章:
0
3 [报告]
发表于 2010-08-06 09:33 |只看该作者
fs/ext2/file.c

59 /*
60  * We have mostly NULL's here: the current defaults are ok for
61  * the ext2 filesystem.
62  */
63 const struct file_operations ext2_file_operations = {
64     .llseek     = generic_file_llseek,
65     .read       = do_sync_read,
66     .write      = do_sync_write,
67     .aio_read   = generic_file_aio_read,
68     .aio_write  = generic_file_aio_write,
69     .unlocked_ioctl = ext2_ioctl,
70 #ifdef CONFIG_COMPAT
71     .compat_ioctl   = ext2_compat_ioctl,
72 #endif
73     .mmap       = generic_file_mmap,
74     .open       = dquot_file_open,
75     .release    = ext2_release_file,
76     .fsync      = ext2_fsync,
77     .splice_read    = generic_file_splice_read,
78     .splice_write   = generic_file_splice_write,
79 };

由此看filp->f_op->flush==NULL。

论坛徽章:
0
4 [报告]
发表于 2010-08-06 15:31 |只看该作者
应该write back模式,是不保证写入磁盘的

否则,fsync等是不是就没意义了
man close
A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a filesystem to flush the buffers when the stream is closed. If you need to be sure that the data is physically stored use fsync(2). (It will depend on the disk hardware at this point.)

回复 1# panweiping

论坛徽章:
0
5 [报告]
发表于 2010-08-09 22:08 |只看该作者
我觉得楼上的解释是正确的。
首先"close(fd)系统调用执行完毕后,文件的数据都会写到硬盘上"这种说法是不准确的。
因为我们一般是在程序里close(fd),然后用cat查看文件,其实此时cat得到的数据未必是磁盘上的,也可能是缓冲区中的。

顺便分析了以下2.4.0的sys_fsync()代码。
sys_fsync
   -->filemap_fdatasync
          -->ext2_writepage
                 -->__block_write_full_page
                       -->submit_bh
  -->ext2_sync_file
         -->fsync_inode_buffers
                -->ll_rw_block
                -->o_sync_inode_buffers
         -->ext2_sync_inode
                -->ext2_update_inode

这样,刷新缓冲区和更新inode都完成了。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP