]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/xfs/xfs_log_recover.c
xfs: Fix oops on IO error during xlog_recover_process_iunlinks()
[karo-tx-linux.git] / fs / xfs / xfs_log_recover.c
index 541a508adea1818c8c9c07486e9908f7ddfa882f..4f5d0ce7854d4a7a63ec722b46822081c182e624 100644 (file)
@@ -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;