治肾虚不含糖,专注内核性能优化二十年。 https://github.com/KnightKu
分类:
2018-08-28 15:31:54
原文地址:ZFS代码简介(1) 作者:qincp-
本文为ZFS文件系统源码的简单介绍。本文假设读者已经对文件系统结构的一般知识和术语有所了解。
传统上,我们描述ZFS由三部分组成:ZPL(ZFS Posix接口层),DMU(数据管理单元),以及SPA(存储池分配器)。虽然这种说法便于理解,但真实的情况要比这个稍微复杂些。下图给出了更为详细的示意。
在图中,仍然可以看到三个基本层次,每一个层次中又包含了多个子模块。除此之外,还有用户空间的ZVOL用户,ZFS用户,管理功能等。本文并不会对每个模块进行详细描述,源码才是最终的文档。如果对本文理解有困难或者有一些建议,欢迎到ZFS论坛()进行讨论。
只通过Posix文件系统API使用ZFS的基本应用。理论上,每个应用都可以归到这个类型。用户进行系统调用,这些调用通过OpenSolaris VFS层到达ZPL。
ZFS提供创建“模拟卷”的方法,这些模拟卷使用存储池中的资源,表现为在/dev目录下的普通设备。这并不是典型用法,但有时也是需要的,有少部分应用直接和这些设备交互,而不是像大多数一般应用使用基于这些设备之上的文件系统功能。
Solaris提供基于web方式ZFS GUI,这可以作为JNI之上的基于Java的GUI的一个例子。该功能在OpenSolaris还暂时不支持。
这类应用对ZFS文件系统或者存储池进行操作,包括检查属性以及数据集层次。除一些小功能模块外(Zoneadm,zoneadmd,fstyp),主要是两个应用:zpool(
该命令负责创建和管理ZFS存储池。主要功能是解释输入命令行,将其翻译为libzfs调用,包括这过程中的一些错误处理。该命令的代码在 usr/src/cmd/zpool目录下。有这样一些文件:
zpool_main.c |
命令入口主处理函数,处理所有参数和子命令 |
zpool_vdev.c |
将一系列的vdev转换为libzfs调用所需要的nvlist |
zpool_iter.c |
对系统中的存储池进行迭代操作的函数集 |
zpool_util.c |
一些杂项函数 |
该命令创建和管理ZFS文件系统。类似于Zpool(
zfs_main.c |
命令入口,处理所有参数和子命令 |
zfs_iter.c |
对系统中数据集进行迭代操作的函数集 |
这个库提供了libzfs的Java界面。当前是一个私有接口,针对GUI进行了裁剪。GUI主要通过CLI进行调用,所以,该库主要关注点为可观察性。库的源码在usr/src/lib/libzfs_jni目录下。
这是管理应用和ZFS核心模块交互的主要接口。库提供了访问和操作存储池和文件系统的统一的,面向对象的机制。库的底层机制则是通过/dev/zfs的ioctl调用接口和内核进行通讯。该库的代码在usr/src/lib/libzfs中,包含下列文件:
libzfs_dataset.c |
操作数据集的主要接口 |
libzfs_pool.c |
操作存储池的主要接口 |
libzfs_changelist.c |
只对象属性更改的传递函数 |
libzfs_config.c |
读和操作存储池配置信息 |
libzfs_graph.c |
为数据集构造链表 |
libzfs_import.c |
发现并且导入存储池 |
libzfs_mount.c |
加载,卸载,共享数据集 |
libzfs_status.c |
基于存储池状态的到FMA知识的链接 |
libzfs_util.c |
杂项函数 |
ZPL是ZFS文件系统的主要接口。它是基于DMU之上相对比较薄的一层,提供文件,目录等对象的抽象,起着OpenSolaris VFS和DMU接口之间的桥梁作用。该层也负责进行ACL规则应用和执行同步语法(O_DSYNC)。
zfs_vfsops.c |
OpenSolaris VFS 接口 |
zfs_vnops.c |
OpenSolaris vnode 接口 |
zfs_znode.c |
每个vnode对应一个底层znode |
zfs_dir.c |
目录操作 |
zfs_acl.c |
ACL实现 |
zfs_ctldir.c |
伪文件系统的实现.zfs/snapshot |
zfs_log.c |
ZPL记录意图日志条目的接口 |
zfs_replay.c |
ZPL 重放意图日志条目的接口 |
zfs_byteswap.c |
ZPL数据结构字节转换函数 |
ZFS提供对存储池中空间直接访问(以ZFS卷)的支持,代码中zvol由一个单独的文件实现:
zvol.c |
卷接口 |
该设备是libzfs的主要控制接口。虽然用户通过/dev/zfs可以直接使用ioctl接口,但该接口不是一个公开接口,和libzfs紧密绑定。该设备由单个文件实现,对ioctl参数进行一些效验工作,将请求送到ZFS中的相应处理模块。
zfs_ioctl.c |
/dev/zfs ioctl() 接口 |
zfs.h |
内核态和用户态之间接口 |