发信人: liangvy()
整理人: hahalee(1999-04-09 17:30:30), 站内信件
|
(翻译:liangvy.icewolf.lenn)[[email protected]] [版权所有,不得书面出版]
2。2。3mount根目录之前的处理概要 mount根目录的时候,main()(@kern/init_main.c)的初始化的过程从xxx_vfs_mountroot() (@kern/init_mail.c)被调用开始。如果处理过程正常,就对rootvp设定包含了root的 v-node。 。main()的初始化过程中,configure()(@autoconf.c)被调用。在这个,io设备 初始化完了后,就转移到如下两个变量的地址:一个是mountroot,是处理mount的routine, 另一个是mountrootvfsops,是处理虚拟文件系统的routine。在本机磁盘中,就进入变量 rootdev所指定的disk号中。这里就是,假定本机磁盘 mountroot vfs_mountroot mountrootvfsop &ufs_vfsops rootdev boot disk number
。xxx_vfs_mountroot()(@kern/init_main.c) 运行(*mountroot)(mountrootvfsops)后,就指明了root file system的mount. 。vfs_mountroot()(@kern/vfs_conf.c) 管理mount的了文件系统的信息的struct mount(@sys/mount.h),对它进行确认 ,然后设定传递过来的对虚拟文件系统的操作群(&ufs_vfsops),才进行"root" 标记。根据VFS_MOUNT(mp,...)进行mount这个虚拟文件系统。mount成功后,就 追加file system的list。这里,由于传递了&ufs_vfsops,就可以调用 ffs_mount()(@ufs/ffs/ffs_vfsops.c) 。ffs_mount() 首先调用bdevvp()(@kern/vfs_subr.c),进行VBLK类别,spec_vnodeop_p (@misc/specfs/spec_vnops.c) v-node操作,保证设定了驱动号的rootdev的 v-node的最新信息,然后设定rootvp。最后,通过ffs_mountfs()调用进行实际 的mount rootvp操作。 。ffs_mountfs() 各种各样的检查完了后,调用VOP_OPEN(),打开rootvp的v-node。在这里,如果 v-node的v_op成员在spec_vnodeop_p存在的话,就调用spec_open()(@misc/ specfs/spec_vnops.c)。 .spec_open 由于VBLK里包含v-node的种类,从v-node指定的device号取得major的号, 调用对应driver的XXopen() routine
续上,由VOP_IOCTL()(还是的通过spec_ioctl()(@misc/specfs/spec_vnops.c)) 可以得到partition信息,然后该检查super block的内容。正确的话,就在struct ufsmount(@ufs/ufs/ufsmount.h)设定unix file system,这样处理过程就完了。
2。2。4 struct buf 和block的输入输出routine 前节的ffs_mountfs()提到使用bread()(@kern/vfs_bio.c)读出partition的 super block。这个接口函数很快就会解释。它主要用于读取block型的device到 kernel内部的buffer中。 bread(struct vnode *vp, /*(in)输入对象的v-node*/ daddr_t blkno, /*(in)block号*/ int size, /*(in)读出的byte数量,block长的倍数*/ struct ucred * cred,/*(in)权限信息*/ struct buf ** bpp)/*(out)存储读来的data*/ 同样的buffer link后的block输出的子程序是bwrite()。 bwrite(struct buf *bp) /*(out)可以输出的struct buf*/ 两者之间共同的地方就是struct buf(@/sys/buf.h),它用于io处理中给device driver 做桥梁作用的数据结构。它记录了v-node,io的区别,可以io的block位置/byte数,存 储实际data buffer的address,io处理的进展情况等。 bread则通过getblk()对block输入的结构struct buf进行操作。getblk()调用在核心 管理buffer link和返回指定大小的block的struct buf。这个(缓冲区)内容在目的 block是否存在与指定v-node的指定位置block是否已经构成缓冲环有关。struct buf 里面有一个标志位,当缓冲环内容变化是,这个标志位就会改变。bread()根据这个 flag判断block是否已经缓冲,如果已经完成,它就终止退出。如果不是这样,则在 struct buf的mark里面标志,然后调用VOP_STRATEGY()。在v-node登记的strategy routine记录了io处理的过程,所以bread()当实际的处理完了后,就调用biowait() 进入等待状态。然后,就转移到别的进程A。io处理完了后,调用biodone(),进程A 也可以继续进行。还有,调用bread()的一边,当完成操作后,就调用brelse(),在 里面对struct buf的flag重新设置,让它对别的程序开放。 bwrite也是同样的通过VOP_STRATEGY()对io处理要求进行登记,同时也调用biowait() 进入等待状态,同样,当实际操作完了后,也设置flag进行复位,使得其他程序可以 使用io,当空闲的时候,io就挂起,转向其他进程处理。 进程等待进入的时候,当然不限于只是调用biowait()。在bread()或者bwrite()之前, 系统必须分配足够的资源供它使用,比如一些缓冲区等。当进行实际io时候,1个block 也可以,多个block也可以,而且这样可以获得更高的效率,这样看起来,就象实际上 是连续操作了。 (代续) --
-- ※ 来源:.网易 BBS bbs.netease.com.[FROM: www2.dt.sanyo.co.jp]
|
|