转自:http://blog.chinaunix.net/uid-28362602-id-3425881.html

目录

用户空间的write函数在内核里面的服务例程为sys_write

Vfs_write函数实现原理

WORD里面的目录复制过来似乎不能直接用。。还是放在这里当主线看吧..

用户空间的write函数在内核里面的服务例程为sys_write

root@syslab ~]# grep write /usr/include/asm/unistd_64.h

#define __NR_write                              1

__SYSCALL(__NR_write, sys_write)

#define __NR_pwrite64                           18

__SYSCALL(__NR_pwrite64, sys_pwrite64)

#define __NR_writev                             20

__SYSCALL(__NR_writev, sys_writev)

#define __NR_pwritev                            296

__SYSCALL(__NR_pwritev, sys_pwritev)

#define __NR_process_vm_writev                  311

__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)

这里根据经验判断,通常write调用应该是sys_write,这里我们讨论sys_write函数的内核实现

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,size_t, count)

{

{//这里SYSCALL_DEFINE3 write到sys_write的转换请参看前面的文章Linux 编程中的API函数和系统调用的关系

//这里unsigned int fd表示用户空间的文件描述符

//char __user *buf是存放从文件读取内容的一个用户空间内存区

struct file *file;

ssize_t ret = -EBADF;

int fput_needed;

file = fget_light(fd, &fput_needed);

if (file) {

loff_t pos = file_pos_read(file);

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

file_pos_write(file, pos);

fput_light(file, fput_needed);

}

return ret;

}

可以看到,和sys_read系统调用不同的地方就是这里调用了vfs_write函数来完成写操作,所以这里我们只看vfs_write都做了什么,其余部分请参看Linux 中read系统调用实现原理

Vfs_write函数实现原理

ssize_t  vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)

即把用户空间的char __user* buf指向的内存地址里面的内容写入相应的设备文件

基本同vfs_read,不过这里变成了

如果文件系统没有实现file_operation或者既没有实现file_operation->write,也没有实现file_operation->aio_write,则报错。(即文件系统即没有实现同步写,也没有实现异步写,那就报错返回错误了)

如果文件系统实现了file->file_operation->write(还记得我吗在open系统调用中讲到的吗,在open系统调用中file->file_operation设置为了inode->file_operation)函数,则调用它来完成。

否则(说明文件系统没有实现write,但是实现了file_operation->aio_write)调用内核的默认函数do_sync_write(file, buf, count, pos);来做同步读写操作;而内核的do_sync_write函数内部实现是

ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos){

struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };

for (;;) {

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

if (ret != -EIOCBRETRY)

break;

wait_on_retry_sync_kiocb(&kiocb);

}

}

这里和do_sync_read不同在于基本也就aio_read换成了aio_write了,do_sync_write最后调用的是file_operation->aio_write方法,但是iov数组长度为1,并且写入过程中如果写入操作没有完成则显式调用进程调度函数,本进程可能被挂起来且进程状态为TASK_UNINTERRUPTIBLE。直到最终写入完成,读取成功后进程状态会变为TASK_RUNNING,且存放在用户空间的buf内存区的内容已经写入硬件上为止

具体请参看Linux 中read系统调用实现原理

Linux VFS中write系统调用实现原理【转】的更多相关文章

  1. Linux 中open系统调用实现原理【转】

    转自:http://blog.chinaunix.net/uid-25968088-id-3426026.html 目录 OPEN系统调用过程 Open在内核里面的入口函数时sys_open Sys_ ...

  2. 在Linux内核中添加系统调用,并编译内核

    1 环境准备 运行系统:vmware下安装的ubuntu10.10 32bit桌面版. 编译内核版本: linux-2.6.32.63 内核目录: /home/wanchouchou/linuxKer ...

  3. ARM Linux系统调用的原理

    转载自:http://blog.csdn.net/hongjiujing/article/details/6831192 ARM Linux系统调用的原理 操作系统为在用户态运行的进程与硬件设备进行交 ...

  4. Linux系统调用(syscall)原理(转)

    引言:分析Android源码的过程中,要想从上至下完全明白一行代码,往往涉及app.framework.native一直到kernel,可能迷失到代码世界,明白了系统调用原理,或许能帮你峰回路转,找到 ...

  5. Linux 编程中的API函数和系统调用的关系【转】

    转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号 API: ...

  6. 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程

    GDB的那些奇淫技巧 evilpan 收录于 Security  2020-09-13  约 5433 字   预计阅读 11 分钟  709 次阅读  gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...

  7. Linux下缓冲区溢出攻击的原理及对策(转载)

    前言 从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用.当函数调用发生时,新的堆栈帧被压入堆栈:当函数返回时,相应的堆栈帧从堆栈中弹出.尽管堆栈帧结构的引入为在高级语言中实现 ...

  8. linux VFS 内核数据结构

    <strong>简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp.</strong> 文件描述 ...

  9. 【转】在linux内核中读写文件 -- 不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8194276 1. 序曲 在用户态,读写文件可以通过read和write这两个系统调用来完成 ...

随机推荐

  1. 【android studio】android studio使用过程中,搜集的一些问题

    1.[知乎]在Android Studio中如何将依赖的jar包放在SDK的android.jar前? 在编译原生Contacts应用时需用到非公开的API,需要引入framework等jar包,但在 ...

  2. Qt Load and Save PCL/PLY 加载和保存点云

    Qt可以跟VTK和PCL等其他库联合使用,十分强大,下面的代码展示了如何使用Qt联合PCL库来加载和保存PCL/PLY格式的点云: 通过按钮加载点云: void QMainWindow::on_pb_ ...

  3. java web(四)文件上传与下载

     一.文件上传原理 1.在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制:但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定. 通 ...

  4. HDU1051 贪心

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. 单页Web应用:

    概念: Web应用程序: WEB应用程序一般是B(浏览器)/S(服务器)模式.Web应用程序首先是“应用程序”,和用标准的程序语言,如C.C++等编写出来的程序没有什么本质上的不同.然而Web应用程序 ...

  6. C/C++中的实参和形参

    今天突然看到一道关于形参和实参的题,我居然不求甚解.藐视过去在我的脑海里只有一个参数的概念,对于形参和实参的区别还真的不知道,作为学习了几年C++的人来说,真的深深感觉对不起自己对不起C++老师  T ...

  7. 队列的C++实现(数组)——创建-进队-出队-返回队首元素-清空队列栈-处理队列

    队列的数组实现,从队尾进入,对头删除. 队列长度用标志变量size,它是独立于front和rear的一个变量.size == 0,队列为空.size == capacity,满队列. 一.结点声明 s ...

  8. css3 animation 实现环形路径平移动画

    注意 @keyframes to/from 的学习 <!DOCTYPE html> <html lang="en"> <head> <me ...

  9. ubuntu安装Python环境以及科学计算环境

    参考:http://blog.csdn.net/a1311543690/article/details/ 1.sudo apt-get install python-pip pip是Python的一个 ...

  10. Bootstrap css栅格 + 网页中插入代码+css表格

    设计达人 http://www.shejidaren.com/30-minimal-app-icons.html CSS栅格: <!DOCTYPE html> <html lang= ...