概述

文件描述符与打开的文件对应。
不同描述符可能指向同一文件。
相同的文件可以被不同的进程打开,也可以在同一个进程被多次打开。
0、1、2,标准输入、标准输出、标准错误输出,已经占了3个描述符,所以打开文件描述符一般从3开始递增。
image.png

  1. # 用户级文件描述符限制(进程)
  2. ulimit -n
  3. 1024
  4. # 系统级文件描述符限制
  5. sysctl -a | grep fs.file-max
  6. 93970

维护文件描述符的三个表

image.png
进程级:文件描述符标志、文件指针
系统级(open file table):每条目叫文件句柄(open file handle)包含:

  1. 当前文件偏移量(调用read()和write()时更新,或使用lseek()直接修改)
  2. 状态标志(open的flags参数)
  3. 文件访问模式(读、写、读写)
  4. 信号驱动设置
  5. i-node指针
  6. 文件类型(普通文件、Socket、FIFO)和权限
  7. 文件所持有锁列表指针
  8. 文件属性(大小,各种时间戳)

i-node:文件类型、文件锁
image.png

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

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

    此外,进程A的描述符0和进程B的描述符3分别指向不同的打开文件句柄,但这些句柄均指向i-node表的相同条目(1976),换言之,指向同一个文件。发生这种情况是因为每个进程各自对同一个文件发起了open()调用。同一个进程两次打开同一个文件,也会发生类似情况。

inode

硬盘最小存储单位为扇区(Sector),每个扇区512字节。操作系统不会一个一个读扇区,效率太低。每次会读一个“块”(Block)。块由多个扇区组成,是文件读写最小单位。块一般4KB。八个扇区组成一个块。
存储文件元信息的地方叫inode(索引节点index node的缩写)。元信息有:文件创建者、创建日期、大小等。

元信息

   文件的字节数
  
文件拥有者的User ID
   文件的Group ID
  
文件的读、写、执行权限
   文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  
链接数,即有多少文件名指向这个inode
  * 文件数据block的位置

stat foo.txt 查看inode信息。
image.png

除了文件名都在inode中存储。inode在硬盘上,格式化的时候会把硬盘分成inode区(inode table)和数据区。
每个inode节点大小一般128或256字节,节点总数在格式化是就给定。一般1KB或2KB就设置一个。如果1GB硬盘,inode节点128字节,每1KB设置一个,占比12.8%。inode table大小128MB。
df -i 命令可查看
image.png
sudo dumpe2fs -h /dev/hda | grep “Inode size”
image.png

硬连接

多个文件名指向一个inode号。当inode硬链接数为0时,系统回收这个inode号以及对应Block区域。
创建目录时,默认会生成两个目录项:”.”和”..”。前者的inode号码就是当前目录的inode号码,等同于当前目录的”硬链接”;后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的”硬链接”。所以,任何一个目录的”硬链接”总数,总是等于2加上它的子目录总数(含隐藏目录)。

软连接

甲文件内容是乙文件的路径,访问甲会自动跳转到乙。甲乙是两个inode号。乙删除,会报”No such file or directory”错误。