系统调用sys_write的过程
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的过程相关推荐
- Linux 系统调用的执行过程
什么是系统调用 系统调用 (在 Linux 中常称为 syscalls ) 是应用程序访问硬件设备之间的桥梁. 系统调用层为用户空间提供一种硬件的抽象接口,使得用户不用关注设备的具体信息,同时系统调用 ...
- 1.3.3 系统调用(执行过程、访管指令、库函数与系统调用)
文章目录 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 1.系统调用知识框架图 2.系统调用和库函数的区别 3.系统调用的执行过程 参考:<2021王道操作系统考研 ...
- Java程序员需要掌握的计算机底层知识(二):操作系统、内核、用户态与内核态、系统调用的执行过程
操作系统 启动过程 通电 -> bios uefi 工作 -> 自检 -> 到硬盘固定位置加载bootloader -> 读取可配置信息 -> CMOS CMOS 用来存 ...
- 操作系统【用户接口】命令解释程序的主要功能、系统调用与一般过程调用的不同之处、系统调用的参数传递方式、系统调用的处理步骤
操作系统 第九章 接口--用户接口 系统安全 命令解释程序:命令解释程序的主要功能: 系统调用:①系统调用与一般过程调用的不同之处②系统调用的参数传递方式③系统调用的处理步骤 命令解释程序的主要功 ...
- Linux内核分析(七)系统调用execve处理过程
本文的内容包括: 1. 用execve系统调用加载和执行一个可执行程序的代码演示 2. 用gdb跟踪系统调用execve的执行过程 3. execve系统调用处理过程分析 一.如何用execve系统调 ...
- 操作系统原理,系统调用,系统调用与库函数API等函数之间的调用关系,功能与机制设计,系统调用的执行过程与Linux系统调用执行示例,不同操作系统下的PCB
操作系统原理,系统调用,功能与机制设计,系统调用的执行过程与Linux系统调用执行示例,不同操作系统下的PCB 一.系统调用:操作系统功能调用,用户在编程时可以调用的操作系统功能. 1.系统调用是操作 ...
- 实验四:汇编代码调用系统调用的工作过程
钟晶晶 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 工作过程 以41 ...
- Linux系统调用的运行过程【转】
本文转自:http://blog.csdn.net/kernel_learner/article/details/7331505 在Linux中,系统调用是用户空间访问内核的唯一手段,它们是内核唯一的 ...
- 中断处理及系统调用的处理过程
转载于:https://www.cnblogs.com/mwxjmmyjfm/archive/2010/11/19/1881870.html
最新文章
- Vue.js 源码目录设计(二)
- sqlmap绕过d盾_WEBSHELL免杀绕过WAF思路amp;方法(一)
- linux下vi修改文件用法
- tensorflow gpu安装_tensorflow-gpu安装配置
- DataGrid与SQL Server 2000数据绑定
- Java 日志管理最佳实践
- 更新CocoaPods1.1.0碰到的问题及知识点
- ProGuard:类混淆,类的指定函数保留
- Python--turtle.circle()参数说明
- java集成kettle教程(附示例代码)
- 经纬度坐标转像素坐标
- 以太坊之最全攻略解析与案例分享
- 【小技巧】利用matlab进行批量文件下载并解压
- 防火墙导致的VNC连接服务器超时10060错误问题解决
- 【paper 2】Learning from Simulated and Unsupervised Images through Adversarial Training
- Word文档恢复,电脑突然关机 如何一步步将.asd恢复为Word文档 (详解)
- 地标海之珠夜色素材高清图片
- 详细讲解Python遍历目录的文件夹(dir)、文件(file)的三种方法:os.listdir、os.walk和os.scandir
- 视频教程-怎么架构生产数据库--生产数据库优化的一种方式-MySQL
- 【日常】python站长素材网免费模板下载(以PPT模板为例)