Linux内核学习

本文介绍了Linux文件系统的原理,包括进程的概念、文件与目录的区别、硬链接与软链接的工作方式及LinuxVFS的基本概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要目的是学习并归纳Linux操作系统中内核的几个基本重要知识

进程

  • 一个进程在地址空间中执行一个单独的指令序列

地址空间是允许进程引用的内存空间的集合,操作系统允许具有多个执行流的进程,即在相同的地址空间可执行多个指令序列。
进程能并发活动,竞争的系统资源主要是CPU
区分程序和进程:
- 几个进程能并发执行同一个程序,同时,同一进程能顺序执行多个程序

现在的CPU处理器一般都是多核CPU,可通过任务管理器查看。而在单处理器系统上,只有一个进程能占用CPU。因此,在某时刻,只能有一个执行流。
CPU有多少个,就有多少个进程可同时执行。选择哪个进程执行由操作系统的调度程序决定,进程分为抢占式进程和非抢占式进程。
对于抢占式进程,只有进程自愿放弃CPU,调度程序才会被调用;
对于非抢占式进程,如多用户系统中的进程调度,操作系统记录下每个进程占优的CPU时间,并周期性地激活调度程序。


为了标识一个特定的文件,进程使用路径名,路径名由斜杠及一列指向文件的目录名交替组成。若路径名第一个字符是斜杠那么该路径就为绝对路径,因为其起点是根目录。若第一项是目录名或文件名,那么路径就是相对路径,因为其起点是进程的当前目录。


Linux文件与目录

操作系统为了解决信息能独立于进程之外被长期存储,而引入了文件。
- 文件作为进程创建信息的逻辑单元,可被多个进程并发使用
在Unix系统中,操作系统为磁盘上的文本与图像、鼠标与键盘等输入设备及网络交互等I/O操作设计了一组通用的API,使他们被处理时均可统一使用字节流。
- Lniux系统中除进程外的一切都是文件,为了便于文件管理而引入目录,这使Linux文件系统形成了一个层级结构的目录树。

Linux系统顶层目录结构
/ 根目录
├── bin 存放用户二进制文件
├── boot 存放内核引导配置文件
├── dev 存放设备文件
├── etc 存放系统配置文件
├── home 用户主目录
├── lib 动态共享库
├── lost+found 文件系统恢复时的恢复文件
├── media 可卸载存储介质挂载点
├── mnt 文件系统临时挂载点
├── opt 附加的应用程序包
├── proc 系统内存的映射目录,提供内核与进程信息
├── root root 用户主目录
├── sbin 存放系统二进制文件
├── srv 存放服务相关数据
├── sys sys 虚拟文件系统挂载点
├── tmp 存放临时文件
├── usr 存放用户应用程序
└── var 存放邮件、系统日志等变化文件

  • Linux系统并不区分文件和目录,目录是记录其他文件名的文件
  • Linux将设备当做文件处理

打开并读取设备文件

 int fd; 
 struct input_event ie; 
 fd = open("/dev/input/event3", O_RDONLY); 
 read(fd, &ie, sizeof(struct input_event)); 
 printf("type = %d  code = %d  value = %d\n", 
             ie.type, ie.code, ie.value); 
 close(fd);

其展示了如何打开设备文件event3并读取文件内容,文件event3表示一直输入设备,其可能是鼠标或键盘,通过查看 /proc/bus/input/devices 可知 event3 对应设备的类型。设备文件 /dev/input/event3 使用 read() 以字符流的方式被读取。结构体 input_event 被定义在内核头文件 linux/input.h 中。

  • 文件都有文件名和数据,在Linux上被分成两部分:用户数据与元数据
  • 用户数据:文件数据块(data block),数据块是记录文件内容的地方
  • 元数据:文件的附加属性,即文件大小、创建时间及所有者等信息。

