When an IO error happens during inode deletion run fromxlog_recover_process_iunlinks() filesystem gets shutdown. Thus any subsequentattempt to read buffers fails. Code in xlog_recover_process_iunlinks() does notcount with the fact that read of a buffer which was read a while ago canreally fail which results in the oops on agi = XFS_BUF_TO_AGI(agibp);

Fix the problem by cleaning up the buffer handling inxlog_recover_process_iunlinks() as suggested by Dave Chinner. We release bufferlock but keep buffer reference to AG buffer. That is enough for buffer to staypinned in memory and we don't have to call xfs_read_agi() all the time.

--- fs/xfs/xfs_log_recover.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-)--- a/fs/xfs/xfs_log_recover.c+++ b/fs/xfs/xfs_log_recover.c@@ -3161,37 +3161,26 @@ xlog_recover_process_iunlinks( */ continue; }+ /*+ * Unlock the buffer so that it can be acquired in the normal+ * course of the transaction to truncate and free each inode.+ * Because we are not racing with anyone else here for the AGI+ * buffer, we don't even need to hold it locked to read the+ * initial unlinked bucket entries out of the buffer. We keep+ * buffer reference though, so that it stays pinned in memory+ * while we need the buffer.+ */ agi = XFS_BUF_TO_AGI(agibp);+ xfs_buf_unlock(agibp);