- }
-
- /*
- * Can only perform callbacks in order. Since this iclog is not in the
- * DONE_SYNC/ DO_CALLBACK state, we skip the rest and just try to clean
- * up. If we set our iclog to DO_CALLBACK, we will not process it when
- * we retry since a previous iclog is in the CALLBACK and the state
- * cannot change since we are holding the l_icloglock.
- */
- if (!(iclog->ic_state &
- (XLOG_STATE_DONE_SYNC | XLOG_STATE_DO_CALLBACK))) {
+ case XLOG_STATE_DONE_SYNC:
+ case XLOG_STATE_DO_CALLBACK:
+ /*
+ * Now that we have an iclog that is in either the DO_CALLBACK
+ * or DONE_SYNC states, do one more check here to see if we have
+ * chased our tail around. If this is not the lowest lsn iclog,
+ * then we will leave it for another completion to process.
+ */
+ header_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
+ lowest_lsn = xlog_get_lowest_lsn(log);
+ if (lowest_lsn && XFS_LSN_CMP(lowest_lsn, header_lsn) < 0)
+ return false;
+ xlog_state_set_callback(log, iclog, header_lsn);
+ return false;
+ default:
+ /*
+ * Can only perform callbacks in order. Since this iclog is not
+ * in the DONE_SYNC or DO_CALLBACK states, we skip the rest and
+ * just try to clean up. If we set our iclog to DO_CALLBACK, we
+ * will not process it when we retry since a previous iclog is
+ * in the CALLBACK and the state cannot change since we are
+ * holding l_icloglock.
+ */