在Linux中,元数据中的inode号为索引节点号,是文件的唯一标识。而文件名是为了方便人们记忆和使用,系统或程序是通过inode号来寻找正确的文件数据块。

  • 查看inode号使用stat或ls -i命令

硬链接&软链接

链接不仅解决了Linux系统文件的共享使用,而且带来了隐藏文件路径、增加权限安全及节省存储等好处。
- 硬链接:一个inode号对应多个文件名
文件A是文件B的硬链接,则A的目录项中的索引inode节点号与B的目录项中的inode节点相同,即同一个inode节点对应不同的文件名,两个文件名指向同一文件,A和B对于文件系统来说是完全等同的。

  • 特点
    文件有相同的 inode 及 data block
    只能对已存在的文件进行创建
    不能交叉文件系统进行硬链接的创建
    不能对目录进行创建,只可对文件创建
    删除一个硬链接文件并不影响其他有相同 inode 号的文件
$ touch test
$ echo "This is a test." > test
$ cat test 
This is a test.
$ ln test filetxt
$ ls -li
total 8
809185 -rw-rw-r-- 2 wonderxiao wonderxiao 16 1013 20:42 filetxt
809185 -rw-rw-r-- 2 wonderxiao wonderxiao 16 1013 20:42 test
其中,809185是文件的inode值,你可简单将文件看作C语言的指针,它指向物理硬盘的一个区块。事实上,文件系统会维护一个引用计数,只要有文件指向这个区块,它就不会从硬盘上消失。 inode 是随着文件的存在而存在,因此只有当文件存在时才可创建硬链接,即当 inode 存在且链接计数器不为 0 时。 若修改刚才创建的filetxt文件:
$ echo "New one" >> filetxt                  
$ cat test 
This is a test.
New one

可看到,这两个就如同一个文件一样,inode值一样,都指向同一个区块。

软链接——符号链接

文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块,因此软链接的创建与使用没有类似硬链接的诸多限制。 - 特点

软链接有自己的文件属性及权限等
可对不存在的文件或目录创建软链接
软链接可交叉文件系统
软链接可对文件或目录创建
创建软链接时,链接计数 i_nlink 不会增加
删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接

链接的访问

