user space 只能通过系统调用来访问kernel提供的函数,下面以sys_read 为例
 sys_write函数声明在include/linux/syscalls.h文件中。这个文件中申明了linux kernel提供的所有系统调用
asmlinkage long sys_write(unsigned int fd, const char __user *buf, size_t count);
其函数实现在fs/read_write.c
SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
        size_t, count)
{
    //得到要操作的文件
    struct fd f = fdget_pos(fd);
    ssize_t ret = -EBADF;

if (f.file) {
        //需要写文件的位置
        loff_t pos = file_pos_read(f.file);
        //调用vfs 提供的写函数
        ret = vfs_write(f.file, buf, count, &pos);
        if (ret >= 0)
            file_pos_write(f.file, pos);
        fdput_pos(f);
    }

return ret;
}
在这个系统调用中调用vfs提供的写函数vfs_write,vfs_write 通过在fs/read_write.c 这个文件中实现。
ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
{
    ssize_t ret;

if (!(file->f_mode & FMODE_WRITE))
        return -EBADF;
    if (!(file->f_mode & FMODE_CAN_WRITE))
        return -EINVAL;
    if (unlikely(!access_ok(VERIFY_READ, buf, count)))
        return -EFAULT;

ret = rw_verify_area(WRITE, file, pos, count);
    if (!ret) {
        if (count > MAX_RW_COUNT)
            count =  MAX_RW_COUNT;
        file_start_write(file);
        ret = __vfs_write(file, buf, count, pos);
        if (ret > 0) {
            fsnotify_modify(file);
            add_wchar(current, ret);
        }
        inc_syscw(current);
        file_end_write(file);
    }

return ret;
}
vfs_write 中通过rw_verify_area 验证可以操作这个文件后,就调用__vfs_write开始写
ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
            loff_t *pos)
{
    if (file->f_op->write)
        return file->f_op->write(file, p, count, pos);
    else if (file->f_op->write_iter)
        return new_sync_write(file, p, count, pos);
    else
        return -EINVAL;
}
__vfs_write 这个函数中就调用具体文件系统的写函数,从可以可以看到优先调用file->f_op->write。
其中file->f_op是在调用文件系统注册的时候赋值的,这里以ext4 为例
const struct file_operations ext4_file_operations = {
    .llseek        = ext4_llseek,
    .read_iter    = generic_file_read_iter,
    .write_iter    = ext4_file_write_iter,
    .unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl    = ext4_compat_ioctl,
#endif
    .mmap        = ext4_file_mmap,
    .open        = ext4_file_open,
    .release    = ext4_release_file,
    .fsync        = ext4_sync_file,
    .get_unmapped_area = thp_get_unmapped_area,
    .splice_read    = generic_file_splice_read,
    .splice_write    = iter_file_splice_write,
    .fallocate    = ext4_fallocate,
};

这里的write是null,因此调用write_iter,也就是ext4_file_write_iter
ext4_file_write_iter->__generic_file_write_iter->generic_file_direct_write->filemap_write_and_wait_range->__filemap_fdatawrite_range->do_writepages->generic_writepages->write_cache_pages->__writepage->ext4_writepage->ext4_bio_write_page->io_submit_add_bh
可见最终的写操作还是在ext4 中实现,写操作由于不同的flag,走的flow有所不同,这里只是举例而已。
总结一下,user space 只能通过系统调用来调用kernel space 提供的接口函数。kernel space 对外通过vfs这个通用接口,各个文件系统自己实现read/write 接口,并把自己注册到文件系统的列表中.

