我认为我遇到了 btrfs 中的一个已知错误:
https://www.spinics.net/lists/linux-btrfs/msg60984.html
当然,错误消息看起来很相似。如果是同一个问题,那么对 2 年前问题的修复尚未移植到 V4.9 稳定内核(Debian 9 使用的内核)中似乎有些遗憾
我现在的情况是,其中一个文件系统 inode 存在范围问题(如 所报告btrfs check
):
root 257 inode 2607184 errors 100, file extent discount
Found file extent holes:
start: 0, len: 81920
似乎没有太多关于如何摆脱这种情况的建议或文档(幸运的是我确实有相关文件系统的备份,所以最坏的情况是可以重新格式化并恢复)
它似乎btrfs check --repair
只是一遍又一遍循环打印相同的错误,而没有真正修复它。
有什么方法可以修复现有的文件系统,或者最好重新创建它并恢复备份?
答案1
我认为root 257
指的是子卷 ID,然后inode 2607184
指向有问题的 inode。我会尝试删除(取消链接)链接到 inode 的每个路径。
挂载子卷:
mount /dev/sdXN -o subvolid=257 /mnt/mountpoint
找到具有匹配 inode 号的每个条目:
find /mnt/mountpoint -xdev -inum 2607184
调查这些对象。希望您能够删除它们。
- (我不确定你的情况是否是目录)。如果是目录,我怀疑其列表可能不完整。
- 将其内容(如果有)移动到另一个新目录(可能使用相同的所有权、权限创建它);删除旧目录;将
mv
新目录恢复为旧名称。 - 与您的备份进行比较,恢复丢失的对象。
- 将其内容(如果有)移动到另一个新目录(可能使用相同的所有权、权限创建它);删除旧目录;将
- 如果是一个或多个文件 –
- 全部移除。
- 从备份中恢复文件。
- (我不确定你的情况是否是目录)。如果是目录,我怀疑其列表可能不完整。
卸载:
umount /mnt/mountpoint
检查文件系统。有问题的 inode 应该不存在了。
或者,您可以删除整个子卷。这似乎有点过头了,但它应该可以摆脱有问题的 inode。
挂载文件系统的根:
mount /dev/sdXN -o subvol=/ /mnt/mountpoint
列出子卷:
btrfs subvolume list /mnt/mountpoint
并找到 ID 为 257 的那个。
删除子卷:
btrfs subvolume delete -c /mnt/mountpoint/path/to/the/subvolume/with/ID/257
卸载:
umount /mnt/mountpoint
检查文件系统。有问题的 inode 应该不存在了。
- 从备份恢复您的数据。
答案2
我有许多文件扩展名漏洞,我将其定位到 Firefox 缓存文件中(可能是在硬关机之后),感谢 Kamil Maciorowski 的回答。
相同的消息,数十条:
root 259 inode 11192417 错误 100,文件范围折扣
发现文件范围漏洞:开始:0,长度:475136
从这次讨论,这似乎不是一个问题:
文件范围折扣根本不是什么问题,kernel/progs/btrfs-fuse 都可以很好地处理它而没有问题。
对于旧的行为,模式仅要求每个洞都有一个洞范围。
如今,我们为新创建的 fs 启用了无洞功能,并且内核可以很好地处理这种情况。
您甚至可以通过 在 fs 上启用该功能
btrfstune -n <device>
,然后 btrfs 检查就永远不会再困扰您这样的文件范围折扣问题。
关于btrfstune -n
,MAN 说:
-n
(since kernel: 3.14) Enable no-holes feature (more efficient representation of file holes), enabled by mkfs feature no-holes.
和这里我找到了这个:
无洞功能可以为每个洞节省 53 个字节,并且它提供了一个很好的解决方法,以防止 btrfs 检查报告混合直接/缓冲 IO 的非连续文件范围洞。
后一个功能对于开发人员处理基于日志写入的测试用例更有帮助。
确实,btrfstune -n
清理了我的btrfs check
。我在下次只收到此消息check
:
缓存和超代不匹配,空间缓存将失效
我用 修复了它btrfs check --clear-space-cache v1
。
现在,一切都好。
希望这可以帮助其他面临这个奇怪问题的人。