意外将 ext4fs 的大小调整到了超过 16TB 的限制,如何回滚?

意外将 ext4fs 的大小调整到了超过 16TB 的限制,如何回滚?

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 可以修复其余错误。现在一切似乎都正常了。

相关内容