|
@@ -2563,43 +2563,41 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
|
|
xfs_mount_t *mp;
|
|
xfs_mount_t *mp;
|
|
xfs_perag_busy_t *bsy;
|
|
xfs_perag_busy_t *bsy;
|
|
xfs_agblock_t uend, bend;
|
|
xfs_agblock_t uend, bend;
|
|
- xfs_lsn_t lsn;
|
|
|
|
|
|
+ xfs_lsn_t lsn = 0;
|
|
int cnt;
|
|
int cnt;
|
|
|
|
|
|
mp = tp->t_mountp;
|
|
mp = tp->t_mountp;
|
|
|
|
|
|
spin_lock(&mp->m_perag[agno].pagb_lock);
|
|
spin_lock(&mp->m_perag[agno].pagb_lock);
|
|
- cnt = mp->m_perag[agno].pagb_count;
|
|
|
|
|
|
|
|
uend = bno + len - 1;
|
|
uend = bno + len - 1;
|
|
|
|
|
|
- /* search pagb_list for this slot, skipping open slots */
|
|
|
|
- for (bsy = mp->m_perag[agno].pagb_list; cnt; bsy++) {
|
|
|
|
|
|
+ /*
|
|
|
|
+ * search pagb_list for this slot, skipping open slots. We have to
|
|
|
|
+ * search the entire array as there may be multiple overlaps and
|
|
|
|
+ * we have to get the most recent LSN for the log force to push out
|
|
|
|
+ * all the transactions that span the range.
|
|
|
|
+ */
|
|
|
|
+ for (cnt = 0; cnt < mp->m_perag[agno].pagb_count; cnt++) {
|
|
|
|
+ bsy = &mp->m_perag[agno].pagb_list[cnt];
|
|
|
|
+ if (!bsy->busy_tp)
|
|
|
|
+ continue;
|
|
|
|
|
|
- /*
|
|
|
|
- * (start1,length1) within (start2, length2)
|
|
|
|
- */
|
|
|
|
- if (bsy->busy_tp != NULL) {
|
|
|
|
- bend = bsy->busy_start + bsy->busy_length - 1;
|
|
|
|
- if ((bno > bend) || (uend < bsy->busy_start)) {
|
|
|
|
- cnt--;
|
|
|
|
- } else {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ bend = bsy->busy_start + bsy->busy_length - 1;
|
|
|
|
+ if (bno > bend || uend < bsy->busy_start)
|
|
|
|
+ continue;
|
|
|
|
|
|
- trace_xfs_alloc_busysearch(mp, agno, bno, len, !!cnt);
|
|
|
|
|
|
+ /* (start1,length1) within (start2, length2) */
|
|
|
|
+ if (XFS_LSN_CMP(bsy->busy_tp->t_commit_lsn, lsn) > 0)
|
|
|
|
+ lsn = bsy->busy_tp->t_commit_lsn;
|
|
|
|
+ }
|
|
|
|
+ spin_unlock(&mp->m_perag[agno].pagb_lock);
|
|
|
|
+ trace_xfs_alloc_busysearch(tp->t_mountp, agno, bno, len, lsn);
|
|
|
|
|
|
/*
|
|
/*
|
|
* If a block was found, force the log through the LSN of the
|
|
* If a block was found, force the log through the LSN of the
|
|
* transaction that freed the block
|
|
* transaction that freed the block
|
|
*/
|
|
*/
|
|
- if (cnt) {
|
|
|
|
- lsn = bsy->busy_tp->t_commit_lsn;
|
|
|
|
- spin_unlock(&mp->m_perag[agno].pagb_lock);
|
|
|
|
|
|
+ if (lsn)
|
|
xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC);
|
|
xfs_log_force(mp, lsn, XFS_LOG_FORCE|XFS_LOG_SYNC);
|
|
- } else {
|
|
|
|
- spin_unlock(&mp->m_perag[agno].pagb_lock);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|