最近在看write系统调用的实现,虽然还有一下细节不是很清楚,但是大致的实现机理还是有一定的理解了。总结如下:

这里假设最普通的情况,不考虑Direct IO 的情况。从全家的高度看,要往一个文件中写入内容,需要一下几步。

1. sys_write 将用户进程要写的内容写入到内核的文件页面缓冲中。sys_write 本身到此就结束了。

2. pdflush 内核线程(定期或者由内核阈值触发)刷新脏的页面缓冲,其实只是提交IO请求给底层的驱动。

3. IO请求并不是同步执行的,而是由底层的驱动调度执行,发出DMA操作指令。

4. 物理IO完成之后会中断并通知内核,内核负责更新IO的状态。

先要去陪儿子睡觉了。有空会继续细化各个部分的实现。

sys_write 的调用过程。(我的linux内核版本为2.6.24,文件系统为ext3)

asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)

vfs_write(file, buf, count, &pos);

file->f_op->write(file, buf, count, pos);

这里的file->fop 是在open一个文件是初始化的函数指针,ext3文件系统对应的函数为do_sync_write。

下面是其实现的要点。

for (;;) {

300                 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);

301                 if (ret != -EIOCBRETRY)

302                         break;

303                 wait_on_retry_sync_kiocb(&kiocb);

304         }

305

306         if (-EIOCBQUEUED == ret)

307                 ret = wait_on_sync_kiocb(&kiocb);

filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); 是实现的核心,其函数指针指向ext3_file_write。

307行的作用在于等待IO的完成。这里的IO完成指的是进入IO的队列而已,不是物理IO的完成。

generic_file_aio_write(iocb, iov, nr_segs, pos);

__generic_file_aio_write_nolock(iocb, iov, nr_segs,  &iocb->ki_pos);

generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);

generic_file_buffered_write(iocb, iov, nr_segs, pos,ppos,count,written);

generic_file_direct_IO(WRITE, iocb, iov, pos, *nr_segs);

以下的调用序列还很长,一时还消化不了。仅供自己参考。

posted on 2008-06-02 21:43 InPractice 阅读(2385) 评论(0)  编辑  收藏

linux实现自己的write函数,Linux 内核源码阅读 - write 系统调用的实现相关推荐

  1. 【转载】ubuntu下linux内核源码阅读工具和调试方法总结

    http://blog.chinaunix.net/space.php?uid=20940095&do=blog&cuid=2377369 一 linux内核源码阅读工具 window ...

  2. Linux内核源码阅读以及工具(转)

    Linux内核源码阅读以及工具(转) 转载地址:Linux内核源码阅读以及工具(转)

  3. linux内核第一个函数,通过内核源码看函数调用之前世今生 - 极光 - CSDN博客

    通过内核源码看函数调用之前世今生 作者:杨小华 栈(Stack):一个有序的积累或堆积 韦氏词典 对每一位孜孜不倦的程序员来说,栈已深深的烙在其脑海中,甚至已经发生变异.栈可以用来传递函数参数.存储局 ...

  4. Linux内核源码阅读以及工具详解

    接上篇Linux内核源码下载方法 这篇总结了如何利用source insight对Linux内核代码进行阅读和学习(资料来源于网络) 随着linux的逐步普及,现在有不少人对于Linux的安装及设置已 ...

  5. linux/usr/src/kernels 目录下没有内核源码 解决方法

    有时我们在安装系统后,发现没有安装当前系统的内核源码在/usr/src/kernels目录下,其实我们是少安装了一个rpm包: 当你配置好yum源后,然后安装下面的包就可以了: 针对CentOS系统: ...

  6. Linux内核剖析-----IO复用函数epoll内核源码剖析

    本文参考董浩博客 http://donghao.org/uii/   epoll内核实现 (1)内核为epoll做准备工作 这个模块在内核初始化时(操作系统启动)注册了一个新的文件系统,叫" ...

  7. Linux内核源码阅读之打开文件篇

    Linux中打开文件是通过open系统调用实现,其函数中调用了do_sys_open()函数完成打开功能,所以下面主要分析do_sys_open()函数,首先先看下open系统调用的入口函数,再具体看 ...

  8. trim函数 php,[PHP源码阅读]trim、rtrim、ltrim函数

    trim系列函数是用于去除字符串中首尾的空格或其他字符.ltrim函数只去除掉字符串首部的字符,rtrim函数只去除字符串尾部的字符. 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下 ...

  9. PHP内核源码阅读过程(四)

    这次来讲讲 zend_startup int zend_startup(zend_utility_functions *utility_functions, char **extensions) 其第 ...

最新文章

  1. ios游戏开发 Sprite Kit教程:初学者 2
  2. YOLOv2/YOLO9000 《YOLO9000: Better, Faster, Stronger》论文笔记
  3. FreeNOS源码编译
  4. python色标_在Python中用色标可视化移动速度
  5. Extjs 之 initComponent 和 constructor的区别(转)
  6. 当遇到用\来分隔字符串
  7. 漫步数学分析番外六(上)
  8. 剑指offer面试题[41]-和为s的两个数VS和为s的连续正数序列
  9. [VB.NET]各们,请问如何使用vb.net编写两个进程间消息通信的程序啊
  10. 数据预处理:中英文印刷字体图片分类数据集生成
  11. freeSHHd+puttygen搭建Sftp
  12. 计算机主机放电,电脑需要放电才能开机_电脑主板放电才能开机
  13. 一文学会如何使用Java的交互式编程环境 JShell
  14. c语言数组作业题,数组练习题
  15. android壁纸背景,android – 选择动态壁纸的背景
  16. 筋膜枪方案-无刷马达方波运用1
  17. amap不同样式marker点_高德地图markers生成和点击
  18. 2022-2028年全球厨房炉灶行业供需分析及发展前景研究报告
  19. PaddlePaddle第二周学习笔记
  20. 不想将就,所以竭尽所能。

热门文章

  1. 基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试
  2. mybatis resultMap type属性问题 ( xx.xx.PO cannot be cast to xx.xx.BO)
  3. Excel VBA Sql 操作Access数据库
  4. css-背景图片和渐变
  5. SQL敲了mySQL变了_MySQL-Front肿么导出SQL文件
  6. java职业发展路线图_软开(Java),该如何规划职业路线?
  7. R语言对数线性模型loglm函数_R 对数变换 《回归分析与线性统计模型》page103
  8. ifix虚拟服务器,ifix的客户端和服务器
  9. psp中java,PSP编程概述
  10. Python map 函数 -Python零基础入门教程