您的位置:首页 > 其它

fallocate和reflink

2016-04-01 02:55 274 查看

一、前言

我自认不是一个标题党,起一个吸引眼球的标题向来不是我所擅长的,本来我想写这篇文章是来自最近XFS邮件列表里几个maintainers在讨论的一个话题,邮件的初始标题是“fallocate mode flag for "unshare blocks"?”,由Darrick
J. Wong发出来的。其目的本来不是讨论fallocate,而是想探讨一下如何让XFS实现reflink功能。但是由于他想通过给fallocate加一个新的mode来支持reflink的实现,所以加入了fallocate的讨论。

想来想去我到底是该说reflink,还是fallocate,还是如何用fallocate实现reflink呢?第三个我肯定说不了或者说说不详细,毕竟这些maintainer们还在讨论如何在XFS上实现它。我觉得聊一下fallocate和reflink的定义可能对理解他们的探讨内容有所帮助。所以我就把标题写成了《fallocate和reflink》这么个不疼不痒的标题,或许我应该效仿网络流行语,其个例如《fallocate和reflink的前世今生》或者《那些年发生在fallocate和reflink之间的故事》或者《下雨天fallocate和reflink更配哦》这样的标题~~~~~
好吧,YY到此结束。

二、fallocate

1. fallocate和posix

fallocate这货是Linux特有的系统调用,并不符合POSIX标准,为了兼容posix标准的fallocate,glibc专门做了一个posix_fallocate函数,看名字就知道这个函数是对应posix标准实现的。然而它和我们要说的fallocate没有任何关系,虽然它从功能上好像是实现的fallocate的基本功能,但是本质上它们是两回事。fallocate是文件系统层提供的实现,它的很多特性必须得到文件系统底层的支持。而posix_fallocate是在上层的实现,就算文件系统底层不支持任何fallocate的操作,你也可以使用posix_fallocate。但是此时我更愿意用dd。。。

2. fallocate上的五种mode

先来看一下fallocate的定义:

int fallocate(int fd, int mode, off_t offset, off_t len);

很显然fallocate就是对fd所指向的文件的offset+len区间做mode指定的操作。那么这个mode就是我们要重点说的。事先声明,现在是2016-04-01,目前最新的Linux版本是Linus刚刚合并完成的Linux-v4.6-rc1。截至目前fallocate在不同的文件系统上共支持五种不同类型的操作,一一列举如下:

I. Allocating disk space

这是默认的操作,对应mode等于0。它所作的工作是如果分配从offset开始到offset+len的一段空间,这个是真的分配磁盘空间,不是hole,新分配的空间以0填充数据。当然这个操作一般在offset+len大于现有文件长度时才会起到增加文件数据空间的作用。

一般情况下新增加空间后文件的size也会随着调整,但是有一个特殊情况,就是当FALLOC_FL_KEEP_SIZE出现在mode中时,在增加文件空间后不会改变文件的size。这样的操作算是一种在文件结尾处的预分配,对于后期的append写入操作有优化作用。

II. Deallocating file space

这个就是大名鼎鼎的punch hole操作,相信在很多软件中都看到过这样的操作。对应的mode是FALLOC_FL_PUNCH_HOLE,从Linux 2.6.38开始由XFS首先支持这个操作,后面ext4在3.0时也支持了这个操作,btrfs在3.7时做到支持(其它文件系统请自行查找)。从字面意思就可以明白punch hole就是“打洞”,就像是在一张纸上戳出很多洞一样,那些被戳掉的地方原来的内容就没了,纸的实际面积就缩小了,但是从整体上看这张纸还是那么大一张,只是中间多了很多洞。那么对这些洞的读操作就默认返回数据0(写操作会重新填充这些洞)。

跟上面的操作一样,这个操作也可以和FALLOC_FL_KEEP_SIZE混用。混用后的效果就是punch hole之后文件的size也不变。这里还要说一下,虽然不带FALLOC_FL_KEEP_SIZE时punch hole操作会导致文件size的减小,但是我们最好不要在调用fallocate的punch hole操作后就认定size一定小多少。没有这样的标准说一定这样,而且将来实现reflink后,对reflink文件的punch
hole操作结果还不得而知。

III. Collapsing file space

