Btrfs
(虽然) Btrfs 目前正在重度开发中,但是我们尽最大努力地保持该文件系统的稳定性和速度。由于开发速度很快,您应尽可能地使用最新内核 (最新发布版和 RC 版的内核)。
功能
用法
使用 DKMS 针对最新稳定版内核使用最新的 Btrfs-next 代码
之所以选用 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
- 据称上面方法再重启后还是会出现相同的问题 (bnc#760279),又根据 Phoronix 上的 The Btrfs File-System Repair Tool Is Available 文章,似乎
btrfsck --repair /dev/sda5
可以解决该问题。