免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5105 | 回复: 12

[文件系统] 关于文件读写互斥的问题 [复制链接]

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-03-15 22:53:29
发表于 2014-11-21 17:41 |显示全部楼层
各位好,版主好,请教大家一个问题:
===============================================================
一方面,在xfs文件系统的读操作回调函数filp->f_op->aio_read,即函数xfs_file_aio_read()中
有下面的代码:
        xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
        …………………………
        ret = generic_file_aio_read(iocb, iovp, nr_segs, iocb->ki_pos);
        …………………………
        xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);

个人的理解是为了对进程读文件操作和写文件操作进行互斥。


另一方面,page cache具有PG_locked和PG_writeback标志,也具有互斥作用。


问题是:
(1) 如果不考虑DIRECT IO,利用page cache的PG_locked和PG_writeback标志就可以做到
   进程在VFS层对page cache的读操作和写操作、块层将page cache回写到磁盘和从磁盘
   读数据到page cache这些操作的互斥,上面的xfs_rw_ilock是否是多余的。
(2) 包括ext4在内的很多文件系统的filp->f_op->aio_read回调函数实际上就是函数
    generic_file_aio_read(),它为什么没有类似xfs文件系统的xfs_rw_ilock()。
    那么如何保证对进程读文件操作和写文件操作进行互斥。
       

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
发表于 2014-11-21 19:36 |显示全部楼层
本帖最后由 镇水铁牛 于 2014-11-21 19:37 编辑

看了xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);的实现是个读写锁,对xfs不熟,谈谈我的观点。
如果xfs对于数据一致性要求很高的话,假设这种场景:
当用户态的IO要写page前,会调用generic_file_buffered_write,调用它前page还未被lock。
但此时系统同时下发一个读同地址的数据的IO请求,有可能就从磁盘上或cache中返回了,数据无法保持一致性,虽然这种概率是很低的。
所以用个读写锁搞定inode,是最保险的,对于读多写少的场景,性能应该还可以。

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-03-15 22:53:29
发表于 2014-11-22 11:49 |显示全部楼层
本帖最后由 yangPSO 于 2014-11-22 11:57 编辑

回复 2# 镇水铁牛

想了想,page cache的PG_locked和PG_writeback标志确实无法保证进程对
page cache的读操作和写操作的互斥。实际上内核代码并不保证这种互斥,
像ext4就没有提供这种保护,而xfs提供了。但是如果考虑到mmap的情况,
这种互斥根本没法保证。这需要用户态应用程序通过文件锁或者其它措施
来保证。不知道说的对不对?一次read或者write系统调用到底有没有原子性?

另外说到mmap,会不会出现底层磁盘驱动正在以DMA的方式将page cache中
数据写往磁盘,与此同时,用户态应用程序正在通过 memcpy方式修改page cache?
如果会出现这种情况,会带来什么影响?


   

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
发表于 2014-11-22 19:01 |显示全部楼层
另外说到mmap,会不会出现底层磁盘驱动正在以DMA的方式将page cache中数据写往磁盘,与此同时,用户态应用程序正在通过 memcpy方式修改page cache?如果会出现这种情况,会带来什么影响?
【回答】当磁盘输出从page cache往磁盘DMA方式写入时,此时page是write back状态,bh是被lock的,此时上层的应用是不能修改page中的数据的;
系统也有类似wait_on_page_writeback(page);的保障的。

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-03-15 22:53:29
发表于 2014-11-22 20:02 |显示全部楼层
本帖最后由 yangPSO 于 2014-11-22 20:18 编辑

回复 4# 镇水铁牛

【以linux-2.32为例】
个人理解:

