免费注册 查看新帖 |

Chinaunix

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

[文件系统] O_DIRECT和OSYNC的区别和联系 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-31 11:48 |只看该作者 |倒序浏览
这几天在看QEMU后端的Disk Caching Model,不禁产生几个疑问,所以这里求助下坛子里的高手。

1)打开一个文件时如果加入了O_DIRECT标志位,意味着对该文件的读写操作将会绕过page cache,直接与存储设备打交道,但是这里不保证每次write返回后,该write要写入的数据已经写完。

2)如果是带O_SYNC标志位,则不绕过pape cache, 每次write的数据不仅会在page cache里写入,还会写入存储设备,并且,O_SYNC保证每次write返回后,数据都已经写入page cache和存储设备。

我的问题就是:3)如果打开一个文件同时带 O_DIRECT和O_SYNC两个标志位,A)会是什么效果?B)这个标志位的组合会和page cache打交道吗?C)存储设备的硬件缓存会感知到这两个标志位的语义吗?该存储硬件缓存会区别对待吗?

欢迎解答!!多谢!!!

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2013-10-31 12:53 |只看该作者
回复 1# almeydifer
大概看了下代码
write时,先判断O_DIRECT标记,所以先绕开缓存写,写完后会判断O_SYNC标记,如果有,则会调用
/*
         * Sync the fs metadata but not the minor inode changes and
         * of course not the data as we did direct DMA for the IO.
         * i_sem is held, which protects generic_osync_inode() from
         * livelocking.
         */
        if (written >= 0 && file->f_flags & O_SYNC)
                generic_osync_inode(inode, mapping, OSYNC_METADATA);
刷inode的“元数据”,这里只刷元数据,不刷数据。

   

论坛徽章:
0
3 [报告]
发表于 2013-10-31 13:49 |只看该作者
回复 2# humjb_1983


    谢谢您的回复!!是不是意味着O_DIRECT会忽视元数据和文件数据的顺序呢??

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
4 [报告]
发表于 2013-10-31 15:56 |只看该作者
almeydifer 发表于 2013-10-31 13:49
回复 2# humjb_1983

不是很明白你的意思??呵呵

论坛徽章:
0
5 [报告]
发表于 2013-10-31 17:14 |只看该作者
humjb_1983 发表于 2013-10-31 15:56
不是很明白你的意思??呵呵


就是在单独O_DIRECT标志位打开的情况下,write不能保证“先写常规数据然后再写元数据”的顺序,从而系统崩溃的时候,会可能导致不一致的情况?
从而O_DIRECT+O_SYNC就可以保证这个顺序??

我又想到一个问题:在开了O_SYNC或者O_DIRECT标志位的情况下,journal会发生作用么??

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
6 [报告]
发表于 2013-10-31 23:12 |只看该作者
回复 1# almeydifer


    Synchronous mode  -
           This flag affects only the write operation (read operatios are always blocking), which blocks the calling process until the data is effectively written to disk.

    Direct I/O mode -
          Any read or write operations transfers data directly from the User Mode address space to disk, or vise versa, by passing the page cache.
   
    依我的理解是, 设置O_sync 会影响的进程的行为(即是进程执行了IO请求后, 是否需要睡眠直到IO解释.). 而O_direct会影响的是数据流动的行为(是否会流动到page cache).

    当同时设置了O_sync和O_direct,  进程对文件进行写操作时, 数据将从ram直接写回到disk中, 同时因为设置了O_sync, 进程必须等待睡眠直到数据写到disk, IO结束才会唤醒.
    另外当你没有设置O_direct时, 数据一般会写到page cache就会表示“已经完成了IO”.

    这个是Virtual filesystem层的事情. 设置O_direct, 越过page cache, 只是从VFS层直接跳到mapping 层,而不需要经过page cache缓存. 下面还要经过generic block 层. IO scheculing层的转换, 最终才到设备驱动层执行真正的IO。所以我认为O_direct不会影响到物理设备.

论坛徽章:
0
7 [报告]
发表于 2013-11-01 09:33 |只看该作者
回复 6# kiongf

谢谢回复,感觉又明白了点!

另外:您觉得开了O_SYNC标志位后,类似与ext3的journal还会有用么?O_DIRECT标志位呢?


   

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
8 [报告]
发表于 2013-11-01 11:31 |只看该作者
回复 5# almeydifer
在通常的write中,实际是写的页缓存,页缓存通过周期性的flush(pdflush)或强制回写到磁盘,页缓存回写时,是通过sync_single_inode按inode来回写的,回写过程中会先调用do_writepages回写数据,然后再调用write_inode回写元数据,所以是有先后顺序的,通常也能保证一致性。

你说的journal是指kjournald线程吧,这个线程负责日志回写(5s一次),跟前面说的页缓存flush是独立的,应该还会正常运转。

   

论坛徽章:
0
9 [报告]
发表于 2013-11-04 10:35 |只看该作者
O_SYNC : 写完数据后(page cache或者direct io)等待数据刷到磁盘
O_DIRECT: 还是会有journal流程,以ext3为例,ext3_direct_IO里也有journal_start和jounral_stop对事务的封装
  1. size_t write_file()
  2. {
  3.    if (O_DIRECT)
  4.        direct_IO();
  5.    else
  6.        buffered_IO();

  7.   if (O_SYNC)
  8.        sync_data_wait();
  9. }
复制代码

论坛徽章:
0
10 [报告]
发表于 2013-11-05 18:24 |只看该作者
回复 9# chenyu105


    多谢回复啊,我很好奇不知道单独加入O_SYNC标志位是否就不会走journal流程了呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP