BlueFs源代码分析报告_第1页
BlueFs源代码分析报告_第2页
BlueFs源代码分析报告_第3页
BlueFs源代码分析报告_第4页
BlueFs源代码分析报告_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、bluefs 源代码分析报告一、什么是bluefs bluefs是密歇根大学电子工程与计算机科学系的研究者们提出的一个分布式文件系统。由于移动存储技术的发展,诸如闪存之类的存储设备的出现,让人们可以轻而易举的随身携带大量的数据。然而传统的数据访问机制并没有考虑到移动存储的大量使用的情况,它们并不是为方便访问移动存储设备而设计的。使用传统的分布式文件系统所提供的数据存取机制访问移动存储设备可能造成高能耗和数据访问速度低的问题。bluefs就是在这种状况下提出的。它让人们对移动存储设备的使用更加自由。二、主要功能首先, bluefs首先是一个分布式文件系统,它必然有着一般分布式文件系统的共同特点。

2、它必须能够将操作系统vfs的文件操作命令截获,然后传递给bluefs自身进行处理。其次,它由客户机和服务器构成。服务器用来存储数据。客户机接受从vfs截获的文件操作命令,然后进行处理;客户机在进行操作的时候相应的文件需要从服务器获取或者提交到服务器。在bluefs中,客户机和服务器的连接是通过rpc协议包实现的。bluefs的系统结构如图1 所示,服务器部分未画出。对我们研究的代码来说无论是客户机还是服务器都包含在一个软件包中,然而这并不是必须的。图 1 bluefs的系统结构其次, bluefs又不同于以往的分布式文件系统,如nfs或者 coda。nfs只是简单的实现了上面提到的功能。 co

3、da另外还支持无连接操作,也就是在连接不上服务器的时候本地磁盘有部分备份,可以在备份上进行文件操作,在重新连接到服务器后进行同步。coda还通过 cache 的使用提高访问速度。coda 的这些技术都被bluefs借鉴。然而bluefs最大的特点是提供移动存储设备的支持,而且这也是bluefs的设计目的所在。因此,bluefs文件系统功能中最有特色的部分也在于此。我们将在下面粗略的说明一下bluefs对设备的支持功能特色。详细的说明将在后面分析代码的时候再进行。首先,bluefs为每个移动存储设备(其实包括服务器和本地非移动存储)提供了一个“写队列”结构,来记录文件系统对此设备的操作。这种“写

4、队列”的应用目的在于通过异步操作提高性能,并减少设备的状态切换从而省电。第二,读数据的时候从各个设备中找出读数据相对“性价比最高”的设备并从中读取数据。这里,“性价比高”意味着省电并且操作时时延相对较小。这部分功能也是由bluefs客户机提供的。第三,enode cache 结构的使用从而提高表现,防止从数据不存在的设备上读取数据。第四,在连接新设备或者去掉一个设备的时候需要有相应的处理操作。第五,有时我们需要某些文件必须能够存储到某个设备上去,这就是“affinity”。bluefs也提供了这部分功能。数据的经常备份复制必然产生不一致问题,怎样处理数据的不一致问题也是bluefs必须提供的功

5、能。bluefs从 coda等文件系统借鉴了callback机制。三、典型工作流程本节描述bluefs的一个典型工作流程。首先,我们要做的当然是启动bluefs了。先启动bluefs的服务器,然后启动客户机,它将会试图与服务器建立一个rpc连接。连接建立以后,我们就能顺利进行各种操作了。(其实无连接状态下也是可以操作的 , 但这不是bluefs的主要功能)现在某应用程序要存储一个文件到bluefs文件夹下(即放在bluefs文件系统中)。首先,应用程序要调用vfs的文件存储函数,应用程序期望vfs能够帮它完成其余的工作把文件存储到bluefs文件夹下。在这里,vfs的操作被传递到bluefs的

6、 kernel模块儿。而kernel模块的功能也就是接受vfs的存储命令并把它传递给客户机(wolverine模块)。几乎所有的处理工作都在wolverine完成。wolverine负责把 kernel传递过来的数据进行存储。它把数据存储命令加到各个设备(包括server )的写队列上去。并在合适的时机执行写操作。然后,应用程序就可以在bluefs文件夹下读取文件了。当然,这个文件可能并不是放在bluefs文件夹所在的文件系统的。我们甚至不知道它究竟放在哪里。但是应用程序只需要给vfs一个读取命令,vfs自然会告诉bluefs kernel我们需要读取这个文件,而kernel会把这个需求告诉w

7、olverine ,wolverine按照自身的方案从某个设备(可能是server ,与服务器的通信是通过rpc 包进行的)将文件取出,然后再经过传递送回应用程序。具体步骤参看图1。上面我们从整体上说明了bluefs的工作流程,下面我们将具体的分析bluefs的源代码,使我们对bluefs文件系统有一个更清楚,详细的认识。四、源代码解析4.1 代码结构bluefs 代码的结构如下所示:bluefs admin bfs.c barnacle_lib dumb_diskcache libdiskcache.c dumb_ptpcache libptpdevice.c forker libforke

8、r.c id3merge libid3merge.c memleak libmemleak.c memstomp libmemstomp.c noop libnoop.c 、noop_pq.c radiohead barnacle_ops.c、id3ops.c 、libradiohead.c 、performance_pq.c segfault libsegfault.c common configs daemon bluefs_device.c cache_common.c c_lock.c directory.c diskcache.c dumb-scan.c dumbcache.c ec

9、ache.c edda.c federate.c sentinel.c wl_diskcache.c wl_dumbcache.c wl_server.c writelog.c ds if edda_if.rpc3 include kernel bluefs_dev.c bluefs_dirops.c bluefs_fids.c bluefs_inode.c bluefs_query.c bluefs_super.c ds_list_kernel.c ds_list_kernel_private.c mount_tool scripts server cache.c client.c crea

10、te_vol.c devices.c directory.c dirops.c fileops.c main.c query.c rpccalls.c volume.c wa_log.c test makefile bluefs 的各个功能模块基本上是按照以上目录或者文件结构组织在一起的。另外,bluefs 的运行仅仅依靠 bluefs 自身的代码是不行的。它需要一个运行环境。bluefs 要求运行在linux 内核上,并且需要rpc协议(必需)和stmp 协议(可选)的支持。bluefs 客户端和服务器交互的信息通过rpc (远程进程调用)协议进行通讯;bluefs 一些功能的实现需要stm

11、p 电源管理的支持。4.2 基本数据结构说明ds_list_t和 ds_hash_t 数据结构以及在它们之上的有关操作:实际上就是一个普通的链表和哈希链表的结构和操作的定义。bluefs的一些通用数据和函数定义:如alloc (分配内存空间)、assert (判断条件是否满足)、mxlock(对互斥量加互斥锁)以及一些通用时间操作函数。efid 结构用来标记一个文件,etype_ 类型结构定义文件类型,eattr 结构定义文件属性,ecred 结构来确定文件所有者。edda_dirent结构描述目录的一些额外属性。qheader 、qentry结构是当文件类型为query 时的有关结构。三个函

12、数get_sprocket_rdlck、get_sprocket_wrlck、 unlock_sprocket_lck函数分别将sprocket_rwlck进行读锁、写锁和解锁。bluefs的有关数据格式:这些类型的数据都是bluefs内核和设备共享的数据格式。用于bluefs kernel和 edda 之间的数据传输。这些数据结构包括 bfs_kmsg_data、bfs_kmsg_strings、bfs_kdwncall、bfs_installpage、bfs_installfids、bfs_clearcache、bfs_installattrs、bfs_execcb 、 bfs_fedse

13、rver、bluefs_mountdata、bfs_kupcall。主要的数据传输时通过bfs_kdwncall和 bfs_kupcall两个结构进行的。writelog有关的结构和函数操作:wl_type_ 类数据表示对文件的操作类型;定义了对文件的各种操作,如截断、读取、存储等等。数据结构wlogentry将各种操作封装。对writelog的操作包括创建、增加、匹配、清空等。每个设备以及服务器都有自己的writelog。ipc (进程间通信)相关结构:edda_msgtype_ 类结构定义操作类型,包括mount、unmount、register、affinity等。 edda_msgbu

14、f 结构用来传输进程间通信的操作类型。在管理bluefs 、对 bluefs进行挂载设备等操作时以及系统测试中使用较多。callback有关数据结构:devcb、callback_msg结构。它们的存在主要是为了保证数据一致性。devcb 为设备持有,用于记录对象的状态。callback_msg 是 edda 要发送给server的, edda 改变了某个设备上的该数据,则它应该告诉其他所有相关设备也必须修改该数据。barnacle 相关: params 结构中包含barnacle函数可能用到的参数;listentry结构。 barnacle_ 类型结构定义 barnacle的操作类型。对新文

15、件文件属性的设置函数:new_file_attrs、new_symlink_attrs和 new_query_attrs函数针对文件的类型,来对新建文件的文件属性进行初始设置。对目录的操作函数:create_new_dirchunk函数建立一个新目录块儿,init_dir_data初始化一个目录块儿, read_dirchunk函数用来读目录项,is_in_dirchunk用来查找目录项,is_in_dirchunk_by_id也用来查找目录项,add_entry_to_dirchunk和 remove_entry_from_dirchunk函数分别向目录块儿中添加和删除目录项。4.3kern

16、el 模块kernel模块的主要作用是截获linux的 vfs (虚拟文件系统)操作,并通过upcall机制将其传递给bluefs的 daemon (wolverine )。另外它还要在内存中维护一个linux file cache。先看一下linux的 vfs到底是怎么回事。linux 的文件系统主要有三大块,包括上层的文件系统调用, vfs ,以及挂载到vfs中的实际文件系统如ext2 ,ntfs等。可以把vfs看做文件系统管理者,它用来管理下层各个文件系统,并向上层的文件系统调用提供通用的接口,屏蔽了低层文件系统之间的技术差异。从这个意义上来说,把vfs看做一个实际文件系统与系统调用之间

17、的接口也未尝不可。如果我们想要在 linux 下实现一个实际文件系统的话,必须遵守vfs与实际文件系统的一些接口规则。图 2 磁盘与文件系统vfs的接口包括一些数据结构和函数,相关数据结构结构包括superblock 、inode 、dentry 、file。superblock (超级块)是存在于磁盘的结构,它定义了文件系统的管理参数,如总块数、空闲块、根索引节点。如图2所示。 inode (索引节点)管理文件系统中所有对象,可通过它引用一个文件、目录或者符号链接。要注意这里提到的inode 是 vfs层的 inode ,而不是每个实际文件系统的inode 。dentry (目录项)对象。f

18、ile是表示文件的结构。int register_filesystem (struct file_system_type *fs);函数用于注册一个文件系统,将实际文件系统注册到vfs中。所有已注册的file_system_type结构在vfs形成一个链表。文件系统注册后,还需要安装才能使用。但注册以后注册的文件系统同我们在此文件系统中定义的各个结构、函数之间已经建立了一定的对应关系。安装使用系统的mount ()调用:mount(char * dev_name,char *dir_name,char *type,unsigned long flags,void *data)。 vfsmoun

19、t结构用来描述挂载点。卸载文件系统使用umount 命令。kernel 中的函数这么几类:对超级块进行操作的函数;对设备本身进行操作的函数;对文件inode和直接对文件进行操作的函数。首先,对超级块进行操作的函数。这部分主要集中在kernel文件夹下的bluefs_super.c文件中。我们把函数调用关系列出来。用“”表示调用init_module register_filesystem bluefs_fs_type(结构)init_module unregister_filesystem bluefs_fs_type(结构)安装 bluefs的时候通过register_filesystem函

20、数注册bluefs_fs_type文件系统。bluefs_fs_type的 file_system_type结构有两项: .get_sb和.read_super 。这两项代表系统对该文件系统超级块进行操作要调用的函数,分别对应bluefs_get_sb和 bluefs_read_super函数。bluefs_fs_type .read_super bluefs_read_super bluefs_fids_init bluefs_dev_setsuper .get_sb bluefs_get_sb bluefs_fill_super bluefs_super_ops bluefs_fids_i

21、nit bluefs_dev_setsuper 其中 bluefs_super_ops各项对应的是是超级块的实际操作函数,如取文件系统状态,读超级块等。bluefs_super_ops结构 .put_super bluefs_put_super .read_inode bluefs_read_inode .clear_inode bluefs_clear_inode .statfs bluefs_statfs 其次,对设备进行操作的函数。这里所说的设备,并不是指某一个特定的物理设备,而是指bluefs本身作为一个“虚拟设备”。整个bluefs文件系统就安装在这个虚拟设备上。实际上这部分的数据结

22、构完全是放在内存里的,是vfs对“ bluefs设备”进行的管理。函数调用关系init_module bluefs_dev_init register_chrdev(注册字符设备bluefs ) bluefs_devops cleanup_module bluefs_dev_destroy bluefs_devops是 file_operations类型数据。它有几个子项,分别对应一个设备操作函数。如下bluefs_devops .release bluefs_devclsoe .open bluefs_devopen .poll bluefs_poll .read bluefs_devrea

23、d bfs_cpytouser .write bluefs_dev_write bluefs_federate bluefs_install_fids bluefs_install_page bluefs_install_attr bluefs_exec_cb do_callback bluefs_clearcache do_callback bluefs_dev_write函数通过copy_from_user从用户空间拷贝数据到内核空间,以此与daemon交互。然后通过不同的函数将内核态数据写到bluefs设备上去。 bluefs_dev_read调用 copy_to_user (通过 bf

24、s_cpytouser)从内核拷贝数据到用户空间,由应用程序使用。copy_from_user和 copy_to_user均通过超级块的文件系统接口(dev_read/dev_write)与应用程序交互。这不同于kernel和 daemon之间的交互。 kernel 和 daemon之间应该是通过bkmsg_queue和?来进行交互的。(oneway,twoway 函数向bkmsg_queue中添加内容,devread 从其中取内容)。但是在 sentinel中将 /dev/xfs0 挂载为 bluefs类型文件系统设备,因此对/dev/xfs0的读写也就是对bluefs文件系统的读写。ker

25、nel 和 daemon两者之间是通过 /dev/xfs0这个 fifo文件进行通讯的。bluefs_install_fids、bluefs_install_page、bluefs_install_attr函数分别是对设备的响应块进行操作的函数。bluefs还通过一个cclist链表在内核中进行cache 缓存的管理和查询。如下new_bfs_node add_inode_cclist free_bfs_node remove_inode_cclist 当系统新建立一个文件节点时,就在系统中维护的cclist里添加此节点的cache;反之,当删除一个文件节点时,就将此文件的cache 从 cc

26、list里删除。 fedlist有什么用?最后,对文件索引节点和文件本身进行操作的函数。函数调用关系init_module bluefs_cache_init cleanup_module bluefs_cache_destroy bluefs_cache_init和 bluefs_cache_destroy函数分别用于在内存中初始化或销毁两个分别名为bknode_cachep 和 bkmsg_cachep 的存储空间,用于作为内存cache 和暂存消息。用函数 new_bfs_node 建立一个新的文件节点的时候,会根据此文件的类型确定vfs文件系统中对应inode 的情况。如inode-i

27、_op,inode-i_fop等。 inode 的 i_op 对应对 inode 进行操作需要调用的函数,而 i_fop对应对 inode 指向的文件本身进行操作需要调用的函数。为目录,则i_op=bluefs_inode_dirops .lookup bluefs_lookup .permission bluefs_permission .create bluefs_create init_inode new_bkmsg new_bfs_node .unlink bluefs_unlink new_bkmsg .rename bluefs_rename new_bkmsg .mkdir bl

28、uefs_mkdir kern_init_dir kern_add_entry_to_page init_inode new_bkmsg new_bfs_node .link bluefs_link new_bkmsg .symlink bluefs_symlink init_inode new_bkmsg new_bfs_node .readdir bluefs_readdir 为普通文件i_op=bluefs_file_inode_operations .setattr bluefs_setattr new_bkmsg i_fop=bluefs_file_operations .relea

29、se_file bluefs_release_file new_bkmsg .fsync bluefs_sync i_aop=bluefs_aops .readpage bluefs_readpage .prepare_write bluefs_prepare_write .commit_write bluefs_commit_write 我们注意到,bluefs_create、bluefs_symlink、 bluefs_mkdir都调用了new_bfs_node 函数。而inode 的有关参数也是通过new_bfs_node 函数设置的。看起来有点矛盾。但是我们需要注意到,在超级块初始化阶

30、段已经通过调用new_bfs_node 建立了一个根节点。4.4daemon模块( wolverine )4.4.1 启动过程我们从 daemon模块的 main 函数来看其启动过程。如下图所示首先, main 调用 ed_init函数读取config文件进行客户端初始化,读取data 文件读取当前状态。然后调用server_init进行服务器连接。接着通过server_init_register注册客户机到服务器。如果需要调用 write_config_file写 config文件。然后通过client_startup启动客户机(没连接上服务器则用 client_startup_discon

31、nected)。然后将服务器上的callback都移除。通过mount_device函数挂载相应的设备到bluefs文件系统。而后,调用bluefs_get_downcall等待接收内核传递过来的文件操作,并进行相应处理。我们在下面进行代码分析的时候也将基本按照上述各个小的功能模块顺序进行说明。一、客户端初始化。ed_init函数首先对usertokernel_users、userstokernel_groups、kerneltouser_users、kerneltouser_groups四个哈希队列进行初始化。这几个结构的作用我们将在后面说明,主要是处理接收内核传递过来的操作数据。然后读取配

