mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-07-27 06:18:13 +00:00
bb34e69f3d
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
85 lines
2.8 KiB
Diff
85 lines
2.8 KiB
Diff
From 2b91e04fb1c28cce172844b2519c4bbedd9849c2 Mon Sep 17 00:00:00 2001
|
|
From: Jan Kara <jack@suse.cz>
|
|
Date: Thu, 15 Mar 2012 09:34:02 +0000
|
|
Subject: [PATCH 124/147] xfs: Fix oops on IO error during
|
|
xlog_recover_process_iunlinks()
|
|
|
|
commit d97d32edcd732110758799ae60af725e5110b3dc upstream.
|
|
|
|
When an IO error happens during inode deletion run from
|
|
xlog_recover_process_iunlinks() filesystem gets shutdown. Thus any subsequent
|
|
attempt to read buffers fails. Code in xlog_recover_process_iunlinks() does not
|
|
count with the fact that read of a buffer which was read a while ago can
|
|
really fail which results in the oops on
|
|
agi = XFS_BUF_TO_AGI(agibp);
|
|
|
|
Fix the problem by cleaning up the buffer handling in
|
|
xlog_recover_process_iunlinks() as suggested by Dave Chinner. We release buffer
|
|
lock but keep buffer reference to AG buffer. That is enough for buffer to stay
|
|
pinned in memory and we don't have to call xfs_read_agi() all the time.
|
|
|
|
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
Reviewed-by: Dave Chinner <dchinner@redhat.com>
|
|
Signed-off-by: Ben Myers <bpm@sgi.com>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
fs/xfs/xfs_log_recover.c | 33 +++++++++++----------------------
|
|
1 file changed, 11 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
|
|
index 541a508..4f5d0ce 100644
|
|
--- 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);
|
|
|
|
for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
|
|
agino = be32_to_cpu(agi->agi_unlinked[bucket]);
|
|
while (agino != NULLAGINO) {
|
|
- /*
|
|
- * Release the agi buffer so that it can
|
|
- * be acquired in the normal course of the
|
|
- * transaction to truncate and free the inode.
|
|
- */
|
|
- xfs_buf_relse(agibp);
|
|
-
|
|
agino = xlog_recover_process_one_iunlink(mp,
|
|
agno, agino, bucket);
|
|
-
|
|
- /*
|
|
- * Reacquire the agibuffer and continue around
|
|
- * the loop. This should never fail as we know
|
|
- * the buffer was good earlier on.
|
|
- */
|
|
- error = xfs_read_agi(mp, NULL, agno, &agibp);
|
|
- ASSERT(error == 0);
|
|
- agi = XFS_BUF_TO_AGI(agibp);
|
|
}
|
|
}
|
|
-
|
|
- /*
|
|
- * Release the buffer for the current agi so we can
|
|
- * go on to the next one.
|
|
- */
|
|
- xfs_buf_relse(agibp);
|
|
+ xfs_buf_rele(agibp);
|
|
}
|
|
|
|
mp->m_dmevmask = mp_dmevmask;
|
|
--
|
|
1.7.9.4
|
|
|