![链接的访问](https://raw.githubusercontent.com/wonderxiao/BlogPicture/master/photos/2017-10-13_%E9%93%BE%E6%8E%A5%E7%9A%84%E8%AE%BF%E9%97%AE.png)
$ ln -s filetxt softtxt
$ ls -li
total 8
809185 -rw-rw-r-- 2 wonderxiao wonderxiao 24 1013 21:11 filetxt
809068 lrwxrwxrwx 1 wonderxiao wonderxiao  7 1013 21:14 softtxt -> filetxt
809185 -rw-rw-r-- 2 wonderxiao wonderxiao 24 1013 21:11 test
这个软链接的inode值不一样了,且文件属性为1,说明刚才创建的软链接文件根本不是同一类型。 若删除filetxt文件,然后输出软硬链接文件内容:
$ rm filetxt
$ cat test
This is a test.
New one
$ cat softtxt
cat: softtxt: No such file or directory
之前硬链接没有任何影响,这是由于其inode所指向的区块有一个硬链接在指向它,所以此区块仍然有效,可继续访问。而软链接的inode所指向的内容实际上保存的是一个绝对路径,当用户访问这个文件时,即访问的是这个文件路径所在的文件。此时,这个文件已被删除,所以找不到它。
  • 软链接:保存其代表的绝对路径,是另外一个文件,在硬盘上有独立的块,访问时会替换自身路径。
  • 硬链接:代表的是文件的副本

Linux VFS

Linux有极其丰富的文件系统,可分为:
- 网络文件系统,如nfs、cifs等
- 磁盘文件系统,如ext4、ext3等
- 特殊文件系统,如proc、sysfs、ramfs、tmpfs等

这些文件系统系统在Linux下共存的基础是Linux VFS(Virtual File System),VFS作为一个通用的文件系统,抽象定义了文件系统的四个基本概念:
- 文件
- 目录项
- 索引节点
- 挂载点

其在内核中,为用户空间层的文件系统提供了相关接口,即VFS实现了open()、read()等系统调用的函数,这就真正实现:在Linux系统中,除进程外一切都是文件。

VFS在系统中架构

VFS在系统架构

VFS存在四个基本对象:
- 超级块对象(superblock object)
一个已安装的文件系统
- 索引节点对象(inode object)
一个文件
- 目录项对象(dentry object)
一个目录项,如设备文件event3在路径/dev/input/event3中,存在四个目录项对象:/、dev/、input/及event3。
- 文件对象(file object)
代表进程打开的文件

这四个对象与进程及磁盘文件间的关系如下图:
对象与进程及磁盘文件间的关系

其中,d_inode为硬链接,是文件路径的快速解析。同时,Linux VFS设计了目录项缓存dcache。

在Linux中,索引节点结构存在于系统内存及磁盘中,其可分为VFS inode与实际文件系统的inode。VFS inode是作为实际文件系统中inode的抽象。

VFS中inode与inode_operations结构体

struct inode { 
    ... 
    const struct inode_operations   *i_op; // 索引节点操作
    unsigned long           i_ino;      // 索引节点号
    atomic_t                i_count;    // 引用计数器
    unsigned int            i_nlink;    // 硬链接数目
    ... 
 } 

 struct inode_operations { 
    ... 
    int (*create) (struct inode *,struct dentry *,int, struct nameidata *); 
    int (*link) (struct dentry *,struct inode *,struct dentry *); 
    int (*unlink) (struct inode *,struct dentry *); 
    int (*symlink) (struct inode *,struct dentry *,const char *); 
    int (*mkdir) (struct inode *,struct dentry *,int); 
    int (*rmdir) (struct inode *,struct dentry *); 
    ... 
 }

每个文件存在两个计数器:
- i_count:引用计数,用于跟踪文件被访问的数量,或者说 i_count 跟踪文件在内存中的情况
- i_nlink:硬链接计数,使用 ls -l 等命令查看到的文件硬链接数,即是磁盘计数器。当文件被删除时,则 i_nlink 先被设置成 0。

文件的这两个计数器使得 Linux 系统升级或程序更新变的容易。系统或程序可在不关闭的情况下(即文件 i_count 不为 0),将新文件以同样的文件名进行替换,新文件有自己的 inode 及 data block,旧文件会在相关进程关闭后被完整的删除。

文件系统 ext4 中的 inode

struct ext4_inode { 
    ... 
    __le32  i_atime;        // 文件内容最后一次访问时间
    __le32  i_ctime;        // inode 修改时间
    __le32  i_mtime;        // 文件内容最后一次修改时间
    __le16  i_links_count;  // 硬链接计数
    __le32  i_blocks_lo;    // Block 计数
    __le32  i_block[EXT4_N_BLOCKS];  // 指向具体的 block 
    ... 
 };

其中三个时间的定义可对应与命令 stat 中查看到三个时间。i_links_count 不仅用于文件的硬链接计数,也用于目录的子目录数跟踪(目录并不显示硬链接数,命令 ls -ld 查看到的是子目录数)。由于文件系统 ext3 对 i_links_count 有限制,其最大数为:32000(该限制在 ext4 中被取消)。

总结

本文描述了 Linux 系统中文件与目录被引入的原因及 Linux 处理文件的方式,然后我们通过区分硬链接与软链接的不同,了解 Linux 中的索引节点的相关知识,并以此引出了 inode 的结构体。索引节点结构体存在在于 Linux VFS 以及实际文件系统中,VFS 作为通用文件模型是 Linux 中“一切皆是文件”实现的基础。文章并未深入 Linux VFS,也没涉及实际文件系统的实现,文章只是从 inode 了解 Linux 的文件系统的相关内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值