大概从Linux 3.15开始ext4和XFS开始支持fallocate的collapse操作,对应的mode是FALLOC_FL_COLLAPSE_RANGE。对比上面的punch hole操作,这个collapse操作不会留下空洞。它相当于把一张白纸从A到B处撕下去,然后把剩下的部分重新拼接起来组成一张新的白纸。就是把offset到offset+len这段区域的数据丢掉,然后把offset+len以后的数据移动到offset的位置,整个offset+len后的文件数据往前移动。

这里一定要和punch hole区分,punch hole之后,读取offset+n(n < len)会读到0,但是collapse之后读offset+n时就会读到原来offset+len+n位置的数据。

collapse操作不能和包括FALLOC_FL_KEEP_SIZE在内的任何mode参数混用。

IV. Zeroing file space

这个操作也是从Linux 3.15开始被部分文件系统支持,对应的mode是FALLOC_FL_ZERO_RANGE。好吧,我不得不说这个操作比collapse操作更容易和punch hole混淆。我们上面说punch hole就是把offset到offset+len这段空间删除,但这段空间偏移量还保留在那里,读的时候会读到0。那么zero操作就比较复杂了,对于像XFS来说zero操作就相当于把offset到offset+len这段区域变为unwritten
extents。说到unwritten extent还得解释什么时unwritten extent……烦躁……还是给个连接自己去看吧(http://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/ch02s07.html),要不说多了我又该跑题了,我太容易跑题了,你看现在就有点跑题了。。。

简单来说unwritten extent就是把一段区域设置为“这里我还没有写,这段数据现在是无效的,先别让人看到这段数据”的模式,在metadata中设置这样的标志就会把这段空间保护起来不让人看见,而对这段空间的读操作就会返回数据0。看效果和punch hole差不多,共同点是读的时候都会返回0,但区别还是有的,至少一段没有的空间和一段在那只是不给你看的空间比起来后者写起来效果更快吧。具体不同也要看不同文件系统的实现。(另:在xfs上可以通过xfs_bmap来查看punch
hole和zero操作的不同,-p选项可以列出zero操作的unwritten extents,而punch hole的地方会直接显示hole。)

zero操作也可以和FALLOC_FL_KEEP_SIZE混用,混用的效果和上面punch hole的效果一样,都是不改变文件大小。

V. Increasing file space

这是个比较新的操作,从Linux 4.1开始被XFS实现,4.2开始才在ext4上实现。对应的mode是FALLOC_FL_INSERT_RANGE。insert顾名思义就是插入的意思,那么这个mode就是插入一个hole。在一个文件的中间offset位置上插入一个len长度的hole,而原offset到offset+len区域的数据的偏移量向后移动len长度。插入一个hole之后虽然没有实际分配新的磁盘空间,但是由于增加了偏移量而让文件的size增大。对hole区域的读操作还是返回0。注意这个操作的offset不能超过文件的结尾。

insert操作也可以和FALLOC_FL_KEEP_SIZE混用,混用的效果还是不改变文件size。

3. fallocate总结

说了fallocate的五种模式,其实没什么可总结的,很多细节的东西还是要看官方的man page。不明白的地方挂载个文件系统自己亲自尝试看看。

三、 reflink

现在凌晨2:40了,我很困,也开始后悔起这么大的标题了。所以我决定简单说下reflink就结束了。reflink是区别于symlink和hardlink的第三种link的存在。symlink是创建一个符号连接文件,此文件的内容保存着目标路径。hardlink是创建一个相同inode号的文件,文件名不同但是inode是同一个(限制是只能在同一文件系统内创建)。reflink不同于它们两个,reflink是创建一个新的inode,但是这个新的inode和目标inode共享相同的磁盘空间,直到新的内容被写入到新的inode里。这就是一个copy
on write的实现,可以实现快速的拷贝。

目前btrfs支持这个特性,XFS像我上面说的还在开发阶段。那封邮件所探讨的就是如何在XFS上实现这一功能,有人提出为fallocate添加一个新的mode,来支持reflink的实现。总之了解上面的fallocate现有mode后对理解他们的对话会有些许作用的。感兴趣的可以持续关注此feature的开发和测试,不感兴趣的等这个feature出来也可以知道如何使用,因为cp命令已经有--reflink选项了。

此致,睡觉
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: