Commit 57c2e62d authored by Glen Overby's avatar Glen Overby Committed by Christoph Hellwig

[XFS] fix one more set of transaction callback ordering issues,

this was always there, but exposed by the last change in
this area and made much more likely.

SGI Modid: 2.5.x-xfs:slinx:139655a
parent 61bcd68e
...@@ -378,17 +378,26 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ ...@@ -378,17 +378,26 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
iclog->ic_callback_tail = &(cb->cb_next); iclog->ic_callback_tail = &(cb->cb_next);
} }
LOG_UNLOCK(log, spl); LOG_UNLOCK(log, spl);
if (!abortflg) { if (abortflg) {
if (xlog_state_release_iclog(log, iclog)) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
return EIO;
}
} else {
cb->cb_func(cb->cb_arg, abortflg); cb->cb_func(cb->cb_arg, abortflg);
} }
return 0; return 0;
} /* xfs_log_notify */ } /* xfs_log_notify */
int
xfs_log_release_iclog(xfs_mount_t *mp,
void *iclog_hndl)
{
xlog_t *log = mp->m_log;
xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
if (xlog_state_release_iclog(log, iclog)) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
return(EIO);
}
return 0;
}
/* /*
* Initialize log manager data. This routine is intended to be called when * Initialize log manager data. This routine is intended to be called when
......
...@@ -164,6 +164,8 @@ void xfs_log_move_tail(struct xfs_mount *mp, ...@@ -164,6 +164,8 @@ void xfs_log_move_tail(struct xfs_mount *mp,
int xfs_log_notify(struct xfs_mount *mp, int xfs_log_notify(struct xfs_mount *mp,
void *iclog, void *iclog,
xfs_log_callback_t *callback_entry); xfs_log_callback_t *callback_entry);
int xfs_log_release_iclog(struct xfs_mount *mp,
void *iclog_hndl);
int xfs_log_reserve(struct xfs_mount *mp, int xfs_log_reserve(struct xfs_mount *mp,
int length, int length,
int count, int count,
......
...@@ -808,19 +808,6 @@ xfs_trans_commit( ...@@ -808,19 +808,6 @@ xfs_trans_commit(
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
/*
* Once all the items of the transaction have been copied
* to the in core log we can release them. Do that here.
* This will free descriptors pointing to items which were
* not logged since there is nothing more to do with them.
* For items which were logged, we will keep pointers to them
* so they can be unpinned after the transaction commits to disk.
* This will also stamp each modified meta-data item with
* the commit lsn of this transaction for dependency tracking
* purposes.
*/
xfs_trans_unlock_items(tp, commit_lsn);
/* /*
* Once the transaction has committed, unused * Once the transaction has committed, unused
* reservations need to be released and changes to * reservations need to be released and changes to
...@@ -856,12 +843,36 @@ xfs_trans_commit( ...@@ -856,12 +843,36 @@ xfs_trans_commit(
tp->t_logcb.cb_arg = tp; tp->t_logcb.cb_arg = tp;
/* We need to pass the iclog buffer which was used for the /* We need to pass the iclog buffer which was used for the
* transaction commit record into this function, attach * transaction commit record into this function, and attach
* the callback to it, and then release it. This will guarantee * the callback to it. The callback must be attached before
* that we do callbacks on the transaction in the correct order. * the items are unlocked to avoid racing with other threads
* waiting for an item to unlock.
*/ */
error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
#endif #endif
/*
* Once all the items of the transaction have been copied
* to the in core log and the callback is attached, the
* items can be unlocked.
*
* This will free descriptors pointing to items which were
* not logged since there is nothing more to do with them.
* For items which were logged, we will keep pointers to them
* so they can be unpinned after the transaction commits to disk.
* This will also stamp each modified meta-data item with
* the commit lsn of this transaction for dependency tracking
* purposes.
*/
xfs_trans_unlock_items(tp, commit_lsn);
/*
* Now that the xfs_trans_committed callback has been attached,
* and the items are released we can finally allow the iclog to
* go to disk.
*/
error = xfs_log_release_iclog(mp, commit_iclog);
/* /*
* If the transaction needs to be synchronous, then force the * If the transaction needs to be synchronous, then force the
* log out now and wait for it. * log out now and wait for it.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment