Linux 内核源码阅读 - write 系统调用的实现

Linux 内核源码阅读 - write 系统调用的实现

最近在看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);

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

你可能感兴趣的:(Linux 内核源码阅读 - write 系统调用的实现)