复习笔记|第九、十章 Linux文件系统《操作系统原理教程》
大纲问题回答(精简版)
1. Ext2文件卷的布局?各部分的作用是什么?
Ext2文件卷的布局
◼ Ext2把磁盘块分为组,每组包含存放在相邻磁道的数据块和索引节点。块组的大小相等并顺序安排。
◼ Ext2用“块组描述符”来描述这些块组本身的结构信息,同时将超级块和所有块组描述符重复存储于每个块组中。
◼ Ext2通过“位图”来管理每个块组中的磁盘块和索引节点。盘块位图,索引节点位图。
◼ 超级块存放整个文件卷的资源管理信息。
◼ 索引节点存放文件的管理控制信息。
◼ 只有块组0中所包含的超级块和块组描述符才由内核使用,而其余的超级块和块组描述符保持不变,事实上,内核甚至不考虑它们。
◼ 盘块位图必须存放在一个单独的块中
◼ 索引节点位图也必须存放在一个单独块中
2. Linux系统把一般的文件目录项分成哪两部分?这样做的好处是什么?
◆简单目录项、索引节点
◼ 把通常的文件目录项分成简单目录项和索引节点两部分。
◼ 简单目录项包含了文件名和索引节点号等,可以提高文件目录的检索速度。
◼ 系统只保留一个索引节点,就可实现多条路径共享文件,减少信息冗余。(硬链接)
3. Linux文件系统的索引节点中,索引表划分成几级?文件的索引表是如何增长的?要求能够利用索引表实现将文件中的字节地址转换成文件的物理块的操作。
◆直接索引、一次间接索引、二次间接索引、三次间接索引
索引表
◼ 索引表:是一个有15个元素的数组,每个元素占4B。数组的15个元素有4种类型。
◼ 最初的12个元素是直接索引项,给出文件最初的12个逻辑块号对应的物理块号。
◼ 索引12是一次间接索引块,对应的文件逻辑块号从12到(b/4)+11,b是盘块大小。
◼ 索引13是二次间接索引块,对应的文件逻辑块号从b/4+12到 (b/4)2+(b/4)+11。
◼ 索引14是三次间接索引块,对应的文件逻辑块号从(b/4)2+(b/4)+12到(b/4)3+(b/4)2+(b/4)+11。
索引表
4. 硬链接和符号链接的区别?
符号链接文件
◼ 当符号链接文件的路径名小于60个字符时,就存放在i_block[ ]中;当大于60时,需要一个单独的数据块。可以跨文件系统。
◼ 设备文件、管道文件、套接字文件:信息存放在索引节点中,无需数据块。
符号链接又称作软链接
区别:1、硬链接时文件重命名或文件移动不会改变链接指向,符号链接时文件重命名或文件移动则使链接断开;2、硬链接只能链接文件,符号链接可以链接文件和文件夹;3、符号链接可以跨不同的文件系统创建,硬链接则不可以跨不同的文件系统创建。
5. Linux文件系统如何管理空闲存储空间?
P199
1.空闲磁盘块的分配
当内核要为普通文件分配一个磁盘块时, 调用ext2_ get blok()函数。先检查指定磁盘块是否在页高速缓存中,若在,立即返回。否则,分配一块。调用格式为:
ext2_ get_ block();
当分配成功时,修改Ext2 相关的数据结构:索引节点对象的文件索引表,减少超级块对象的空闲块计数等。
为了减少文件的碎片,Ext2 文件系统设法在为文件分配的最近一块附近分配一个新块。如果失败,就在包含该文件索引节点的块组中分配一块。 否则,在其他块组中分配一块。同时采用预分配策略,一次可分配多达 8个相邻的磁盘块。为了减少不必要的浪费,当文件关闭、或文件被截短、或下一个写操作不是顺序写时,通过调用ext2_ free_block()函数,释放还没有使用的预分配块。
ext2_ get_block()函数是通过调用ext2 alloc block()函数实现分配一个磁盘块的。ext2_get_block(传递给该函数的参数有指向索引节点对象的指针、目标逻辑块号和错误返回码变量。ext2 get_block()函数根据下列原则确定目标逻辑块号:
●如果要求目标逻辑块号与前面刚分配的块是文件的连续块号,则目标逻辑块号=前面刚分配的逻辑块号+1
●如果已经为文件分配过至少一个块,且目标逻辑块号与前面刚分配的块不是文件的连续块号,则目标逻辑块号应该是这些块的逻辑块号中的一个,以便分配时以它做参考进行分配。
●如果前面两者都不符合,则目标逻辑块号就是索引节点所在块组中的第一个逻辑块号,而且不必空闲。
ext2_ alloc block()函数首先检查目标逻辑块号是否指向预分配块中的一块。如果是,分配一块并返回它的逻辑块号。否则释放所有剩余的预分配块并调用ext2_new_block()函数分配一个新的磁盘块。ex2 new block0)函 数根据传递的参数,具体实现如下:
(1)如果传递给ex12_aloc_block()函数的目标逻辑块号为空闲的,就分配它;
(2)如果不空闲,检查目标逻辑块后的其他块之中是否还有空闲的块。如果有,就分配一块。如果没有,转(3)。
(3)从包含目标逻辑块的块组开始,查找所有的块组。对于每个块组,寻找至少包含有8个相邻空闲块的一组盘块; 若找到,进行8个块的预分配;如果没有找到,就分配一个独立的空闲块。
(4)若已经进行了8个块的预分配,则修改磁盘索引节点的i_prealloc_block和i_prealloc count 字段为适当的块号和块数,并返回。
2.空闲磁盘块的回收
当进程要删除或截短一个文件时,要释放文件不再占用的磁盘块。通过调用ext2_ truncate (ptr) 函数完成。其调用语法为:
ext2 truncate (ptr) ;
ptr为文件索引节点对象的指针。该函数扫描磁盘索引节点的i block 数组,以确定所有要释放的数据块的位置。然后反复调用ext2_ free_ block()函 数释放这些块。ext2_ free block()函数接收的参数为:文件索引节点对象的指针、要释放的第一个磁盘块的块号和要释放的块数。
实现功能:
(1)获得要释放块所在块组的块位图。
(2)把块位图中要释放块对应位清零,并把位图所在的缓冲区标记为脏。
(3)增加该块组和超级块的空闲块计数,并把相应的块组和超级块的缓冲区标记为脏等。
(4)根据标记为脏的信息修改磁盘相应的数据结构。
6. VFS通用文件模型中的四个主要对象?
◼ 超级块对象:Linux为每个安装好的文件系统都建立一个超级块对象。
◼ 索引节点对象:对于具体文件系统,代表一个文件,对应于存放在磁盘上的FCB。
◼ 目录项对象:dentry (directory entry)
◼ 文件对象:记录了进程与打开的文件之间的交互信息。
7. Linux系统中,进程打开一个磁盘文件要涉及哪些数据结构?了解:它们各有哪些关键字段?他们的作用是什么?
参考图10.2。
索引节点对象
struct inode { P207
unsigned long i_ino; 磁盘索引节点号
atomic_t i_count; 该对象的引用计数
nlink_t i_nlink; 硬链接计数
struct inode_operations *i_op; P209
struct address_space *i_mapping;……}
struct ext2_inode_info { /*内存索引节点*/
……; struct inode vfs_inode; ……
}; P196
文件对象
struct file { P210
struct list_head f_list; 文件对象链表
struct dentry *f_dentry; 指向目录项对象
atomic_t f_count; 该对象的引用计数
loff_t f_pos; 文件的当前读写位置
struct file_operations *f_op;
struct address_space *f_mapping; 映射
……}
没有对应的磁盘映像。
目录项对象
struct dentry { P212
atomic_t d_count; 引用计数
struct inode *d_inode; 指向inode对象
struct dentry *d_parent; 指向父目录项对象
struct list_head d_alias; 属于同一inode的
dentry链表
struct dentry_operations *d_op; 方法
……}
没有对应的磁盘映像。
与进程打开文件相关的数据结构
Struct task_struct{
……
struct files_struct *files; 指向进程打开文件信息
…}
files_struct
struct files_struct { P214
struct file **fd; 指向文件对象指针数组
struct file *fd_array[ ]; 文件对象指针数组
……}
该数组包含32/64个文件对象指针,若不够用,内核就分配一个更大的数组,地址放在fd字段。
每个进程最多同时打开的文件数为1024个。
8. 一个文件在使用与不用时各占用系统哪些资源?
使用时是CPU资源、主存和软件资源 ,不使用是外设
9. 安装表的作用是什么?
内核将安装点与被安装的文件系统信息保存在vfsmount结构中,形成一个链式安装表。
struct vfsmount {
struct dentry *mnt_mountpoint;
/*指向安装点的目录项对象*/
struct dentry *mnt_root;
/*指向被安装文件系统的根目录*/
……
}
mount(要安装的文件系统类型,块特别文件路径名,安装点的目录路径名)
块特别文件路径名:是被安装的文件系统所在的块设备文件路径名。P222
mount –t ntfs /dev/hda2 /mnt/ntfs
大纲问题回答
1. Ext2文件卷的布局?各部分的作用是什么?(4)
Ext2文件卷的布局
◼ Ext2把磁盘块分为组,每组包含存放在相邻磁道的数据块和索引节点。块组的大小相等并顺序安排。
◼ Ext2用“块组描述符”来描述这些块组本身的结构信息,同时将超级块和所有块组描述符重复存储于每个块组中。
◼ Ext2通过“位图”来管理每个块组中的磁盘块和索引节点。盘块位图,索引节点位图。
◼ 超级块存放整个文件卷的资源管理信息。
◼ 索引节点存放文件的管理控制信息。
◼ 只有块组0中所包含的超级块和块组描述符才由内核使用,而其余的超级块和块组描述符保持不变,事实上,内核甚至不考虑它们。
◼ 盘块位图必须存放在一个单独的块中
◼ 索引节点位图也必须存放在一个单独块中
Ex2 文件卷有若干磁盘块组成(1 个引导块和 n 个块组)。每个块组又由超级块、块组描述符、数据块位图、文件的索引节点位图、索引节点区和文件数据区组成。
(1)引导块。Ex2 文件卷的第一个盘块不被 Ex2 文件系统使用,他用作 Linux 系统的引导块或保留不用。引导块用以读入并启动操作系统。只有根文件系统的引导块才起作用。
(2)块组结构。每组包含存放在相邻磁道的数据块和索引节点。块组的大小相等并顺序安排。
采用这种结构,可以用较少的平均寻道时间访问在磁盘一个单独块组中的文件。
(3)超级块。存放整个文件卷的资源管理信息。
(4)数据块位图。记录文件数据区各个盘块的使用情况。
(5)索引节点位图。记录索引节点区各个索引节点的使用情况。
(6)索引节点区。存放文件的索引节点,一个索引节点存放一个文件的管理和控制信息。
(7)文件数据区。存放普通文件和目录文件。
2. Linux系统把一般的文件目录项分成哪两部分?这样做的好处是什么?(2)
◼ 把通常的文件目录项分成简单目录项和索引节点两部分。
◼ 简单目录项包含了文件名和索引节点号等,可以提高文件目录的检索速度。
◼ 系统只保留一个索引节点,就可实现多条路径共享文件,减少信息冗余。(硬链接)
3. Linux文件系统的索引节点中,索引表划分成几级?文件的索引表是如何增长的?要求能够利用索引表实现将文件中的字节地址转换成文件的物理块的操作。(5)
◆直接索引、一次间接索引、二次间接索引、三次间接索引
索引表
◼ 索引表:是一个有15个元素的数组,每个元素占4B。数组的15个元素有4种类型。
◼ 最初的12个元素是直接索引项,给出文件最初的12个逻辑块号对应的物理块号。
◼ 索引12是一次间接索引块,对应的文件逻辑块号从12到(b/4)+11,b是盘块大小。
◼ 索引13是二次间接索引块,对应的文件逻辑块号从b/4+12到 (b/4)2+(b/4)+11。
◼ 索引14是三次间接索引块,对应的文件逻辑块号从(b/4)2+(b/4)+12到(b/4)3+(b/4)2+(b/4)+11。
索引表
4. 硬链接和符号链接的区别?(2)
硬链接:为同一文件取新的符号名;
符号链接:使用符号链接文件(一种极小的文件)存储欲共享文件的绝对路径;
符号链接文件
◼ 当符号链接文件的路径名小于60个字符时,就存放在i_block[ ]中;当大于60时,需要一个单独的数据块。可以跨文件系统。
◼ 设备文件、管道文件、套接字文件:信息存放在索引节点中,无需数据块。
符号链接又称作软链接
区别:1、硬链接时文件重命名或文件移动不会改变链接指向,符号链接时文件重命名或文件移动则使链接断开;2、硬链接只能链接文件,符号链接可以链接文件和文件夹;3、符号链接可以跨不同的文件系统创建,硬链接则不可以跨不同的文件系统创建。
5. Linux文件系统如何管理空闲存储空间?(1)
文件的数据块和其索引节点尽量在同一个块组中。
文件和它的目录项尽量在同一个块组中。
父目录和子目录尽量在同一个块组中。
每个文件的数据块尽量连续存放。
P199
1.空闲磁盘块的分配
当内核要为普通文件分配一个磁盘块时, 调用ext2_ get blok()函数。先检查指定磁盘块是否在页高速缓存中,若在,立即返回。否则,分配一块。调用格式为:
ext2_ get_ block();
当分配成功时,修改Ext2 相关的数据结构:索引节点对象的文件索引表,减少超级块对象的空闲块计数等。
为了减少文件的碎片,Ext2 文件系统设法在为文件分配的最近一块附近分配一个新块。如果失败,就在包含该文件索引节点的块组中分配一块。 否则,在其他块组中分配一块。同时采用预分配策略,一次可分配多达 8个相邻的磁盘块。为了减少不必要的浪费,当文件关闭、或文件被截短、或下一个写操作不是顺序写时,通过调用ext2_ free_block()函数,释放还没有使用的预分配块。
ext2_ get_block()函数是通过调用ext2 alloc block()函数实现分配一个磁盘块的。ext2_get_block(传递给该函数的参数有指向索引节点对象的指针、目标逻辑块号和错误返回码变量。ext2 get_block()函数根据下列原则确定目标逻辑块号:
●如果要求目标逻辑块号与前面刚分配的块是文件的连续块号,则目标逻辑块号=前面刚分配的逻辑块号+1
●如果已经为文件分配过至少一个块,且目标逻辑块号与前面刚分配的块不是文件的连续块号,则目标逻辑块号应该是这些块的逻辑块号中的一个,以便分配时以它做参考进行分配。
●如果前面两者都不符合,则目标逻辑块号就是索引节点所在块组中的第一个逻辑块号,而且不必空闲。
ext2_ alloc block()函数首先检查目标逻辑块号是否指向预分配块中的一块。如果是,分配一块并返回它的逻辑块号。否则释放所有剩余的预分配块并调用ext2_new_block()函数分配一个新的磁盘块。ex2 new block0)函 数根据传递的参数,具体实现如下:
(1)如果传递给ex12_aloc_block()函数的目标逻辑块号为空闲的,就分配它;
(2)如果不空闲,检查目标逻辑块后的其他块之中是否还有空闲的块。如果有,就分配一块。如果没有,转(3)。
(3)从包含目标逻辑块的块组开始,查找所有的块组。对于每个块组,寻找至少包含有8个相邻空闲块的一组盘块; 若找到,进行8个块的预分配;如果没有找到,就分配一个独立的空闲块。
(4)若已经进行了8个块的预分配,则修改磁盘索引节点的i_prealloc_block和i_prealloc count 字段为适当的块号和块数,并返回。
2.空闲磁盘块的回收
当进程要删除或截短一个文件时,要释放文件不再占用的磁盘块。通过调用ext2_ truncate (ptr) 函数完成。其调用语法为:
ext2 truncate (ptr) ;
ptr为文件索引节点对象的指针。该函数扫描磁盘索引节点的i block 数组,以确定所有要释放的数据块的位置。然后反复调用ext2_ free_ block()函 数释放这些块。ext2_ free block()函数接收的参数为:文件索引节点对象的指针、要释放的第一个磁盘块的块号和要释放的块数。
实现功能:
(1)获得要释放块所在块组的块位图。
(2)把块位图中要释放块对应位清零,并把位图所在的缓冲区标记为脏。
(3)增加该块组和超级块的空闲块计数,并把相应的块组和超级块的缓冲区标记为脏等。
(4)根据标记为脏的信息修改磁盘相应的数据结构。
6. VFS通用文件模型中的四个主要对象?(5)
◼ 超级块对象:Linux为每个安装好的文件系统都建立一个超级块对象。
◼ 索引节点对象:对于具体文件系统,代表一个文件,对应于存放在磁盘上的FCB。
◼ 目录项对象:dentry (directory entry)
◼ 文件对象:记录了进程与打开的文件之间的交互信息。
7. Linux系统中,进程打开一个磁盘文件要涉及哪些数据结构?了解:它们各有哪些关键字段?他们的作用是什么?(1)
参考图10.2。
索引节点对象
struct inode { P207
unsigned long i_ino; 磁盘索引节点号
atomic_t i_count; 该对象的引用计数
nlink_t i_nlink; 硬链接计数
struct inode_operations *i_op; P209
struct address_space *i_mapping;……}
struct ext2_inode_info { /*内存索引节点*/
……; struct inode vfs_inode; ……
}; P196
文件对象
struct file { P210
struct list_head f_list; 文件对象链表
struct dentry *f_dentry; 指向目录项对象
atomic_t f_count; 该对象的引用计数
loff_t f_pos; 文件的当前读写位置
struct file_operations *f_op;
struct address_space *f_mapping; 映射
……}
没有对应的磁盘映像。
目录项对象
struct dentry { P212
atomic_t d_count; 引用计数
struct inode *d_inode; 指向inode对象
struct dentry *d_parent; 指向父目录项对象
struct list_head d_alias; 属于同一inode的
dentry链表
struct dentry_operations *d_op; 方法
……}
没有对应的磁盘映像。
与进程打开文件相关的数据结构
Struct task_struct{
……
struct files_struct *files; 指向进程打开文件信息
…}
files_struct
struct files_struct { P214
struct file **fd; 指向文件对象指针数组
struct file *fd_array[ ]; 文件对象指针数组
……}
该数组包含32/64个文件对象指针,若不够用,内核就分配一个更大的数组,地址放在fd字段。
每个进程最多同时打开的文件数为1024个。
VFS和具体的文件系统系统之间主要通过几个数据结构:super_block, inode, dentry, file和address space以及对应的operations: sb_ops, i_ops, d_ops, f_ops和a_ops来实现文件系统的功能。
8. 一个文件在使用与不用时各占用系统哪些资源?
文件在不使用时仅占用外存资源,而文件在使用时会占用主存(内存)资源,因为Linux 的虚拟文件系统 VFS 会在主存中建立一系列的数据结构便于主存使用文件;
9. 安装表的作用是什么?(3)
将所有已安装的文件系统描述符链在一起
内核将安装点与被安装的文件系统信息保存在vfsmount结构中,形成一个链式安装表。
struct vfsmount {
struct dentry *mnt_mountpoint;
/*指向安装点的目录项对象*/
struct dentry *mnt_root;
/*指向被安装文件系统的根目录*/
……
}
mount(要安装的文件系统类型,块特别文件路径名,安装点的目录路径名)
块特别文件路径名:是被安装的文件系统所在的块设备文件路径名。P222
mount –t ntfs /dev/hda2 /mnt/ntfs