diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 235fcf6dc4ee..ae22f361627f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -530,7 +530,6 @@ xlog_state_release_iclog( struct xlog_in_core *iclog, struct xlog_ticket *ticket) { - xfs_lsn_t tail_lsn; bool last_ref; lockdep_assert_held(&log->l_icloglock); @@ -545,8 +544,8 @@ xlog_state_release_iclog( if ((iclog->ic_state == XLOG_STATE_WANT_SYNC || (iclog->ic_flags & XLOG_ICL_NEED_FUA)) && !iclog->ic_header.h_tail_lsn) { - tail_lsn = xlog_assign_tail_lsn(log->l_mp); - iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); + iclog->ic_header.h_tail_lsn = + cpu_to_be64(atomic64_read(&log->l_tail_lsn)); } last_ref = atomic_dec_and_test(&iclog->ic_refcnt); diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 26d4d9b3e357..7d6ccd21aae2 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -720,6 +720,13 @@ xfs_ail_push_all_sync( finish_wait(&ailp->ail_empty, &wait); } +/* + * Callers should pass the original tail lsn so that we can detect if the tail + * has moved as a result of the operation that was performed. If the caller + * needs to force a tail LSN update, it should pass NULLCOMMITLSN to bypass the + * "did the tail LSN change?" checks. If the caller wants to avoid a tail update + * (e.g. it knows the tail did not change) it should pass an @old_lsn of 0. + */ void xfs_ail_update_finish( struct xfs_ail *ailp, @@ -804,10 +811,16 @@ xfs_trans_ail_update_bulk( /* * If this is the first insert, wake up the push daemon so it can - * actively scan for items to push. + * actively scan for items to push. We also need to do a log tail + * LSN update to ensure that it is correctly tracked by the log, so + * set the tail_lsn to NULLCOMMITLSN so that xfs_ail_update_finish() + * will see that the tail lsn has changed and will update the tail + * appropriately. */ - if (!mlip) + if (!mlip) { wake_up_process(ailp->ail_task); + tail_lsn = NULLCOMMITLSN; + } xfs_ail_update_finish(ailp, tail_lsn); }