Btrfs

跳转至: 导航, 搜索
Btrfs 是一个 Linux 写入时复制 (CoW) 文件系统,目的是在专注容错、修复和易于管理的同时实现高级功能。由 Oracle,红帽,富士通,因特尔,SuSE,STRATO 和许多其它公司合力开发,以 GPL 协议发布。 (虽然) Btrfs 目前正在重度开发中,但是我们尽最大努力地保持该文件系统的稳定性和速度。由于开发速度很快,您应尽可能地使用最新内核 (最新发布版和 RC 版的内核)。

功能

用法

使用 DKMS 针对最新稳定版内核使用最新的 Btrfs-next 代码

DKMS,动态内核模块支持,是一个用来生成源代码不在 Linux 内核源代码树中的内核模块,好处有两个。第一个是可以在老系统上用新驱动,第二个是在升级了新内核后 DKMS 不用用户干预即可自己针对新内核重新编译。openSUSE 并没有提供这个软件包,在 Packman 软件源中。所以添加该源后 sudo zypper in dkms 即可安装。

之所以选用 DKMS 安装 btrfs-next 中的 btrfs 内核模块而不是直接编译 btrfs-next 内核分支代码树,是因为该分支并没有吸收提交给主分支的安全更新,对日用系统不是很友好。

Btrfs 有两个 git,分别是内核空间的 Btrfs 内核模块的 git 和用户空间工具 Btrfs-progs 的 git。我们一般说 git 指的都是内核模块的 git,因为这是最可能出问题的地方。

内核模块的 git 又有两个,一个是 mason 的,一个是 josef 的。mason 的主要是完成版的 git 用于像 linus 推送,因此你可以忽略。而 josef 的这个叫 integration git,意思就是他每天把发送到邮件列表中的故障修复补丁都搜集到一起,新得不得了。所以如果您用 Btrfs 有什么问题,最好先试一下上了这个 git 后还存在不存在,要是不存在了那就不要打扰人家开发者了。

git clone git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next.git 

目前基于 v3.7 Final 的 base。而 openSUSE 12.3 就是 3.7, 对其它老版本 openSUSE 也都提供了 3.7 源。

首先克隆上面那个 git。

然后先要给 3.7 内核做一个补丁,也就是说你的 /usr/src/linux-3.7.1-1 做一个补丁。因为 3.8 中 btrfs 有一些头文件的位置变动了,如果不做补丁的话 dkms 编译会失败。先去 Git Web GUI 看一下最新的 commit 是什么,比如是 635899acae7e637cc7298eeaded0c46271d28f2e

cd /path/to/your/clone/
git diff 635899acae7e637cc7298eeaded0c46271d28f2e.. > btrfs.patch

将这个补丁复制到 /usr/src 备用,由于以后也会用到,所以不要删除。

sudo cp -r btrfs.patch /usr/src

接着是打补丁:

cd /usr/src/linux-3.7.1-1
sudo patch -p1 < ../btrfs.patch

然后准备 dkms.conf

// 软链接到 /usr/src 不然 dkms 找不到
sudo ln -sf /path/to/your/clone/fs/btrfs /usr/src/btrfs-git
// 编辑 version.h,添加时间戳记
vi version.h

把:

#define BTRFS_BUILD_VERSION "Btrfs"

替换成这样:

#define BTRFS_BUILD_VERSION "Btrfs 2013-02-09_03:30:03_+0800"

接着编辑 dkms.conf

vi dkms.conf

按下面的填写:

PACKAGE_NAME="btrfs"
PACKAGE_VERSION="git"
BUILT_MODULE_NAME[0]="btrfs"
DEST_MODULE_LOCATION[0]="/kernel/fs/btrfs/"
AUTOINSTALL="yes"
REMAKE_INITRD="yes"

至此准备工作就完成了。

正式将该模块添加到 dkms 工作区:

dkms add -m btrfs -v git

开始编译

dkms build -m btrfs -v git

编译好的 btrfs.ko 在 /var/lib/dkms/btrfs/git/3.7.1-1-desktop/x86_64/module/。不过您无需手动复制到 /lib/modules/3.7.1-1-desktop/kernel/fs/btrfs,下次启动自动就会安装,因为我们在 dkms 里写了 AUTOINSTALL。

如果编译失败的话可以在 /var/lib/dkms/btrfs/git/build/make.log 中找到原因。

常见问题

开机时无法挂载 /home

表现:开机进入 KDM,弹出窗口提示 "Cannot enter home directory. Using /",点击确认后继续弹出窗口提示 "Call to lnusertemp failed (temporary directories full?). Check your installation."。然后重新回到 KDM。

调试:切换到 console (ALT+CTRL+F1) 后,输出为:

Btrfs:Error removing orphan entry, stopping orphan cleanup
Btrfs:could not do orphan cleanup -22

进行:

btrfs show filesystem //查看 btrfs 分区编号
btrfsck /dev/sda5 //刚查看到的分区编号

后会出现:

ref mismatch on [292356431872 4096] extent item 1, found 0
Incorrect local backref count on 292356431872 root 5 owner 12979743 offset 30584832 found 0 wanted 1 back 0x21f9370
backpointer mismatch on [292356431872 4096]
owner ref check failed [292356431872 4096]
Errors found in extent allocation tree

root 403 inode 18446744073709551605 errors 1
root 404 inode 18446744073709551604 errors 2000

这样的错误。

解决方案

  • workaround: 根据 btrfs: could not do orphan cleanup -22 里说的,该信息是无害的,先只读挂载,再可写挂载,即能规避该问题。上游说他们已经注意到了该问题,在 checksum 算法故障修复后就会修复它。
mount -oro /home
mount -oremount,rw /home
btrfsck --repair /dev/sda5

可以解决该问题。