linux内核开文件系统,内核必须懂(二): Linux文件系统初探

目录

前言

文件系统结构

新建文件和inode

文件创建过程

inode解析

打开文件

参考

最后

前言

这次来说文件系统. 文件系统是非常重要的, 提高磁盘使用率, 减小磁盘磨损等等都是文件系统要解决的问题. 市面上的文件系统也是数不胜数, 比较常用的像ext4, xfs以及ntfs等等, 国内的像鹅厂的tfs, 然后还有sun号称"last word in file system"的ZFS, 学习ZFS而来的btrfs.

下面上一张Linux文件系统组件的体系结构图, 是我整合了多方文献并结合自己的经验画出来的. 可以看出, 最重要的就是vfs, 正是因为它, 才让Linux可以同时支持多种的文件系统. 举个例子, 比如你装了双系统mint+windows, 在mint中, 你可以看到windows的ntfs磁盘, 但是返回了windows, 你就看不到mint的磁盘了.

AAffA0nNPuCLAAAAAElFTkSuQmCC

那Linux支持哪些文件系统呢? 来到源码的fs文件夹, Linux支持的文件系统可多了去了, 注意看蓝色的.

AAffA0nNPuCLAAAAAElFTkSuQmCC

文件系统结构

磁盘扇区什么的就不多说了. 也许会出一篇谈存储介质的文章, 说说ssd结构啥的. 直接跳过硬件从文件系统结构开始. 注意, 我说的是通用模型, 每个fs的具体实现有差异, 而且差异蛮大的. ext家族是Linux默认的fs了, 事实上ext2/ext3和ext4差异也很大.

superblock: 记录此fs的整体信息, 包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;

inode table: superblock之后就是inode table, 存储了全部inode.

data block: inode table之后就是data block. 文件的内容保存在这个区域. 磁盘上所有块的大小都一样.

inode: 记录文件的属性, 同时记录此文件的数据所在的block号码. 每个inode对应一个文件/目录的结构, 这个结构它包含了一个文件的长度、创建及修改时间、权限、所属关系、磁盘中的位置等信息.

block: 实际记录文件的内容. 一个较大的文件很容易分布上千个独产的磁盘块中, 而且, 一般都不连续, 太散会导致读写性能急剧下降.

好, 我猜你和我一样是右脑思维, 上图就好:

AAffA0nNPuCLAAAAAElFTkSuQmCC

可以看出来, 这是多层索引结构的文件系统. 用b+树是最佳解决方案, 比如btrfs. inode table指向inode, inode指向一个或者多个block, 注意, 图中还是直接指向, 后面还会讲述多层指向. 最怕的就是inode指向的block太散. 一个比较好的解决办法就是在文件末尾不断添加数据, 而不是新建文件.

新建文件和inode

新建一个文件和文件夹, 用stat指令查看文件信息.

touch hello

stat hello

mkdir hellodir

stat hellodir

AAffA0nNPuCLAAAAAElFTkSuQmCC

可以看到一些信息. 例如一个目录初始大小就是4KB, 8个block, 一个扇区就是512B, 一个io block是4KB, 对应第一幅图的General Block Device Layer层. 这些其实不看也知道, 前提是这是常规的fs.

文件创建过程

创建成功一个文件有4步:

存储属性: 也就是文件属性的存储, 内核先找到一块空的inode. 例如, 之前的1049143. 内核把文件的信息记录其中. 如文件的大小、文件所有者、和创建时间等, 用stat指令都可以看到.

存储数据: 即文件内容的存储, 比方建立一个1B的文件, 那一个block, 8个扇区, 内核把数据放到一个空闲逻辑块中也就是空闲block中. 很明显, 碎片化的问题已经呈现在这里了. 1B它也要用4K对吧.

记录分配情况: 假如数据保存到了3个block中, 位置要记录到inode的磁盘序号列表中. 这3个编号分别放在最开始的3个位置. 然后读的时候会一次性读, 可以看我的第二张图. 当然了fat就没有inode, 它在一个块中放了下一个块的位置, 形成链, u盘就是这种fs.

添加文件名到目录: 文件名和inode之间的对应关系将文件名和文件以及文件的内容属性连接起来, 找到文件名就找到文件的inode,通过inode就能找到文件的属性和内容. 换句话说, 就是机器看的和人看的做衔接, 例如网址和ip. 当然, 如果你看inode就能区分文件, 第四步可以不要(手动滑稽).

目录的话, 就是多了点文件(指向自己), 点点文件(指向上级目录). 然后添加自己的inode到上级目录. 看图就秒懂了.

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

inode解析

用df指令可以看inode的总数和使用量.

df -i

dumpe2fs打开指定磁盘可以看inode的大小, 这里是256.

AAffA0nNPuCLAAAAAElFTkSuQmCC

inode如何记录文件并且最大是多少呢? inode记录block号码的区域定义为12个直接, 一个间接, 一个双间接与一个三间接记录区. 一个inode是4B, 这样用4K的block可以有1K的inode.

直接: 12 * 4K

间接: (4K / 4) * 4K

双间接: (4K / 4) * (4K / 4) * 4K

三间接: (4K / 4) * (4K / 4) * (4K / 4) * 4K

所以的话, 4T, are you OK? 算归算, fs在不断发展, 这是过时的大小了. ext4的话单个文件可以到达16TB, fs可达1EB. 但是注意, ext4的作者都说了, ext4只是过渡, btrfs会更棒, 那事实上, cent os用的xfs也很很棒.

打开文件

创建之后当然要打开了, 打开文件也是有一系列过程的. 先来看看两个指令:

sysctl -a | grep fs.file-max

ulimit -n

AAffA0nNPuCLAAAAAElFTkSuQmCC

第一个指令查看os最大打开数, 这是系统级限制.

第二个指令查看单进程最大打开数, 这是用户级限制.

进程描述符(task_struct):

为了管理进程, 操作系统要对每个进程所做的事情进行清楚地描述, 为此, 操作系统使用数据结构来代表处理不同的实体, 这个数据结构就是通常所说的进程描述符或进程控制块(PCB). 通俗来讲就是操作系统中描述进程的结构体叫做PCB.

Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程, 这个结构体包含了一个进程所需的所有信息. 它定义在include/linux/sched.h文件中. 这不是这次的重点, 但是这个task_struct结构体确实很重要, 也很复杂.

每个进程都会被分配一个task_struct结构, 它包含了这个进程的所有信息, 在任何时候操作系统都能跟踪这个结构的信息.

文件描述符表(file_struct): 该表记录进程打开的文件. 它的表项里面有一个指针, 指向存放在内核空间的文件表中的一个表项. 它向用户提供一个简单的文件描述符(fd), 使得用户可以通过方便地访问一个文件. 例如, 当进程使用open打开一个文件时, 内核就会在这个表中添加一个表项. 如果对同一个文件打开多次, 那么将有多个表项. 使用dup时, 也会增加一个表项.

文件表: 文件表保存了进程对文件读写的偏移量. 该表还保存了进程对文件的存取权限等等. 比如, 进程以O_RDONLY方式打开文件, 这将记录到对应的文件表表项中. 然后每个表有一个指向inode table中inode的指针. 结合之前的图片看, 所有结构就联系起来了, 所以inode是核心点.

上图上图:

AAffA0nNPuCLAAAAAElFTkSuQmCC

在进程A中, 文件描述符1和2都指向了同一个打开的文件表A. 这可能是通过调用dup()、dup2()、fcntl()或者对同一个文件多次调用了open()函数而形成的.

进程A的文件描述符0和进程B的文件描述符2都指向了同一个打开的文件表A. 这种情形可能是在调用fork()后出现的(即, 进程A、B是父子进程关系), 或者当某进程通过UNIX域套接字将一个打开的文件描述符传递给另一个进程时, 也会发生. 再者是不同的进程独自去调用open函数打开了同一个文件, 此时进程内部的描述符正好分配到与其他进程打开该文件的描述符一样.

此外, 进程A的描述符0和进程B的描述符255分别指向不同的打开文件表, 但这些文件表均指向inode table的相同条目(假设), 也就是指向同一个文件. 发生这种情况是因为每个进程各自对同一个文件发起了open()调用。同一个进程两次打开同一个文件, 也会发生类似情况.

为什么要说这些情况呢? 因为如果没有理解清楚这些, 在做多进程多线程read和write的时候很有可能会导致读取和写入混乱.

参考

看了非常多很棒的文章, 这里也分享给大家.

最后

这次从结构上逐步往内解剖文件系统, inode是核心点. 当然还有两篇甚至更多的后续文章, 最后会写个简单的用户态文件系统, 喜欢记得点个赞或者关注我哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gps卫星位置计算程序matlab_科研项目 | BD/ GPS卫星导航仿真测试系统研究

一、项目背景在移动互联和互联网的时代,卫星导航定位已经成为生活中不可或缺的部分。目前,我国的交通、银行、电力、采矿、测绘等部门以及大众化市场都需要大量的定位、授时服务。许多企业也形成了覆盖卫星导航相关材料及元器件、卫星导航芯片、卫星导航…

Linux输入密码接口,Linux下搭建接口自动化测试平台

前言我们今天来学习一下在Linux下如何搭建基于HttpRunner开发的接口自动化测试平台吧!需要在Linux上提前准备的环境(下面是本人搭建时的环境):1,Python 3.6.8 (可参考随笔:Linux学习6-安装Python3.6)2,MySQL 5.7(可参考…

linux下查看windows文件夹大小,如何从Windows命令行检查文件夹的大小?

我意识到这个问题要求使用进行文件大小分析CMD line。但是,如果您愿意使用它,PowerQuery (Excel add-in, versions 2010)则可以创建一些非常引人注目的文件大小分析。下面的脚本可以粘贴到空白查询中;您唯一需要做的就是添加一个名为“ param…

图像语义分割_图像语义分割(9)-DeepLabV3: 再次思考用于图像语义分割的空洞卷积...

论文地址 :Rethinking Atrous Convolution for Semantic Image Segmentation论文代码:Github链接1. 摘要文章主要的工作:使用空洞卷积来调整滤波器的感受野并控制特征图分辨率使用不同空洞率的空洞卷积的串联或者并行操作来分割不同尺度的目标…

sql replace 双引号变单引号_sql-汇总、排序以及分析思路

一、汇总函数注:汇总函数,如果输入是列名,计算会把null 排除在外,count(*)对所有的行进行计数二、如何用sql解决业务问题注1:空值(null)的排序,排序是最小的,例如select * from tea order by tea_name注2&a…

openwrt是嵌入式linux,非常方便的OpenWrt的嵌入式Linux开发环境

今天听中央经济广播电台说,今年有559万大学毕业生,大学生的就业形式严峻.我想那些精通Linux开发的毕业大学生们,估计一点也不用担心,因为他们已经不再是一颗大白菜了.最近在帮一个朋友把OpenWrt移植到一块单板上,有一些心得,分享给大家.OpenWrt是一个很好的学习Linux的平台,而且…

php多个表中查找数据_HeidiSQL 免费的可视化数据库管理工具

HeidiSQL是一款免费的软件,并且易于学习和使用。HeidiSQL让你从数据库内可视化的读写数据、结构体。它支持MariaDB、MySQL、Microsoft SQL、PostgreSQL等数据库。功能免费且开源内置中文在同个窗口连接多个服务支持以命令行形式连接服务连接支持SSH、SSL创建修改表、…

嵌入式linux启动根文件系统,嵌入式Linux根文件系统制作和挂载

嵌入式Linux系统由三部分组成: uboot、kernel、根文件系统, 还是这张老图这里的根文件系统可以说是包含两个部分: 一个是根,一个是文件系统那么什么是根呢?哈哈 其实根表示的就是第一个的意思下面贴张图看看整个根文件…

sqlite 查询 支持多用户同时_SQLite支持多进程同时操作数据库文件吗?

多个进程可以同时打开同一个数据库。多个进程可以同时执行SELECT。但是,只有一个进程可以随时对数据库进行更改。SQLite使用读/写锁来控制对数据库的访问。(在Win95 / 98 / ME下,缺少对读写锁的支持,而是使用概率模拟。)但请注意:…

pgsql 查询每天的最后一条_Qamp;A | 如何允许他人查询表单数据?

小金Q&A来啦!这一期小金Q&A中,小金收集到近期大家关注最多的几个问题。小金将定期为小金人们答疑解惑,帮助你每天用好小金一点。●Q&A●问:如何批量设置新数据微信提醒?答:点击右上角头像 个人…

linux 解压tar.jz,linux系统压缩文件和解压缩命令

linux系统压缩文件和解压缩命令tar命令   解包:tar zxvf FileName.tar打包:tar czvf FileName.tar DirName gz命令   解压1:gunzip FileName.gz解压2:gzip -d FileName.gz压缩:gzip FileName.tar.gz 和 .tgz解压&a…

linux fall delay 10,Cell的Rise delay和Fall delay、Rise transition和fall transition

Cell的Rise delay和Fall delay、Rise transition和Fall transition介绍:如下图所示为一个Cell的lib中关于cell_rise/cell_fall、rise_transition/fall_transition的描述:在NLDM模型的.lib中,cell_rise/cell_fall它描述的是Cell从输入到输出的…

keil流水灯c语言程序两个一起亮,我用keil c51编了一个流水灯程序,编译无误却只有第一和第二个灯亮了,最后停在第一个灯处不动...

满意答案zJ张俭2014.02.09采纳率:43% 等级:12已帮助:10469人你有几个错误:1 你的定时器没有重装,导致第一次中断和后面的中断时间不一样,第一次时间短,后面的时间一直是以65536个周期中断的.2 你在中断函数里用了 for 循环,for循环是一下子…

pyquery获取不到网页完整源代码_python动态网页爬取:爬取pexel上的图片

前言同样的,我们在写一个爬虫前要明确自己想要爬取的东西是什么,明确下载目标数据在浏览器的操作如何对于动态网页的爬取,在网页地址不变的情况下,我们首先要明确如何获取AJAX请求首先我们看看这个网站pexel打开页面后再Chrome浏览…

W ndows找不到explorer,windows找不到explorer.exe的处理教程

很多网友入手windows过程里找不到explorer.exe,很是烦恼,为了帮助大家排忧解难,这里小编就分享了windows找不到explorer.exe的处理教程,希望可以帮助到大家。windows找不到explorer.exe的处理教程1、按winr打开运行窗口&#xff0…

极光推送 android 最新,Android——快速集成极光推送-Go语言中文社区

集成极光推送1,首先肯定是注册,添加应用2,开始自动集成比手动集成简单第一步 在 build.gradledefaultConfig {multiDexEnabledtrueapplicationId rootProject.ext.cfg.applicationIdminSdkVersionrootProject.ext.cfg.minSdkVersiontargetSdk…

华为云服务怎么弄金卡会员_万科牵手华为终端云服务,共建松山湖智慧商圈

12月18日,坐落在东莞松山湖南华为旁的44000㎡的开放式商业mall——滨湖万科里正式启幕。现场华为终端云服务部还与万科南方区域商业事业部签署了战略合作协议,开启共建智慧商圈的新版图。值得一提的是,这也是华为终端云服务与万科在商业板块的…

cad2014打开文件崩溃_CAD玩的再牛,崩溃了咋办?

导读前几天,一入职新人晚上加班画完的图纸在最后一刻CAD崩溃了!好在最后在临时保存文件夹中找到了完整的图纸。这才免于通宵。CAD崩溃是我们画图中经常遇到的问题。对于CAD崩溃后的处理,相信老司机都已经游刃有余。但也有防不胜防的时候&…

android 弹窗ui,Android 弹出窗口与对话框 UI设计

左图: Android 自带的日期选择弹窗; 右图: Android 自带的时间选择弹窗.左图: Android 日历中的重复选择; 右图: Chrome 中的打印.干净简洁的布局与有趣儿又引人注目的交互让操作变得轻松而愉快, 尤其是那在时间选择器中出现的双环.同样的, 也有很多人试图在自己的应用中给他们…

vim反向删除_VIM之操纵缓冲区列表

引子昨天遇到了一个奇怪的问题,一条在Sublime里面看着十分正常的SQL语句,执行了也是正常的,导出的Insert语句也是看着没毛病的,但是在查询出来,传递到下游的时候,说多了一个乱码。WTF,然后就开始…