Commits
Vasily Averin authored and Pavel Emelianov committed d03e304a834
[PATCH] ext3: orphan list corruption on bad inodes This patch fixes ext3 orphan list corruption due to bad inodes created in ext3_read_inode(). Trying to catch orhpan list corruption in OpenVZ we found the following debug messages in the logs: May 30 10:39:38 df-rs-l24 kernel: EXT3-fs warning (device sda6): ext3_unlink: Deleting nonexistent file (37901290), 0 Inode 00000101a15b7840: orphan list check failed! 00000773 6f665f00 74616d72 00000573 65725f00 06737270 66000000 616d726f ... Call Trace: [<ffffffff80211ea9>] ext3_destroy_inode+0x79/0x90 [<ffffffff801a2b16>] sys_unlink+0x126/0x1a0 [<ffffffff80111479>] error_exit+0x0/0x81 [<ffffffff80110aba>] system_call+0x7e/0x83 first messages says that unlinked inode has i_nlink=0, then ext3_unlink() adds this inode into orphan list. second message means that this inode has not been removed from orphan list, and inode dump shows that i_fop = &bad_file_ops Then I've discovered that bad_file_ops can be set only in make_bad_inode(). ext3_read_inode() can call make_bad_inode() without any error/warning messages in the following case: ... if (inode->i_nlink == 0) { if (inode->i_mode == 0 || !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) { /* this inode is deleted */ brelse (bh); goto bad_inode; ... i.e when inode->i_nlink == 0 and !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS) Bad inode can live some time, ext3_unlink can add it to orphan list then, but ext3_delete_inode() doesn't delete this inode from orphan list, since inode is bad. As a result we have orphan list corruption detected in ext3_destroy_inode(). This issue present in rhel4/rhel5/mainstream kernels too.