直接IO路径分析
来源:互联网 发布:qq游戏大厅mac版官方 编辑:程序博客网 时间:2024/04/30 04:00
直接IO路径
下图,是在O_DIRECT打开模式下,对文件进行进行读写的函数调用图。
函数generic_file_aio_read进行IO类型判别,如果是直接IO:
对块设备文件,会走blkdev_direct_IO分支,代码如下:
清单 1. 函数 blkdev_direct_IO()
static ssize_t
blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
loff_t offset, unsigned long nr_segs)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
return blockdev_direct_IO_no_locking_newtrunc(rw, iocb, inode,
I_BDEV(inode), iov, offset, nr_segs,
blkdev_get_blocks, NULL);
}
它只是简单取出文件对象和索引节点结构,索引节点同时是其地址空间的owner,然后,调用blockdev_direct_IO_no_locking_newtrunc. 而blockdev_direct_IO_no_locking_newtrunc只是一个封装函数,它立即调用 __blockdev_direct_IO_newtrunc.
清单 2 函数 blkdev_direct_IO_no_locking_newtrunc()
static inline ssize_t blockdev_direct_IO_no_locking_newtrunc(int rw, struct kiocb *iocb,
struct inode *inode, struct block_device *bdev, const struct iovec *iov,
loff_t offset, unsigned long nr_segs, get_block_t get_block,
dio_iodone_t end_io)
{
return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
nr_segs, get_block, end_io, NULL, 0);
}
对普通文件,会走blockdev_direct_IO_newtrunc,代码如下:
清单 2 函数 blkdev_direct_IO_newtrunc()
static inline ssize_t blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb,
struct inode *inode, struct block_device *bdev, const struct iovec *iov,
loff_t offset, unsigned long nr_segs, get_block_t get_block,
dio_iodone_t end_io)
{
return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
nr_segs, get_block, end_io, NULL,
DIO_LOCKING | DIO_SKIP_HOLES);
}
到这一步可以看出,对普通文件和块设备文件的直接IO,到最后都会调用__blockdev_direct_IO_newtrunc,其差别在于有没加锁,可以看它的最后一个参数是不同的,即对普通文件的DIO要加锁,避免多个进程在同一时刻对文件写,而块设备文件则没有加以限制,而是交由底层的设备驱动进行处理,底层的写操作会以串行方式执行。
__blockdev_direct_IO_newtrunc函数,代码如下,主要完成这样几个任务
1)检查各个段的内存边界,不能出现跨页的段
2)检查,如果有锁,即是对普通文件的DIO,则调用filemap_write_and_wait_range,将相应位置可能存在的page cache废弃掉或刷回磁盘(避免产生不一致),然后调用direct_io_worker来处理请求
清单 3 函数 __blkdev_direct_IO_newtrunc()
ssize_t
__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, const struct iovec *iov, loff_t offset,
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
dio_submit_t submit_io, int flags)
{
if (dio->flags & DIO_LOCKING) {
...
mutex_lock(&inode->i_mutex);
retval=filemap_write_and_wait_range(mapping,offset, end-1);
...
}
retval = direct_io_worker(rw, iocb, inode, iov, offset,nr_segs, blkbits, get_block,
end_io, submit_io, dio);
...
}
direct_io_worker,一次可能包含多个读操作,对于其中的每一个,调用do_direct_IO.
- 直接IO路径分析
- java.io.File的路径获取方式分析
- 磁盘IO:缓存IO与直接IO
- linux 直接IO机制
- linux 直接IO机制
- ORACLE直接路径操作
- Oracle 直接路径读
- Oracle直接路径加载
- ORACLE直接路径操作
- 直接路径插入
- io分析
- 理解redo(6)日志却的流程和直接路径加载的REDO分析
- java IO 文件路径
- [IO]——路径
- iO文件路径问题
- 直接IO模拟键盘源代码
- 使用WinIo直接访问IO
- 使用WinIo直接访问IO
- startActivityForResult( )与startActivity( )的不同之处
- unity3d事件函数整理,事件,回调函数,消息处理
- 效果超酷的textarea的输入字数限制及提示
- 修改DOS窗口编码格式
- 学习c++及c++用途
- 直接IO路径分析
- HTML5 vedio标签与canvas的结合实现视频同步模糊效果
- 多线程的那点儿事(基础篇)
- 企业网站SEO方案的制作流程和步骤
- [置顶]深入浅出---unix多进程编程之wait()和waitpid()函数
- JavaScript window.setTimeout() 的详细用法
- QTester Web自动化测试利器
- Asp.net错误“System.Web.HttpException: 超过了最大请求长度”解决办法
- 在 SQL Server 2008 中新建用户登录并指定该用户的数据库