32、置文件和文件系统状态的信息。涉及到的函数调用关系如下所示ed_init usertrans_init read_config_file read_data_file 这三个函数承担了我们上面所说的初始化哈希表,读配置文件,读文件系统状态的作用。二、服务器连接。server_init调用 rpc3_newbinding 函数,同服务器建立rpc连接。如果未注册则server_client_register调用 registerclient函数注册rpc客户,并用write_config_file函数写配置文件,包含注册id 等信息。三、启动客户机。调用client_startup或者 clien

33、t_disconnect_startup函数启动客户机。client_startup的调用的函数如下client_startup clienthello connect_client(server) get_root_volume(server) truncatelog safe_read send_multi multi handle_conflict 总的来说,通过client_startup调用 clienthello与服务器会话;然后通过truncatelog函数读取无连接日志文件disc_log,并将相应的操作通过send_multi调用服务器接口multi函数与服务器进行同步。其中

34、multi函数将向多个设备发送标识此文件无效的invalidation。四、 bluefs系统初始化,自动挂载设备。系统初始化是通过sentinel_init函数来完成的。sentinel就是系统内所有设备的总管理员。然后系统自动挂载一些记录的存储设备。sentinel_init主要做了以下几件事:初始化writelog,这是在内核与daemon之间传送文件操作命令的结构;初始化ecache,这是 ecache 结构,具体见bluefs文章;初始化federate ;?为 server建立一个writelog,通过此 writelog把服务器当做一个设备来操作,但是调用的函数都是服务器自己的函

35、数;然后sentinel_init建立了几个线程,分别用于设备管理,callback管理和设备卸载管理。sentinel_init的函数调用如下所示:sentinel_init writelog_init ecache_init bluefs_getroot federate_init writelog_create、server_fetch、.、server_issue_ghost device_monitor find_device getfid gen_getattr get_next_device gen_fetch get_next_device getpath getparent

36、find_in_dir getname getparent find_in_dir mount_device find_device refetch_file send_kernel_cb unmount_device find_device refetch_file do_affinity do_type_affinity add_new_query get_fid_from_module cb_monitor send_kernel_cb umount_monitor unmount_device refetch_file device_monitor线程接收程序运行中的进程间通信quer

37、y 请求,并根据请求类型进行相应处理。cb_monitor 处理程序运行过程中产生的callback。unmount_monitor 函数每隔一段时间检查挂载的设备是否还在,并不断升级数据和服务器时延。还有两个函数gen_op 和 gen_doubleop 是接受bluefs_get_down从内核接收传送过来的操作,然后交给它们进行实际处理操作。这两个函数把操作挂到各个设备的写队列上去。五、实际文件操作。main 函数调用bluefs_get_down来接收系统(内核)的文件操作命令,然后进行实际的操作。包括将操作写到各个设备的写队列、维护ecache、设备读写策略等等。我们在下面将对这些方

38、面进行深入的分析。4.4.2运行中数据流下面我们从bluefs程序运行过程中的数据流角度来对daemon进行深入的分析。数据在应用程序和bluefs的交互依次经过了vfs调用实际文件系统;bluefs kernel截断对文件的操作并传递给bluefs daemon ;bluefs daemon先是接收内核传送过来的数据和命令,主要通过bluefs_device文件中相关函数实现; daemon接收到命令,然后将相应的操作添加到各个设备的writelog上去;然后写到各个设备writelog上的操作经过各个设备或者服务器的相关函数处理,真实的写到各个物理设备上。如下图所示当然,在这个数据流的过程