系统调用sys_write的过程相关推荐

  1. Linux 系统调用的执行过程

    什么是系统调用 系统调用 (在 Linux 中常称为 syscalls ) 是应用程序访问硬件设备之间的桥梁. 系统调用层为用户空间提供一种硬件的抽象接口,使得用户不用关注设备的具体信息,同时系统调用 ...

  2. 1.3.3 系统调用(执行过程、访管指令、库函数与系统调用)

    文章目录 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 参考:<2021王道操作系统考研 ...

  3. Java程序员需要掌握的计算机底层知识(二):操作系统、内核、用户态与内核态、系统调用的执行过程

    操作系统 启动过程 通电 -> bios uefi 工作 -> 自检 -> 到硬盘固定位置加载bootloader -> 读取可配置信息 -> CMOS CMOS 用来存 ...

  4. 操作系统【用户接口】命令解释程序的主要功能、系统调用与一般过程调用的不同之处、系统调用的参数传递方式、系统调用的处理步骤

    操作系统 第九章 接口--用户接口   系统安全 命令解释程序:命令解释程序的主要功能: 系统调用:①系统调用与一般过程调用的不同之处②系统调用的参数传递方式③系统调用的处理步骤 命令解释程序的主要功 ...

  5. Linux内核分析(七)系统调用execve处理过程

    本文的内容包括: 1. 用execve系统调用加载和执行一个可执行程序的代码演示 2. 用gdb跟踪系统调用execve的执行过程 3. execve系统调用处理过程分析 一.如何用execve系统调 ...

  6. 操作系统原理,系统调用,系统调用与库函数API等函数之间的调用关系,功能与机制设计,系统调用的执行过程与Linux系统调用执行示例,不同操作系统下的PCB

    操作系统原理,系统调用,功能与机制设计,系统调用的执行过程与Linux系统调用执行示例,不同操作系统下的PCB 一.系统调用:操作系统功能调用,用户在编程时可以调用的操作系统功能. 1.系统调用是操作 ...

  7. 实验四:汇编代码调用系统调用的工作过程

    钟晶晶 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 工作过程 以41 ...

  8. Linux系统调用的运行过程【转】

    本文转自:http://blog.csdn.net/kernel_learner/article/details/7331505 在Linux中,系统调用是用户空间访问内核的唯一手段,它们是内核唯一的 ...

  9. 中断处理及系统调用的处理过程

    转载于:https://www.cnblogs.com/mwxjmmyjfm/archive/2010/11/19/1881870.html

最新文章

  1. Vue.js 源码目录设计(二)
  2. sqlmap绕过d盾_WEBSHELL免杀绕过WAF思路amp;方法(一)
  3. linux下vi修改文件用法
  4. tensorflow gpu安装_tensorflow-gpu安装配置
  5. DataGrid与SQL Server 2000数据绑定
  6. Java 日志管理最佳实践
  7. 更新CocoaPods1.1.0碰到的问题及知识点
  8. ProGuard:类混淆,类的指定函数保留
  9. Python--turtle.circle()参数说明
  10. java集成kettle教程(附示例代码)
  11. 经纬度坐标转像素坐标
  12. 以太坊之最全攻略解析与案例分享
  13. 【小技巧】利用matlab进行批量文件下载并解压
  14. 防火墙导致的VNC连接服务器超时10060错误问题解决
  15. 【paper 2】Learning from Simulated and Unsupervised Images through Adversarial Training
  16. Word文档恢复,电脑突然关机 如何一步步将.asd恢复为Word文档 (详解)
  17. 地标海之珠夜色素材高清图片
  18. 详细讲解Python遍历目录的文件夹(dir)、文件(file)的三种方法:os.listdir、os.walk和os.scandir
  19. 视频教程-怎么架构生产数据库--生产数据库优化的一种方式-MySQL
  20. 【日常】python站长素材网免费模板下载(以PPT模板为例)

热门文章

  1. AsyncTask解析、使用方法
  2. EDIUS是怎么制作倒影
  3. 浪漫婚礼相册-我们结婚啦PPT模板
  4. LINUX指令:查日志,查性能
  5. 用Win7自带的工具给硬盘分区与合并
  6. 【生活技能】如何洗白衣服
  7. 云应用开发之新浪SAE日志查看
  8. 应届生Java面试经验总结
  9. zynq实现视频动态字符叠加OSD,提供2套工程源码和技术支持
  10. 视频矩阵系统中三代OSD字符叠加技术全面解析