2、系统调用与驱动程序接口 对于使用文件描述符的系统调用的基本操作流程: 核心从用户文件描述符的指针找到系统打开文件表项和文件 的索引节点。 检查文件的类型,根据需要存取块设备或字符设备开关表。 > 从索引节点中抽取主设备号和次设备号。 > 使用主设备号为索引值进入相应的开关表。 > 根据用户所发的系统调用来调用开关表中的对应函数。 6
2、系统调用与驱动程序接口 对于使用文件描述符的系统调用的基本操作流程: 核心从用户文件描述符的指针找到系统打开文件表项和文件 的索引节点。 检查文件的类型,根据需要存取块设备或字符设备开关表。 从索引节点中抽取主设备号和次设备号。 使用主设备号为索引值进入相应的开关表。 根据用户所发的系统调用来调用开关表中的对应函数。 6
2、系统调用与驱动程序接口(续) 对设备文件的系统调用与对正规文件的系统调用之间的一个 重要区别是:当核心执行驱动程序时,对设备文件的索引节点是 不上锁的。 因为驱动程序会频繁地睡眠,以等待硬连接或数据的到来, 因此核心不能确定一个进程要睡眠多长时间。 如果对设备文件的索引节点上锁,则其它存取此节点的进程 (如通过系统调用stat)会因为本进程在驱动程序中睡眠,而无 限期地睡眠(等待)下去。 7
2、系统调用与驱动程序接口(续) 对设备文件的系统调用与对正规文件的系统调用之间的一个 重要区别是:当核心执行驱动程序时,对设备文件的索引节点是 不上锁的。 因为驱动程序会频繁地睡眠,以等待硬连接或数据的到来, 因此核心不能确定一个进程要睡眠多长时间。 如果对设备文件的索引节点上锁,则其它存取此节点的进程 (如通过系统调用stat)会因为本进程在驱动程序中睡眠,而无 限期地睡眠(等待)下去。 7
①算法:open*用于设备驱动程序的open* 输入:路径名,打开方式 输出:文件描述符 { 将路径名转换为索引节点,增加索引节点的引用计数; 与正规文件一样,分配系统打开文件表项和用户文件描述符; 从索引节点取主设备号和次设备号; if(块设备) { 使用主设备号作为查块设备开关表的索引值; 调用该索引值对应的驱动程序打开过程一传递参数为次设备号和打开方式: else*是字符设备*/ f 使用主设备号作为查字符设备开关表的索引值; 调用该索引值对应的驱动程序打开过程一传递参数为次设备号和打开方式: if(open在驱动程序中失败) 减少系统打开文件表项和索引节点的计数值: 8
① 算法:open /* 用于设备驱动程序的open */ 输入:路径名,打开方式 输出:文件描述符 { 将路径名转换为索引节点,增加索引节点的引用计数; 与正规文件一样,分配系统打开文件表项和用户文件描述符; 从索引节点取主设备号和次设备号; if (块设备) { 使用主设备号作为查块设备开关表的索引值; 调用该索引值对应的驱动程序打开过程——传递参数为次设备号和打开方式; } else /* 是字符设备 */ { 使用主设备号作为查字符设备开关表的索引值; 调用该索引值对应的驱动程序打开过程——传递参数为次设备号和打开方式; } if (open在驱动程序中失败) 减少系统打开文件表项和索引节点的计数值; } 8
②、算法:close 断开一个进程与设备的连接 a、搜索系统打开文件表(file表)以确认没有其他进程仍 然打开着这个设备。 既不能仅仅看fle表中的计数值来确认这是该设备的最 后一次关闭操作,因为几个进程可能通过不同的fle表项(读写指 针)来存取该设备; 也不能依靠活动索引节点表(inode表)的计数值来确定 这是否为最后一次关闭操作,因为可能有几个不同的文件代表同 一设备,例如: crw-rw-rw-1 root sys 9,1 Aug 62014 /dev/tty01 crw-rw-rw-1 root unix 9,1 Sep52015 /dev/tty02 虽然上述两个设备的名字不同,但它们的主设备号和此设备 号相同,因此是同一设备。有可能多个进程独立地打开这两个文 件,这些进程存取不同的inode,但却是对同一设备进行操作g
②、算法:close 断开一个进程与设备的连接 a、搜索系统打开文件表(file表)以确认没有其他进程仍 然打开着这个设备。 既不能仅仅看file表中的计数值来确认这是该设备的最 后一次关闭操作,因为几个进程可能通过不同的file表项(读写指 针)来存取该设备; 也不能依靠活动索引节点表(inode表)的计数值来确定 这是否为最后一次关闭操作,因为可能有几个不同的文件代表同 一设备,例如: crw-rw-rw- 1 root sys 9, 1 Aug 6 2014 /dev/tty01 crw-rw-rw- 1 root unix 9, 1 Sep 5 2015 /dev/tty02 虽然上述两个设备的名字不同,但它们的主设备号和此设备 号相同,因此是同一设备。有可能多个进程独立地打开这两个文 件,这些进程存取不同的inode,但却是对同一设备进行操作。9
②、算法:close 断开一个进程与设备的连接(续) b、对于一个字符设备,核心调用该设备对应的cose过程 并返回用户态。 对于一个块设备,首先判断该设备上是否为一个已安装 的文件系统。 如果是已安装的文件系统,则释放索引节点后返回。 如果不是已安装的文件系统,核心要做两件事: 搜索数据缓冲区高速缓冲,看是否有先前安装本 文件系统时遗留下来的数据块以“延迟写”的形式还 在内存中,还没有写回设备。如果有,则先写回这些 数据块。 在关闭本设备后,核心再扫描一次数据缓冲区高 速缓冲,使装有本设备数据块的缓冲区无效(释放到 空闲链表的表头),以使装有有效数据的缓冲区能在 内存中停留更长时间。 10
②、算法:close 断开一个进程与设备的连接(续) b、对于一个字符设备,核心调用该设备对应的close过程 并返回用户态。 对于一个块设备,首先判断该设备上是否为一个已安装 的文件系统。 如果是已安装的文件系统,则释放索引节点后返回。 如果不是已安装的文件系统,核心要做两件事: ① 搜索数据缓冲区高速缓冲,看是否有先前安装本 文件系统时遗留下来的数据块以“延迟写”的形式还 在内存中,还没有写回设备。如果有,则先写回这些 数据块。 ② 在关闭本设备后,核心再扫描一次数据缓冲区高 速缓冲,使装有本设备数据块的缓冲区无效(释放到 空闲链表的表头),以使装有有效数据的缓冲区能在 内存中停留更长时间。 10