Linux源码阅读笔记16-文件系统关联及字符设备操作

简介: Linux源码阅读笔记16-文件系统关联及字符设备操作

文件系统关联

设备文件都是由标准函数处理,类似普通文件。设备文件也是通过虚拟文件系统来管理的,和普通文件都是通过完全相同的接口访问的。

inode中设备文件的成员数据

  • 虚拟文件系统每个文件都关联到一个inode,用于管理文件的属性。源码如下:

  • 唯一地标识与一个设备文件关联的设备,内核在i_mode中存储文件类型(面向块,面向字符),而且在i_rdev中存储主从设备号。主从设备号在内核中合并为一种变量类型为dev*_t
  • 在内核开发当中认为必要的时候会进行修改,只应该使用两个函数imajoriminor来从i_rdev提取主设备号和从设备号,这两个函数都只需要一个指向inode实例的指针作为参数。
  • const struct file_operations* i_fop是一组函数指针的集合,包括许多文件操作(打开,读取,写入等等),这些由虚拟文件系统使用来处理块设备。内核会根据inode表示块设备还是字符设备,使用i_bdevi_cdev指向更具体的信息。
  • 实际上,inodeVFS使用的一个现象,用于存放内核在操作文件或目录时所需要的全部信息。索引节点有两种:一种是VFS节点,存在内核中;另一种具体文件系统的索引节点,存在磁盘当中,使用时将其读入内存填充VFS节点,之后对VFS索引节点的任何修改都将写回磁盘和磁盘的索引节点。

标准文件操作

在打开一个设备文件时,各种文件系统的实现基本都会调用init_special_inode函数,为块设备或字符设备创建一个inode。具体源码如下:

void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
{
  inode->i_mode = mode;
  if (S_ISCHR(mode)) {
    inode->i_fop = &def_chr_fops;
    inode->i_rdev = rdev;
  } else if (S_ISBLK(mode)) {
    inode->i_fop = &def_blk_fops;
    inode->i_rdev = rdev;
  } else if (S_ISFIFO(mode))
    inode->i_fop = &pipefifo_fops;
  else if (S_ISSOCK(mode))
    ; /* leave it no_open_fops */
  else
    printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
          " inode %s:%lu\n", mode, inode->i_sb->s_id,
          inode->i_ino);
}
EXPORT_SYMBOL(init_special_inode);
  • 除了通过mode传递进来的设备类型之外,底层文件系统还必须返回主从设备号。代码中会根据设备类型,向inode提供不同的文件操作。

字符设备标准操作

每个设备文件都需要一组独立、自定义操作。具体源码如下:

/*
 * Dummy default file-operations: the only thing this does
 * is contain the open that then fills in the correct operations
 * depending on the special file...
 */
const struct file_operations def_chr_fops = {
  .open = chrdev_open,
  .llseek = noop_llseek,
};

块设备标准操作

与自负设备相比,块设备操作的指针会集中到一个叫做blk_fops通用的结构体。具体源码如下:

const struct file_operations def_blk_fops = {
  .open   = blkdev_open,
  .release  = blkdev_close,
  .llseek   = block_llseek,
  .read_iter  = blkdev_read_iter,
  .write_iter = blkdev_write_iter,
  .iopoll   = blkdev_iopoll,
  .mmap   = generic_file_mmap,
  .fsync    = blkdev_fsync,
  .unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
  .compat_ioctl = compat_blkdev_ioctl,
#endif
  .splice_read  = generic_file_splice_read,
  .splice_write = iter_file_splice_write,
  .fallocate  = blkdev_fallocate,
};

字符设备操作

前面说到过,字符设备是由struct cdev表示,同时内核维护一个数据库,包括所有活动的cdev实例。

表示字符设备具体源码如下

打开设备文件

通过chrdev_open打开字符设备的通用函数。具体源码如下:

  • 假设表示设备文件的inode没有被打开过,根据给出的设备编号,kobject_lookup查询字符设备的数据库并返回与该驱动程序关联的kobject实例,返回值可用于获取cdev实例。

  • 获得对应设备的cdev实例,内核通过cdev->ops还可以访问特定于设备的file_operations。接下来我们就设备的各种数据结构之间的关联关系如下图所示:

读写操作

读写字符设备文件,其实虚拟文件和设备驱动程序代码之间已建立关联。调用标准库的读写操作,向内核发出一些系统调用,最终会调用file_operations结构体中的相关操作(重点是read和write)。只需要调用内核函数来完成操作,具体源码如下:

相关文章
|
1月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
112 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
3天前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
38 8
|
6天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
30 5
|
9天前
|
存储 Linux 文件存储
Linux文件系统
Linux文件系统 一切皆文件 在Linux中,“一切皆文件”的概念意味着系统中的所有资源,包括硬件设备、目录及进程等,均被视为文件。这种设计简化了操作和管理,具体包括: 普通文件:存储数据的常规文件。 目录文件:包含其他文件和子目录的文件。 进程文件:在/proc目录下代表系统中运行的进程。 设备文件:位于/dev目录,代表硬件设备。 网络字节流套接字文件:用于网络通信的数据流。 链接文件:指向另一个文件的符号链接或硬链接。 管道文件:用于进程间通信的文件。
40 7
|
22天前
|
Linux 开发工具 Perl
Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
【10月更文挑战第20天】Linux命令替换目录下所有文件里有"\n"的字符为""如何操作?
34 4
|
29天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
81 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
存储 Linux 索引
Linux 下最主流的文件系统格式——ext
【9月更文挑战第8天】硬盘被划分为若干相同大小的块(Block),默认大小为4K,便于灵活管理文件数据。文件数据分散存放于这些块中,提高了数据添加、删除和插入的便利性。
|
2月前
|
存储 缓存 Linux
Linux文件系统的功能规划
【9月更文挑战第12天】本文通过类比图书馆,形象地解释了文件系统的组织形式和管理方法。首先,文件系统需按块存储文件,并设有索引区方便查找。其次,热点文件应有缓存层提高效率,文件需分类存储以便管理。最后,Linux内核需记录文件使用情况,通过文件描述符区分不同文件,确保文件操作准确无误。
|
3天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
17 3