2005-11-19 17:01
sinister
也说说 SOLARIS 内核 vop_read()/vop_write() 与 vop_map() 的区别
system call 与 vfs/vnode 函数对应关系。(假设下层实际文件系统是 UFS)
mmap()->vop_map()->ufs_map()
read()->vop_read()->ufs_read()
write()->vop_write()->ufs_write()
这些操作都会建立映射文件来读/写数据,其关键在于是哪个 segment 驱动来
映射,映射到什么地方,vop_map() 是由 seg_vn 驱动映射,当没有物理内存
对应情况下产生 page fault 触发 segvn_fault() 函数,在其中调用
vop_getpage() 完成映射,seg_vn 驱动会将数据直接映射到当前进程的地址
空间,这样以后的每次读/写不用调用系统调用来进行 app->kernel 的特权切
换和复制数据。而 vop_read() / vop_write() 则是由 seg_map 驱动来映射,
没有物理内存对应情况下产生 page fault 触发 segmap_fault() 函数,在其
中同样调用 vop_getpage() 完成映射。segmap 驱动将内容映射到内核地址空
间,以后每次读/写都要调用系统调用,从内核空间复制数据到用户空间或从
用户空间复制数据到内核空间。我们可以看到不论是 vop_map() 还是
vop_read() / vop_write() 最终都将调用 vop_getpage(), vop_putpage() 来完
成操作(这里也有特例,比如 swap file 的 I/O 调用的是 vop_pageio 而不是
vop_getpage()),但调用的 segment 驱动不同,映射的地方也不同。可以说
seg_map 驱动是专门为 vop_read() / vop_write() 等调用提供的,seg_map 驱
动不象 seg_vn 驱动那样要处理所有进程的内存操作,不提供 share memory 与
copy on write 等特性,只为处理文件读/写,目的是为了提高效率。
以上是我个人理解,欢迎探讨。