xfs文件系统在回写某个page cache到块层时设置了page cache的PG_writeback标志,然后释放了PG_locked标志,具体来说就是:
通过如下的函数关系
mapping->a_ops->writepages(mapping, wbc);
xfs_vm_writepages
generic_writepages
write_cache_pages
调用到函数write_cache_pages(),其中包含如下的代码:
  1. while (!done && (index <= end)) {
  2.                 int i;

  3.                 nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
  4.                               min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
  5.                 if (nr_pages == 0)
  6.                         break;

  7.                 for (i = 0; i < nr_pages; i++) {
  8.                         struct page *page = pvec.pages[i];
  9.                         ..................

  10.                         lock_page(page);
  11.                         ..................
  12.                         if (PageWriteback(page)) {
  13.                                 if (wbc->sync_mode != WB_SYNC_NONE)
  14.                                         wait_on_page_writeback(page);
  15.                                 else
  16.                                         goto continue_unlock;
  17.                         }

  18.                         BUG_ON(PageWriteback(page));
  19.                         ..................
  20.                         ret = (*writepage)(page, wbc, data);
  21.                         ..................
  22.         }
复制代码
对于每个待写(刷新)的page cache,首先调用函数lock_page()进行加锁,如果page正在回写过程中并且wbc->sync_mode为WB_SYNC_NONE,
将调用函数wait_on_page_writeback()等待回写过程结束。然后调用writepage回调函数,即函数xfs_vm_writepage()执行写操作。
同时,函数xfs_vm_writepage()通过如下的函数关系
   xfs_vm_writepage
    xfs_start_page_writeback
   set_page_writeback
   test_set_page_writeback
   ret = TestSetPageWriteback(page);
设置page的PG_writeback标志,表明page处于回写过程中。
同时,函数xfs_start_page_writeback()在设置完page的PG_writeback标志后将调用函数unlock_page()将page解锁,在解锁前一刻将page设置为Uptodate的。

那么某个进程就可能在在该page cache 的PG_locked标志释放后成功设置其PG_locked标志后去写这个page cache,而该page cache可能正在以DMA的方式将page cache中数据写往磁盘。
进程写page cache并不需要判断PG_writeback标志,只会判断PG_locked标志。

另外mmap方式写内存根本不执行系统调用,更不会判断什么锁状态。

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
发表于 2014-11-22 20:26 |显示全部楼层
回复 5# yangPSO
    文件系统在回写某个page cache到块层时设置了page cache的PG_writeback标志,然后释放了PG_locked标志是对的,在IO写操作的整个流程中,在两个地方会对page进行lock操作,一个是标脏(prepare write附近),一个是set writeback(过滤dirty page并准备submit)那里。
    但是page lock这个锁粒度太大,而且灵活性不足,可以看看buffer head的lock,io提交就是基于bio的,这个锁就十分灵活。


   

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-03-15 22:53:29
发表于 2014-11-22 20:57 |显示全部楼层
回复 6# 镇水铁牛


    我在函数generic_perform_write()看不到lock_buffer()。
   lock_buffer()是不是只对回写同一个page cache的不同上下文起到互斥作用,但是进程从系统调用写page  cache不受它的影响啊
   像mmap方式只是memcpy写page cache,没有进入内核,根本没有什么锁啊。

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
发表于 2014-11-22 20:59 |显示全部楼层
本帖最后由 镇水铁牛 于 2014-11-22 21:00 编辑

另外mmap方式写内存根本不执行系统调用,更不会判断什么锁状态。
【回复】
         没使用过mmap,但mmap是映射磁盘上的文件,也就是说它应该是把磁盘上的文件映射到进程的某段vma中。
         对该地址空间的访问,和访问真实文件是一样的,
如果是读操作,通过访问fd对应的struct file,对磁盘上的文件进行操作,我感觉mmap和普通vfs接口好像没啥大的差别(不知道mmap函数返回的地址有没有分配实际物理内存)。               
如果是写的话,mmap写的是进程用户态的虚拟地址,在内核可以通过该虚拟地址找到其物理页框,然后进行数据拷贝,这个好像和direct io很相似,那mmap和mmap间应该能保证互斥,如果此时如果有别的vfs入口访问该文件,好像还真的无法保证数据一致性了。
    这些是我的猜测哈。

论坛徽章:
1
15-16赛季CBA联赛之北控
日期:2016-03-15 22:53:29
发表于 2014-11-22 21:14 |显示全部楼层
本帖最后由 yangPSO 于 2014-11-22 21:17 编辑

回复 8# 镇水铁牛



如果暂时不考虑mmap,常规的写分2步,首先是系统调用写page  cache,然后在之后某个时刻将page  cache回写。
lock_buffer()是不是只对回写同一个page cache的不同路径起到互斥作用,而进程从系统调用写page  cache不受它的影响,
也就是说,lock_buffer()做不到回写page cache和系统调用写page  cache的互斥???


   

论坛徽章:
2
寅虎
日期:2014-11-25 21:47:342015小元宵徽章
日期:2015-03-06 15:58:18
发表于 2014-11-22 21:35 |显示全部楼层
你可以细看下__block_write_full_page。这里搞成双簧了哈,  刷屏实在是不好啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP