Linux性能学习(3.1):IO_文件系统IO


参考资料:
1. Linux I/O模型

在Linux下一切皆文件,当我们操作一个文件时候,最基础的就是读写操作,即I/O操作,因此这篇就大致了解解文件系统I/O的相关功能。

1 文件系统

1.1 基本概念

文件系统是操作系统中负责管理持久数据的子系统,即管理文件和目录的一套机制。

说到文件系统,在嵌入式开发过程中经常遇到以下几个文件系统:jffs2、NFS、/proc、FAT32。

jffs2是比较常用的磁盘文件系统,FAT32也是SD卡常用的文件系统;

/proc是基于基于内存的文件系统,即这类文件系统会占用内存;

NFS是网络文件系统,将其进行挂载后可以通过网络访问其它计算机的数据。

上面介绍了几种不同的文件系统,每种文件系统都有自己的特点、实现细节、以及不同的接口,但是Linux系统在这些文件系统之上又引入一个抽象层,即VFS(虚拟文件系统)。VFS提供了一套公有的数据结构和标准接口,不同的文件系统都要遵守这套接口,然后用户就不需要关注底层使用什么文件系统,只需要使用VFS提供的标准接口进行交互,由VFS来和不同的文件系统进行交互,用户不需要关注底层的文件系统。

1.2 文件管理

文件系统为了文件管理方便,为每个文件分配了两个数据结构:索引节点(index node)和目录项(directory entry)。

索引节点保存了文件系统中的每一个文件的元信息数据,即文件的属性信息,比如创建时间、修改时间、文件大小、访问权限、文件的链接数等信息。索引节点数保存在硬盘上的,在格式化时会将硬盘格式化为数据区(存放文件数据)和inode区(存放inode)。

目录项是由文件的文件名以及文件对应的inode组成。多个关联的目录项,就构成了文件系统的目录结构。目录项是由内核维护的内存数据结构,是保存在内存中的。

目录项中的文件名和索引节点是一一对应的,但是却不是唯一对应的,一个文件名只有唯一的一个索引节点与其对应,但是一个索引节点可能有多个文件名与其对应,比如一个文件可能被硬链接为不同的的名字,但是实际的文件数据就一份,实际就链接同一份文件。

1.3 索引节点参数查看

可以使用stat命令查看文件的索引节点相关参数:

# stat tmp_2.txt 
  File: 'tmp_2.txt'
  Size: 0         	Blocks: 0          I/O Block: 4096   regular empty file
Device: 803h/2051d	Inode: 4102336     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2021-07-09 14:26:28.573696292 +0800
Modify: 2021-06-03 09:31:57.435248074 +0800
Change: 2021-06-03 09:31:57.435248074 +0800
 Birth: -
#

上面的Links表示有多少文件名指向这个inode。

我们还可以使用df指令查看每个硬盘分区的inode总数和已经使用的数据:

# df -i
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
udev             376445     437   376008    1% /dev
tmpfs            384194     780   383414    1% /run
/dev/sda3      12599296 2526082 10073214   21% /

还可以使用指令查看每个inode的大小:

# dumpe2fs -h /dev/sda3 | grep "Inode size"
dumpe2fs 1.42.13 (17-May-2015)
Inode size:	          256

还可以使用指令查看各种索引节点在内存中的缓存情况:

# cat /proc/slabinfo | grep "inode"
ovl_inode             46     46    696   23    4 : tunables    0    0    0 : slabdata      2      2      0
rpc_inode_cache       23     23    704   23    4 : tunables    0    0    0 : slabdata      1      1      0
btrfs_inode            0      0   1152   14    4 : tunables    0    0    0 : slabdata      0      0      0
mqueue_inode_cache     17     17    960   17    4 : tunables    0    0    0 : slabdata      1      1      0
fuse_inode            38     38    832   19    4 : tunables    0    0    0 : slabdata      2      2      0
ecryptfs_inode_cache      0      0   1024   16    4 : tunables    0    0    0 : slabdata      0      0      0
fat_inode_cache        0      0    752   21    4 : tunables    0    0    0 : slabdata      0      0      0
squashfs_inode_cache     23     23    704   23    4 : tunables    0    0    0 : slabdata      1      1      0
ext4_inode_cache   31074  37874   1096   29    8 : tunables    0    0    0 : slabdata   1306   1306      0
hugetlbfs_inode_cache     25     25    632   25    4 : tunables    0    0    0 : slabdata      1      1      0
sock_inode_cache    2263   2277    704   23    4 : tunables    0    0    0 : slabdata     99     99      0
shmem_inode_cache   2064   2288    720   22    4 : tunables    0    0    0 : slabdata    104    104      0
proc_inode_cache    6200   6900    688   23    4 : tunables    0    0    0 : slabdata    300    300      0
inode_cache        18120  18187    616   13    2 : tunables    0    0    0 : slabdata   1399   1399      0
# 

1.4 目录项参数查看

使用ls指令可以查看当前目录中每一个文件名以及对应的inode:

# ls -li ./
4102334 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_0.txt
4102335 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_1.txt
4102336 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_2.txt
4102337 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_3.txt
4102338 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_4.txt
4102339 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_5.txt
4102340 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_6.txt
4102341 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_7.txt
4102342 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_8.txt
4102343 -rw-r--r--  1 root   root         0 6月   3  2021 tmp_9.txt

我们也可以使用指令查看目录项在内存中的缓存情况:

# cat /proc/slabinfo | grep "dentry"
dentry             70420  76398    192   21    1 : tunables    0    0    0 : slabdata   3638   3638      0
#

也可以使用slabtop指令进行查看:

 Active / Total Objects (% used)    : 774331 / 853767 (90.7%)
 Active / Total Slabs (% used)      : 26529 / 26529 (100.0%)
 Active / Total Caches (% used)     : 87 / 129 (67.4%)
 Active / Total Size (% used)       : 159912.13K / 177094.16K (90.3%)
 Minimum / Average / Maximum Object : 0.01K / 0.21K / 12.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
 37874  31074  82%    1.07K   1306       29     41792K ext4_inode_cache
266214 237780  89%    0.10K   6826       39     27304K buffer_head
 76398  70420  92%    0.19K   3638       21     14552K dentry
 21882  18113  82%    0.57K   1563       14     12504K radix_tree_node
 86640  86640 100%    0.13K   2888       30     11552K kernfs_node_cache
 18187  18120  99%    0.60K   1399       13     11192K inode_cache
 42123  41381  98%    0.20K   2217       19      8868K vm_area_struct
   955    877  91%    5.44K    191        5      6112K task_struct

1.5 文件系统I/O

当我们在读写文件时候,因为操作方式不同,可能会导致I/O数据的就会有不同的表现形式:缓冲I/O与非缓冲I/O、直接I/O与非直接I/O、同步非阻塞I/O、同步阻塞I/O、异步I/O等等,这里不再赘述。

猜你喜欢

转载自blog.csdn.net/u011003120/article/details/128286818