lvresize
我们尝试使用以下命令来增加 15TB 分区的大小:
lvresize --resizefs --size +1T /dev/vg0/mm
操作过程中没有显示任何错误,但结果却有点灾难性。没有任何文件可见,整个驱动器似乎都是空的。
syslog
包含以下错误:
inode #2: block 31777: comm ls: bad entry in directory: inode out of bounds - offset=0(0), inode=2, rec_len=12, name_len=1
我们设法进行了umount
分区并且计划运行fsck
来修复它:
$ fsck.ext4 -n /dev/mapper/vg0-mm
e2fsck 1.42.9 (4-Feb-2014)
Superblock has an invalid journal (inode 8).
Clear? no
fsck.ext4: Illegal inode number while checking ext3 journal for /dev/mapper/vg0-mm
/dev/mapper/vg0-mm: ********** WARNING: Filesystem still has errors **********
$ fsck.ext4 -v /dev/mapper/vg0-mm
e2fsck 1.42.9 (4-Feb-2014)
Superblock has an invalid journal (inode 8).
Clear<y>? yes
*** ext3 journal has been deleted - filesystem is now ext2 only ***
Corruption found in superblock. (inodes_count = 0).
The superblock could not be read or does not describe a valid ext2/ext3/ext4
filesystem. If the device is valid and it really contains an ext2/ext3/ext4
filesystem (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
e2fsck -b 8193 <device>
or
e2fsck -b 32768 <device>
/dev/mapper/vg0-mm: ***** FILE SYSTEM WAS MODIFIED *****
好的,接下来尝试列出可用的备用超级块:
$ mke2fs -n /dev/mapper/vg0-mm
mke2fs 1.42.9 (4-Feb-2014)
mke2fs: Size of device (0x100000000 blocks) /dev/mapper/vg0-mm too big to be expressed in 32 bits using a blocksize of 4096.
因此看起来我们意外地超出了 16TB 的限制,lvresize
并且我们的 ext4fs 没有启用 64 位功能标志。
之后,我们尝试将大小减小到 16TB 限制以下,但 resize2fs 也不起作用,因为它认为分区(显然)很脏并且不想对其执行任何操作。
有什么建议下一步该怎么做吗?强制运行调整大小或尝试启用 64 位功能标志?还有其他吗?
dumpe2fs
显示此信息(以及其他信息):
Inode count: 0
Block count: 4294967295
Block size: 4096
相关版本信息:
cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"
e2fsprogs version: 1.42.9-3ubuntu1.3 amd64
Kernel version: 3.13.0-147-generic
更新:阅读一些源代码后,我们发现了问题的根本原因:https://github.com/torvalds/linux/commit/4f2f76f751433908364ccff82f437a57d0e6e9b7
问题仍然存在,如何从由于溢出错误而导致 inode 计数被重置为 0 的情况中恢复。
答案1
似乎早在 2009 年就首次发现了使用 --resizefs 选项以及 ext 文件系统和最后一个字节完整的 16 TB 大分区的 lvresize 的奇怪行为:(https://www.redhat.com/archives/ext3-users/2009-January/msg00003.html)
“如果遇到这样的边界条件,我们应该让 mkfs 悄悄地砍掉一个块...”
片尾字幕?
我们能够通过手动破解超级块来修复这种情况。我们首先对启动情况进行了 LVM 快照。然后我们将分区的前 64k 字节转储到文件中以进行更仔细的检查。由于上面列出的错误,超级块最开始处的 Inode 计数和块计数值被破坏了。(https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Layout)
根据对 e2fsprogs 源代码的研究,我们确定通过将 Inode 计数和块计数值写入比最大值小一个块组(32k)的超级块可能是一个不错的尝试,而且它确实有效。字节为
00 80 ff ff 00 80 ff ff
我们只是将它们添加到分区中。
使用最新版本的自编译 e2fsprogs 的 fsck 可以修复其余错误。现在一切似乎都正常了。