分享
 
 
 

FreeBSD 核心 (2)

王朝system·作者佚名  2006-11-23
窄屏简体版  字體: |||超大  

FreeBSD核心探讨.5.驱动程序篇

2.2 虚拟文件系统和v-node

FreeBSD在disk上的除了ffs以外还可以操作各种各样的文件系统。主要的如

下:

。cd9660

可以对ISO9660形式的cd-rom的目录/文件构造的文件系统进行mount,

locate等目录层的操作

。ms-dos

对ms-dos文件系统进行目录层次的mount,定位等操作

。mfs

通过使用虚拟内存对swap区的一部分进行unix文件系统的构造,定位

作为目录的一部分进行读写

。nfs

由nfs server提供的remote目录级进行mount,定位的目录层操作。

。null

对已经存在的目录层的使用别名

。union

对已有的目录A(上层)在下层目录B上进行重叠 (不大理解这的意思

,大概是在下层目录里面又嫁接了上层目录的意思:译者)。文件名的查

找由上层优先进行。没有的话就转道下层。如果对下层的文件进行写操作

,它的拷贝就在上层上进行。举例说明,作业目录在上层,但cd-rom的源

在下层,两个目录重叠,那么编译source的时候,就相当方便了。

。procfs

对于进程号的目录作成mount point。通过文件名对各个目录的进程进行

控制。

。kernfs

为了对动作中的kernel有关的信息进行参考,而作成的mount point

。fdesc

对于各个进程,用它所打开的文件柄对应的文件作成的mount point

实际上,在核心内部,为了对它们进行统一操作,就对文件系统和v-node

进行抽象化,实际的处理过程就是调用各类的文件系统的模块进行处理。

2.2.1对虚拟文件系统的操作

各个文件系统可以提供的操作的一览如下,它在struct vfsops

(@sys/mount.h)里面定义:

。对文件系统进行mount的操作

。本文件系统的开始动作的操作

。本文件系统的umount操作

。表达文件系统的根的v-node的查找操作

。对一般用户的权限控制

。取得文件系统的状态

。内存内的管理信息写入介质中

。从i-node到v-node的取得操作

。v-node和nfs的文件柄的相互变换的操作

。文件系统实际的模块的初始化

对于文件系统,各个实际的操作routine在vfsops的形式提供准备工作。各个文件系

统的vfsops,在以下的表里的source进行定义:

--------------------------------------------------------------

file system vfsops的定义 source

--------------------------------------------------------------

ufs ufs_vfsops ufs/ffs/ffs_vfsops.c

cd9660 cd9660_vfsops isofs/cd9660/cd9660_vfsops.c

msdos msdosfs_vfsops msdosfs/msdosfs_vfsops.c

mfs mfs_vfsops ufs/mfs/mfs_vfops.c

nfs nfs_vfsops nfs/nfs_vfsops.c

null null_vfsops miscfs/nullfs/null_vfsops.c

nuion union_vfsops miscfs/union/union_vfsops.c

procfs procfs_vfsops miscfs/procfs/procfs_vfsops.c

kernfs kernfs_vfsops miscfs/kernfs/kernfs_vfsops.c

fdesc fdesc_vfsops miscfs/fdesc/fdesc_vfsops.c

devfs devfs_vfsops miscfs/devfs/devfs_vfsops.c

ext2fs ext2fs_vfsops gnu/ext2fs/ext2_vfsops.c

lfs lfs_vfsops ufs/lfs/lfs_vfsops.c

portal portal_vfsops miscfs/portal.portal_vfsops.c

umap umap_vfsops miscfs/umapfs/umap_vfsops.c

---------------------------------------------------------------

这些就是文件系统的实际模块(*_vfsops.c),文件系统名称,文件系统号等等

在struct vfsconf(@sys/mount.h)里面汇总,各个模块里用宏VFS_SET()进入核

心。

根据main()(@kern/init_main.c),在kernel初始化的过程中,vfsinit()

(@kern/vfs_init.c)里面有

struct vfsconf *vfsconf[MOUNT_MAXTYPE+1];

struct vfsops *vfssw[MOUNT_MAXTYPE+1];

各种东西的设定,这些是,管理mount信息的struct mount(@sys/mount.h)的成员

mnt_vfc和mnt_op要指定所对应的文件系统的vfsconf,vfssw。还有宏VFS_操作名

(struct mount *,..)里,可以各个操作的调用。

2.2.2对v-node的操作

虚拟文件系统就是通过对i-node的抽象化之后的v-node的文件/目录进行io处理。

为了这个目的,作为对v-node的适用处理,有

。从v-node到文件名的查找,返回v-node

。打开/关闭v-node

。检查是否可能访问v-node

。得到-v-node的属性

。设定v-node的属性

。对v-node的输入/输出

。扩展v-node的硬连接和符号连接

。对v-node进行目录的作成和删除

。。。。

由这里开始,一共定义了41个。

v-node由struct vnode(@sys/vnode.h)里定义,作为类别在enum vtype

里面表示出来,一共是9种类。它包含着在各个文件系统上对各个的文件/目录(包

括特殊)文件进行统一识别的信息。为了实现这样,v-node一连串的操作就是在各

模块里通过宏VNODEOP_SET()和核心通讯。这些操作名和实现的routine只需要必要

的几个对应。在核心初始化里,vfs_opv_init()(@kern/vfs_init.c)就使从数据得

到的号码一一对应,收集了routine的地址的同一size的配列再进行组合。各个

v-node就一个一个指向这些配列。对v-node的操作在vnode_if.h里定义:

它以

VOP_操作名(v-node,...)

的统一形式记述。

下面是对v-node的操作的定义source:

------------------------------------------------------------------------