39、中伴随着ecache 的维护(参考文章),callback的维护,以及访问策略的设定,数据一致性的维护等一系列相关问题。在这之前,我们需要介绍一下device数据结构。这是daemon为每个设备维护的一个设备结构。以它为基础对实际设备进行各种操作,如writelog、affinity、latency 、 energy 、readable 、removable 等。具体结构如下所示:struct device char nameedda_max_path; /* unique identifier for this device */ char typeedda_max_path; /* typ

40、e of this device */ int deviceno; /* this devices unique id number*/ int edevno; /* index into enode dev number */ u_long sync_write; /* this device does synchronous writes */ /* xxx two u_chars makes gcc x-compiler unhappy :( */ u_char flags; /* what type of device is this */ log_id writelog; /* wr

41、itelog for this device */ struct ecred cred; /* authority for this device */ getattr_fn getattr; /* fetches attribues from this device */ fetch_fn fetch; /* fetches data from this device */ get_aff_fn get_affinity; /* gets affinity status */ set_aff_fn set_affinity; /* changes affinity status */ ter

42、m_fn term; /* call for clean detach of device */ pred_fn get_latency; /* returns predicted access latency */ pred_fn get_energy; /* returns predicted energy usage */ rdbl_fn get_readable; /* returns whether device is readable */ pred_fn get_ideal_latency; /* returns ideal access latency */ pred_fn g

43、et_ideal_energy; /* returns ideal energy usage */ hint_fn issue_ghost; /* issues ghost hint for device */ reat_fn reattach; /*reattach this device after clnt disc */ char devpathedda_max_path; /*path to device removable media is mnted on */ short removable; /* whether this device is removable or not

44、 */ void* data; /* device-specific data */ pthread_mutex_t rl_lock; /* protects rl_list */ ds_list_t* rl_list; /* list of objects to refetch */ ; 首先, daemon接收内核传送过来的命令并与内核交互的模块集中在bluefs_device.c文件中维护。bluefs_get_down函数接受内核传送过来的文件操作命令,然后交给其他处理函数进行相关处理。bluefs_get_down do_unmount unmounter get_pentry us

45、erfromkernel gen_op writelog_add gen_doubleop termination_proc bluefs_readpage userfromkernel gen_fetch send_upcall cache_block bluefs_getfids server_get_fids send_upcall bluefs_getattr userfromkernel gen_getattr usertokernel send_upcall cache_attr 除此之外,还有两个函数usertrans_add和 grouptrans_add被 read_conf

46、ig_file函数调用。而usertokernel_users、kerneltouser_users、 usertokernel_groups、 kerneltouser_groups则维护一个在内核和用户之间传送数据的结构。然后,我们将对写队列writelog进行分析。 wlog 是设备的writelog表结构。当初始化一个设备的时候(可以使diskcache 、dumbcache 或者服务器)的时候,调用writelog_create函数为本设备建立一个 writelog,sentinel也会调用此函数创建一个callback的 writelog。此函数将创建monitor线程。monit

47、or将根据 writelog的情况不断进行检查并做相应执行,并根据设备的反馈对writelog进行相应处理。也就是monitor负责把 writelog上的内容传送给实际的物理存储设备。已冲洗则冲洗pendinglist,已提交则删除pentry项。相关的函数调用关系如下:dcache_initdumbcache_init federate_serversentinel_init writelog_create monitor pop_entry_from_wlog add_to_pending_list do_wait_fn flush_pending_list flush_pending_

48、list writelog_add是被其他读取文件的操作函数调用的,它用来将操作写到各个设备的写队列上。writelog_add wlogentry_modifies add_entry_to_wlog wlogentry_size 还有一个函数writelog_is_safe用来判断 writelog是否是没有冲突的,只有安全的文件才能被读写。writelog_is_safe wait_on_object getattr_conflict file_conflict dir_conflict handle_conflict prune_writelogs prune_pending_list

49、 remove_entry_from_wlog prune_writelogs将所有设备写队列上与某个文件相关的项剪除。这个函数只有在处理冲突的时候才会调用到。还有两个函数writelog_exit和 writelog_flush会在设备挂载或者卸载的时候调用到,用来清理 writelog。unmount_device sentinel_term writelog_exit device_monitorunmount_device writelog_flush unmount_device writelog_dirty_exit 第三、 enode 的维护。为了防止经常无谓的在不存在此数据的设

50、备上查找文件,我们维护一个enode结构来说明某文件所在的所有设备。此结构不存放实际的文件数据。具体结构如下:struct enode struct efid fid; / last device holds info on page cache callbacks unsigned char device_listedda_max_devices+1; struct enode* prev; struct enode* next; ; 此结构的有效数据仅为文件的fid 、以及此fid的文件存放的所有设备device_list。load_enodesgetflagsaddflags setfl

