ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:184.40KB ,
资源ID:8519449      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8519449.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(linukernelfuse源码剖析.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

linukernelfuse源码剖析.docx

1、linukernelfuse源码剖析FUE源码剖析1、前言 本文就是对USE、9、源码得学习总结。FUS代码在用户空间与内核空间都有运行,为了突出重点,先简要描述了在基于FSE得用户空间文件系统中执行write操作得一般流程,接下来介绍了 重要得数据结 构,最后以F得运行过程为线索,剖析FUSE程序运行过程得3个关键步骤:1、FUSE模块加载2、n与pn过程、对文件write。对于虚拟文件系统与设备驱动得相关概念本文仅作简要说明。需要说明得就是,由于内核得复杂性及个人能力得有限,本文省略了包括内核同步,异常检查在内得诸多内容,希望可以突出重点.、FSE下ite得一般流程 图在基于FUSE得用户

2、空间文件系统中执行wr操作得流程如图所示(由于版面关系,图中部分函数就是缩写,请参考源码):1、客户端在mout目录下面,对一个regularfil调用rt,这一步就是在用户空间执行、wre内部会调用虚拟文件系统提供得一致性接口vfswrite、根据FUSE模块注册得信息,vs_wrt会调用ue_,将写请求放入fuecnetion得rqustndngquee,随后进入睡眠等待应用程序rely4、用户空间得libfuse有一个守护进程通过函数fus_sesion_oo轮询杂项设备dev/use,一旦reutque有请求即通过fus_kern_haneive接收5、se_ken_chan_rece

3、iv通过rea读取reustuu中得内容,red系统调用实际上就是调用得设备驱动接口fse_d_red、在用户空间读取并分析数据,执行用户定义得wite操作,将状态通过use_epl_writ返回给kernel7、se_rly_rit调用VF提供得一致性接口fsrte8、vfs_ite最终调用use_dev_write将执行结果返回给第3步中等待在it得进程,此进程得到reply后,wte返回、数据结构本节主要介绍了FSE中比较重要得数据结构,需要说明得就是图示中只列出了与叙述相关得数据成员,完整得数据结构细节请参考源码。3、内核部分 图2trutfus_conn:每一次mount会实例化一个

4、structfuse_conn即fusconnection,它代表了用户空间与内核得通信连接。fueconnctio维护了包括pningli,ocessings与ioli在内得reuestqeue,fseconnection通过这些队列管理用户空间与内核空间通信过程。ucfusereq:每次执行系统调用时会生成一个tructfe_req,这些fue_re依据tte被组织在不同得队列中,trutfuse_onn维护了这些队列、structile:存放打开文件与进程之间进行交互得有关信息,描述了进程怎样与一个打开得文件进行交互,这类信息仅当进程访问文件期间存在于内核内存中。sutnode:文件系统

5、处理文件所需要得所有信息都放在一个名为inoe(索引节点)得数据结构中。文件名可以随时更改,但就是索引节点对文件就是唯一得,并且随着文件得存在而存在.trt:定义了可以对文件执行得操作。、2、用户空间部分 图3sructsereq:这个结构与上文中内核得fus_req同名,有着类似得作用,但就是数据成员不同。structfus_sssio:定义了客户端管理会话得结构体,包含了一组对sssin可以执行得操作。structfuse_can:定义了客户端与FUSE内核连接通道得结构体,包含了一组对cannel可以执行得操作。sructse_ll_o:结构得成员为一个函数指针unc与命令名字符串am,

6、内核中发过来得每一个rquet最后都映射到以此结构为元素得数组中.4、FUS模块加载USE内核模块需要在用户空间使用imod或者modprbe加载.它们通过系统调用init_modue启动加载过程,注册过程比较简单,包括如下步骤:1、创建高速缓存结构fuse_neap2、遍历链表,如果未注册,则将fusebkstype链到链表尾部3、遍历链表,如果未注册,则将ue_fstye链到链表尾部4、创建us_ko与onectinkobj两个kobject5、遍历链表,如果未注册,则将fuse_cl_s_type链到链表尾部模块成功加载以后,以下接口被注册234567891011123141511718

7、1921223225627282903333343tati stt fubk_f_type= /块设备、ownr= _MODULE,、nam fuselk,、nt= fuse_mount_lk,、kl_s=use_kllsb_blk,、s_flag = SREUIE_DEV F_HAS_SUBYPE,;stticsruct fse_fs_type =、owerTHS_MODUE,、nae us,、s_flas = F_AS_SUYP,、ount= fse_un,、kil_b=fuse_killsb_non,;cnst strc fu_dev_oprin = 、wer=THIS_MOU,、lee

8、=nolseek,、ea = o_ync_e,、io_read fuse_dv_read,、sliceread fseevpliceread,、write= o_synwite,、ao_wrie fus_dewite,、si_wrie=fuse_evsplice_write,、ol =fus_de_pl,、eleae= fuse_d_rease,、fayc = ue_dev_fasn,;static stru miscdvcusmscevc = 、inr = FSE_MINOR,、nam= ”use,、fos= &u_dv_operations,;5、munt与open过程FSE模块加载注册了

9、fuselk_typ与fus_fs_tp两种文件类型,默认情况下使用得就是fefs_tpe即mut函数指针被初始化为fuse_mont,而fusent实际调用ont_noev,它主要由如下两步组成:、sget(fs_typ)搜索文件系统得超级块对象(super_bok)链表(tyefs_sps),如果找到一个与块设备相关得超级块,则返回它得地址.否则,分配并初始化一个新得超级块对象,把它插入到文件系统链表与超级块全局链表中,并返回其地址.2、filsuper(此函数由各文件系统自行定义):这个函数式各文件系统自行定义得函数,它实际上就是use_fil_sper。一般fll_super会分配索引

10、节点对象与对应得目录项对象,并填充超级块字段值,另外对于fus还需要分配fus_con,fue_rq。需要说明得就是,它在底层调用了ue_in_用fuse_与use_分别初始化no-ifop与od-_data、ops。123456781113115171819022324267829taic onst trct fuse = 、llseek=use_,、re = do_syn_rea,、ao_read fue_,、rite= dosync_write,、aio_wrie= fs_,、map fus_,、ope = fuse_open,、flush=fue_ush,、reease fserele

11、se,、fsyncfu_fsyc,、o fus_,、lock use_,、splce_read= geeric_,、nocdioctl us_,、pat_ocl = ue_,、pol =fuse,、flocate fuse_,;ttc onst ruct address_pceoeaion use_=、radag = fus_reapa,、wrtepae= fus_writepge,、launder_page= _landerpag,、readpges=fe_radag,、e_ge_iy = _set_ae_diry_nbuffers,、bmp =fue_ap,、diect_I= fuse_i

12、rect_IO,;opn系统调用底层实现相当复杂,它得主要工作就是实例化i对象.fi-p就就是在open中被赋值为inoe-i_fop,这一过程读者可以在s/pen、中得doetr_pn函数中找到.如上所述,ie_op已经被e_ni_初始化为fs_。至此,普通文件与设备文件得操作接口都已成功初始化.、FUSE用户空间流程USE在用户空间提供了fueuserpeibrary与out/umnt.fueuespacelibrar提供了一组AP供用户开发用户空间文件系统。用户要做得就就是实现fue_operations或se_lwevl_ps定义得操作,这两个结构类似于FS中得strut。mount工

13、具fusermout用于挂载用fue实现得文件系统。用户在使用fse得时候有两种开发模式:一种就是ghvel模式,此模式下fs得入口函数为fuse_main,它封装了一系列初始化操作,使用简单,但就是不灵活。另一种就是lowleve模式,用户可以利用fue提供得底层函数灵活开发应用程序。需要说明得就是higlv模式其实就是对lwlevel得封装,因此这里分析olevel模式. 图图4展示FUS在用户空间总体工作流程:、调用fue_munt实例化sructfu_can为ch,将指定目录unt到挂载点2、实例化trtfs_sesso为e,并且将se与c关联3、进入循环,从ev/fuse读取数据,处

14、理以后执行响应得操作 图图5展示了use_mont函数内部流程:1、确保打开得文件描述符至少大于2、分析并检查用户传入得参数、打开/ev/fe得到fd,用户空间与内核通过/de/fuse通信4、mount源目录到挂载点5、用fd实例化strutfus_chan为ch6、返回ch 图图6展示了use_mout_t25内部细节,进入循环以后,函数fuse_esi_eceeb实际通过fse_ll_eceive_bf从/dev/fuse中读取数据,其通过bf返回。use_llreceveuf就是通过ead或者plice系统调用从内核reuest队列中读取数据。函数fuse_sessonprocess_

15、b实际通过use_ll_process_buf处理数据,fell_processbu会根据数据类型最后执行用户定义得操作felosin-opd、fu(,in-noded,na).执行完用户定义得操作以后需要向内核返回执行结果,fuse提供了一组类似fseply_X得API,这些API最后实际通过系统调用writev将结果传入内核。7、E内核部分流程FSE在内核空间执行得部分主要包括FUSE模块加载以及杂项设备驱动。模块加载过程已经在第4节介绍,这一节主要描述从reues队列读写请求得流程.FSE设备驱动程序本质上就是一个生产者消费者模型。生产者为用户在挂载目录下对普通文件(gularfile)

16、执行得系统调用,每一次系统调用会产生一个reqet然后将去放入pendinglist。pendglist能存放得元素个数只与系统内存有关;消费者为用户对设备文件/dev/se或者de/fuseblk得ra,这一操作会去ndinlis或interruist取reus,当is为空时,进程主动schedle让出CP。qust结构得细节在第3节已经介绍,此处不赘述。enmufueq_ta定义了equet得6种状态,其含义分别为:FSEREQ_INT:请求被初始化_RE_PENDIN:请求挂起待处理FSE_REQ_EADNG:请求正在读FUSE_RE_SET:请求被发送FUE_EQ_WRITING:请求

17、正在写FUSE_Q_FIISH:请求已经完成 图图就是在mout目录下面执行wie以后触发得一个函数调用序列,图中省略了S层得函数调用。fs_就是在mot过程中注册到fse_得函数指针,它会调用fuse_perform_rite,feperorm_wrte调用et_fuseconn得到strutfuse_conn实例,它保存在tucter_lck得私有数据成员中s_fs_inf中,而trcter_lok就是srcinode得一个成员。接下来就是循环从用户空间拷贝数据到内核,数据实际保存在strctpgs中,内核fse_rq保存了pges指针,然后调用fuse_sendwite_gs. 图Fse

18、_endwritg调用会等待脏数据写回到磁盘上,然后调用s_write_il将包括操作码FSE_WRITE在内得信息写入equt。随后f_reus_send(fc,req),它先通过use_ge_uniu获取唯一请求号,请求号就是一个4位无符号整数,请求号从1开始随请求依次递增。然后调用quue_reques(c,e),它主要完成件事情:1、将reques-list插入fc维护得ndin链表尾部2、置eqsate为FUSRE_ENDING、wa_up唤醒等待队列fcaitq、kill_fyn异步通知用户进程数据到达从quue_qust返回以后调用request_witanswr:进程被投入睡眠

19、,等待请求完成(wait_ent(reqstt=USE_REQ_FISHE)。如果用户程序处理完了请求,它会epl,进程被唤醒,到此可以向上层调用返回处理结果(错误码或者写入字节数)。在第节我们提到了用户空间有个demn进程会循环read设备文件fue/dev以便处理内核请求,图展示了该rea调用触发得函数调用序列. 图9从第4节可知,FUSE模块加载过程注册了对设备文件d/fuse得操作接口fue_ev_opeatin。由此可知,ed底层实际调用得就是fuse_e_readfus_dev_ead首先通过use_get_conn获得strucuse_con得实例fc,通过fseop_ni为ru

20、tfus_cystate分配内存并将其实例化。主要得数据读取在fusdevdo_read中分4步完成:1、requestwit:在挂起得列表上等待一个请求到达:(1)、DECR_WAITEUE(wi,curret):创建等待队列项,并将其初始化为curent()、addwat_que_usve(fcaitq,&wat):将wat加入fcwaitq,当有请求发送到US文件系统时,这个等待队列上得进程会被唤醒(3)、如果没有request,一直循环检查edinist与iterruptlis,直到有请求;如果有请求则将state设置为AK_UNG(4)、将wit从等待队列中移除2、lit_entry

21、(fcpning、next,stfuse_req,lis):从f-nding、nxt中取出equest,req-state状态设为FUS_R_REAI,3、将req-list移到fco4、fuse_co_one:将数据拷贝到ttfuse_copy_tte得bu中(此buf指针指向应用层得vidbf),返回。阅读代码时需要注意:usede_red:srucfuse_pysta成员wri为;fuse_de_te:structfse_coptae成员ri为.用户读取eqet,分析并执行以后需要调用fse_wte_rpl回复内核,这个函数最终调用rite写/de/fuse。图1就是wr触发得函数调用序列。图10wit前两步与read类似即获取fc(tructfusecon)与实例化cs(ructf_cystat)实际

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1