From: yangerkun yangerkun@huawei.com
Offering: HULK hulk inclusion category: bugfix bugzilla: 189240, https://gitee.com/openeuler/kernel/issues/I76JSK
--------------------------------
Once we free exact one inode twice in xfs_difree_inobt, this lead to that ir_freecount does not match ir_free(ir_freecount will add twice, but ir_free will change only once), and the latter xfs_inobt_get_rec will bark for the mismatch of the ir_freecount and ir_free. Once we call xfs_inobt_get_rec when we process AGI unlinked lists, this will fail xfs mount.
We has not found the root cause why we free exact one inode twice, but we really should reject this for the purpose to not spread mistakes.
Signed-off-by: yangerkun yangerkun@huawei.com Signed-off-by: Long Li leo.lilong@huawei.com --- fs/xfs/libxfs/xfs_ialloc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 0c2b7a6601a0..a1319f9c8ed8 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1989,7 +1989,11 @@ xfs_difree_inobt( */ off = agino - rec.ir_startino; ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK); - ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off))); + + if (XFS_IS_CORRUPT(mp, rec.ir_free & XFS_INOBT_MASK(off))) { + error = -EFSCORRUPTED; + goto error0; + } /* * Mark the inode free & increment the count. */