各个v-node操作(vnodeopv) source

------------------------------------------------------------------------

cd9660_fifoop_opv_desc isofs/cd9660/cd9660_vnops.c

cd9660_specop_opv_desc isofs/cd9660/cd9660_vnops.c

cd9660_vnodeop_opv_desc isofs/cd9660/cd9660_vnops.c

dead_vnodop_opv_desc miscfs/deadfs/dead_devfs_vnops.c

devfs_vnodeop_desc miscfs/devfs/devfs_vnops.c

ext2fs_fifoop_opv_desc gnu/ext2fs/ext2fs_vnops.c

ext2fs_specop_opv_desc gnu/ext2fs/ext2fs_vnops.c

ext2fs_vnodeop_opv_desc gnu/ext2fs/ext2fs_vnops.c

fdesc_vnodeop_opv_desc miscfs/fdesc/fdesc_vnops.c

ffs_fifoop_opv_desc ufs/ffs/ffs_vnops.c

ffs_specop_opv_desc ufs/ffs/ffs_vnops.c

ffs_vnodeop_opv_desc ufs/ffs/ffs_vnops.c

fifo_nfsv2nodeop_opv_desc nfs/nfs_vnops.c

fifo_vnodeop_opv_desc miscfs/fifofs/fifo_vnops.c

kernfs_vnodeop_opv_desc miscfs/kernfs/kernfs_vnops.c

lfs_fifoop_opv_desc ufs/lfs/lfs_vnops.c

lfs_specop_opv_desc ufs/lfs/lfs_vnops.c

lfs_vnodeop_opv_desc ufs/lfs/lfs_vnops.c

mfs_vnodeop_opv_desc ufs/mfs/mfs_vnops.c

msdosfs_vnodeop_opv_desc msdosfs/msdosfs_vnops.c

nfsv2_vnodeop_opv_desc nfs/nfs_vnops.c

null_vnodeop_opv_desc miscfs/nullfs/null_vnops.c

portal_vnodeop_opv_desc miscfs/portal/portal_vnops.c

procfs_vnodeop_opv_desc miscfs/procfs/procfs_vnops.c

spec_nfsv2nodeop_opv_desc nfs/nfs_vnops.c

spec_vnodeop_opv_desc miscfs/specfs/spec_vnops.c

umap_vnodeop_opv_desc miscfs/umapfs/umap_vnops.c

union_vnodeop_opv_desc miscfs/union/union_vnops.c

------------------------------------------------------------------------

这个基础上,spec_vnodeop_opv_spec里描述的操作群就是device driver

interface的东西!!

( 本小节完,待本岛主有空再继续 )

FreeBSD核心探讨.6.驱动程序篇

2.3 mount根目录之前的处理概要

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也可以,而且这样可以获得更高的效率,这样看起来,就象实际上

是连续操作了。

(代续)

FreeBSD核心探讨.7.驱动程序篇

2.2.5系统调用open()的处理概要

进程通过系统调用read()/write()进行io处理,它由文件描述符指定对哪里进

行i/o,文件描述符是0以上的整数,它在各个进程的struct proc的成员

struct filedesc *p_fd(struct filedesc(@sys/filedesc.h))保留的struct file

((@sys/file.h)进行选择添加。对struct file,它含有从文件的头的输入输出的byte

位置,输入操作,输出操作,输入输出控制,输入输出的准备状态的检查,执行close

的routine,以及描述io处理对象的信息(v-node,socket,pipe) 。系统调用open()

(@kern/vfs_syscalls.c)就是把包含路径信息的v-node找寻出来,为了对它进行io处理,

先要对struct file进行初始化,然后返回文件描述符。

从路径名查找v-nodehe和io准备操作由vn_open()(@kern/vfs_vnops.c)承担。

vn_open()通过namei()(@kern/vfs_lookup.c)查找路径对应的v-node名,由VOP_OPEN()

调用不同的v-node定义的准备过程routine。例如,有如下的处理方法。

。普通的file/directory

调用ufs_open()(@ufs/ufs/ufs_vnops.c),检查open的mode

。特殊设备文件

调用spec_open()(@miscfs/specfs/spec_vnops.c)

文字型 调用device driver的open routine

快型 mount的时候出错。如果不是这样,就调用device driver的

open routine。

回过头来,namei()的任务是就是,对于指定的路径名,对应于跟目录或者当

前目录的v-node作为起点,通过lookup()(@kern/vfs_lookup.c)进行v-node查找。

lookup()从路径名开始的v-node(VDIR)开始查找。找到了的v-node作为新的起点继续进行

查找下一步的要素名,然后得到目的的v-node。这个时候,根据v-node的不同,目录的检

索方法也就不同。各个要素的实际检索由VOP_LOOKUP()来做。

2.2.6系统调用read()的处理概要

open()取得文件描述符后,对它的输入处理,有如下的流程。指定的文件描述符

的struct file内登记的处理routine有vn_read()(@kern/vfs_vnops.c),vn_write(),

vn_ioctl(),vn_select(),vn_closefile(),v_node

登记的操作routine不能分开使用。vn_*()里,只有在合适的前缀操作下,才能正确调用。

read()首先在struct uio(@sys/uio.h)登记进程指定的buffer的位置和长度。

执行read()后,vn_read()向struct file设定登记的文件的读写位置,然后调用VOP_READ()。

根据读出来的byte数,读写位置相应增加。

VOP_READ()的call routine则是与v-node有关,就象下图一样。

vn_read()

文字型/块型 |

/------------------

| | file/directory

spec_read() ---------ffs_read()-------VOP_READ()

block型 | |

/---------------|char型 |

bread() device driver bread()

| |

spec_s

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有