1. open
用户文件描述符, 文件表, 索引节点表。其中前两个表是一一对应
每个open调用都在用户描述符表和内核文件表中分配一个唯一表项,但在内存索引节点表中只有一个表项。
2. read
内核从用户文件描述符得到对应的文件表表项,然后设置进程u区的IO参数,包括用户缓冲区地址、要读的字计数、在文件中的偏移量等。这样这些参数不必作为参数传递。
从文件系统块的边界开始、而且大小为块的整数倍的IO操作具有很多有点,能是内核避免额外重复read中的循环(这种重复以与其他进程竞争对缓冲池的访问为代价)。标准IO库对用户隐瞒了内核缓冲区的大小,能够避免不良性能。
索引节点在read调用期间一直是锁住的,以提供一直的文件视图。
3. write
索引节点中包含直接块与间接块。当写文件时,若文件变大,则调用bmap访问要写入的字节时,内核会发现不但文件中没有对应的字节块,而且也没有索引节点的间接块(或直接块,视偏移地址定)。这是,内核将分配一个磁盘块作为间接块并将块号写入内存索引节点中。然后内核为数据块分配一个磁盘块,并将它的块号写到新分配的间接块中。
写块中的一部分时,需要先从磁盘上把该块读入。而写整块时,直接覆盖即可。
4. 文件和记录的上锁
实现数据库时,需要对特定记录加锁。
5. lseek
lseek只调整文件表中的字节偏移量,与磁盘扇区查找seek无任何关系。
6. close
close将文件表项引用数减一(dup和fork会增加引用数),若引用数为1,内核则释放该表项,并释放open中分配的内存索引节点(iput)。iput是索引节点引用数减一,或归还该索引节点以便再次分配。
当一个进程退出时,内核检查它的活动用户文件描述符并在内部关闭它们。
7. 文件建立
create。内核锁住被查找目录的索引节点,作为新文件的父目录。将父目录中空目录槽的偏移量记录在u区中。
调用ialloc给新文件分配一个索引节点,按保存在u区中偏移量,把新文件名和索引节点号写入父目录中。然后释放父目录索引节点(此时父目录中已含有新文件名和它的索引节点号)。内核在将含有新名字的目录(父目录)写到磁盘之前,要先将新分配的索引节点写到磁盘上(bwrite)。若先写入父目录,且系统在两次写之间出错,纳闷文件系统就会有个引用坏索引节点的路径名。
8. 特殊文件的建立
mknod,建立有名管道、设备文件和目录等。
mknod与create类似,先建立索引节点并将新文件名与索引节点写入父目录。内核在索引节点中设置文件类型字段来表示文件的类型是管道、目录或特殊文件。对于块设备,内核将major和minor好写入该索引节点。
9. chdir
系统启动时,0号进程以”/“作为它的当前目录。它在这个根索引节点上执行iget,将其保存到u区作为它的当前目录,然后释放索引节点的所。
chroot与chdir类似,将新的根索引节点放在u区。完成系统调用后,对该索引节点解锁,但引用数加一。新索引节点是该进程及它的所有后代的文件系统逻辑根。在namei中,所有从'/'开始的路径名查找都将从这个索引节点开始。
10. chown,chdir
改变所有者或许可方式是对文件的索引节点操作,而不是对文件本身。
11. stat, fstat
这两个系统调用只是简单地将对应的索引节点中的若干字段写到buffer中。
12. 管道
1) 无名管道pipe
pipe参数为读、写管道用的两个文件描述符。
创建管道时内核为管道分配一个索引节点,同时分配一对文件描述符及相应的文件表项。内核使用文件表,其系统调用接口与正规文件一致,因此进程不必知道它们读或写的是正规文件还是一个管道。
索引节点中会记录下次对管道的读或写在管道中的其实字节偏移量,这一点不同于正规文件(偏移量在文件表中保存)。
2) 有名管道
一个有名管道是一个文件,在文件系统树中永久存在(unlink可清除)。而无名管道是临时的,当所有进程结束使用时,内核便收回它的索引节点。
为读而打开有名管道的进程将进入睡眠,直到另一个进程以写方式打开该管道。
3) 管道的读写
内核在系统调用write期间,将数据放在管道设备上,并按需要将磁盘块分配给管道。管道只使用索引节点的直接块以获得较高的效率,将直接块作为一个循环队列来管理,内部地修改读写指针,从而保持先进先出的顺序。
read和write偏移量通过存在索引节点中的read和write指针获得(不能向常规文件一样放在文件表中,因为无法共享)。write增加管道大小,read减少管道大小。需要时(到达直接块末尾)回绕到管道的开始。
13. dup
dup复制一个文件描述符,指向同一个文件表,同时文件表项引用数加一。
14. mount和umount
1) mount
系统调用mount允许用户以文件系统的方式,存取磁盘段中的数据,而不是按磁盘块序列的方式存取数据。
内核中有个安装表,每个被安装的文件系统在该表中都占有一个表项。每个安装表项含有:
- 设备号
- 指向含有被安装文件系统超级块缓冲区的指针
- 指向被安装文件系统的根索引节点
- 指向安装点的目录的索引节点。安装点的索引节点和被安装文件系统的根索引节点之间的联系是在系统调用mount期间建立的。
通过将安装表中的设备号字段复制,可防止两个系统调用mount使用统一表项防止再次安装同一文件系统。
内核找出被安装文件系统的根索引节点,并将指向该索引节点的指针保存在安装表中。对用户而言,安装点的目录和被安装的文件系统的根在逻辑上是等价的。内核通过使他们在安装表中同时存在,来建立它们的等价关系,而进程再也不能存取安装点目录的索引节点了。
2) 在文件路径名中跨越安装点
在执行cd时,内核首先在安装点的文件系统中取出索引节点,发现它有”安装点标志“,就在安装表中找出被安装的文件系统的根索引节点,并存取该文件系统的根索引节点。
3) umount
内核释放被卸载设备的索引节点,并在安装表中超找对应表项,清除”安装点标志“
15. link
在新文件父目录的空槽位置,将目的文件名和源文件索引节点号写到该槽中。
读取源或目标文件索引节点,并增加引用数后,需立即释放索引节点的锁,以免引起死锁。
16. unlink
通过下面步骤删除文件连接:1)从父目录中删除文件名,即把索引节点置为0;2)iput释放文件索引节点;3)回收该内核占用的磁盘块。
文件系统一致性:通过特定的顺序进行写磁盘操作,能够使系统发生故障时文件系统的破坏达到最小。
临时文件:进程中通常打开一个文件,然后马上调用unlink删除,并继续读写。程序退出时,临时文件会被自动删除。过程如下:
1)open。文件引用数增加一。
2)unlink。清除目录项,其它进程再无法通过文件名引用该文件。在调用iput时,由于引用数为1,不会清除文件内容。
3)读写文件。通过文件描述符,能够获取索引节点,读写文件。
4)关闭文件(或进程exit)时,文件引用数为0,文件删除。
阅读(1917) | 评论(0) | 转发(2) |