51、agsresetflags _find_or_get_enode ecache_access _new_enode ecache_check_size get_flags 、addflags 、setflags、resetflags分别对 enode 结构某文件在某设备存在与否的标志位进行操作,分别是取标志位、增加、设置、重新设置标志位。这几个函数在访问物理设备前被调用以决定从何物理设备进行访问,并根据物理设备的变化情况对enode 进行一定修改。ecache_check_size函数检查 ecache 是否超出限制大小,超出则执行lru算法清楚一部分endoe。第四、与disk 设备有关的操

52、作。code集中在 diskcache.c和 wl_diskcache.c文件中。mount_device dcache_init dcache_getattr dcache_fetch dcache_get_affinity diskcache_create dcache_set_affinity dcache_term dcache_latency dcache_energy dcache_readable dcache_ideal_latency dcache_ideal_energy dcache_issue_ghost dcache_reattach add_to_refetch_l

53、ist(cache_common ) retrive_cb_list load_enodes serveer_remove_cbs server_attach revalidate_cache clear_device check_cache_limit eviction dcace_lru_purge writelog_create(writelog.c) init_mode_monitor wl_disk_cache_cb dcache_setattr dcache_store dcache_create diskcache_make_empty_file diskcache_create

54、 diskcache_add_direntry dcache_symlink diskcache_make_symlink diskcache_create diskcache_add_direntry dcache_link dcache_mkdir diskcache_make_empty_dir diskcache_create diskcache_add_direntry dcache_rmdir diskcache_remove_direntry dcache_unlink diskcache_remove_direntry dcache_kill dcache_remove dis

55、kcache_remove_direntry diskcache_unlink diskcache_is_in_dir dcache_putattr diskcache_create dcache_putdata diskcache_create dcache_invalidate_object dcache_invalidate_attr dcache_invalidate_data dcache_create_query diskcache_create 另外, check_cache_limit函数用于文件操作前检查此设备占用空间是不是超出了它的设置阈值,如果是则执行一定的lru替换算法

56、进行替换。在一些文件操作过程中此函数被调用:dcache_setattrdcache_putattrdcache_store dcache_putdata dcache_create dcache_symlink dcache_linkdcache_mkdir dcache_unlinkdcache_killdcache_rename check_cache_limit dcache_new 函数在注册设备时调用。它将在新设备中建立一些dcache 目录以存放bluefs数据。另外,我们还有一个dheader 、一个 dcache_data的数据结构需要维护。dheader 是一个短期结构,用

57、它来作为修改目录文件的文件头,而dcache_data 结构则就是该diskcache的一些属性数据。修改dheader 的函数有以下这些:mark_data_valid mark_data_whole mark_data_invalid is_data_whole is_data_valid mark_attr_valid mark_attr_invalid is_attr_valid set_affinity set_sticky_affinity set_type_affinity unset_affinity has_affinity has_sticky_affinity has_t

58、ype_affinity test_set_clock_bit 这些函数可以做设置affinity、判断数据完整性有效性、标记数据为有效或者完整的功能。修改dheader 结构后,可以通过调用write_dheader来将修改的dheader 写入相应文件。用read_header 、read_dheader 、read_block ;write_header、 write_dheader和 write_block可以分别对普通文件头、目录文件头和文件数据块进行读写操作。这六个函数被相应的操作函数调用。第五、 dumbcache 设备,这种设备的大部分相关操作函数与diskcache的操作函数

59、类似。主要功能集中在 dumbcache.c、wl_dumbcache.c 、dumb-scan.c 文件中实现。mount_device dumbcache_init dumbcache_getattr dumcache_fetch dumbcache_get_affinity dumbcache_set_affinity _dumbcache_set_affinity dumbcache_term free_dumbcache_data dumbcache_latency dumbcache_energy dumbcache_readable dumbcache_issue_ghost d

60、umbcache_reattach revalidate_cache do_revalidate retrieve_cb_list retrive_cb_list revalidate_cache free_dumbcache_data wl_dumbcache_cb dumbcache_setattr dumbcache_store dumbcache_create dumbcache_make_empty_file dumbcache_mkdir dumbcache_make_empty_dir dumbcache_rmdir _dumbcache_nuke_dir dumbcache_u

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论