/*
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * Copyright (c) 2008 Dave Chinner
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
xfs_lsn_t lsn;
xfs_log_item_t *lip;
- spin_lock(&ailp->xa_mount->m_ail_lock);
+ spin_lock(&ailp->xa_lock);
lip = xfs_ail_min(ailp);
if (lip == NULL) {
lsn = (xfs_lsn_t)0;
} else {
lsn = lip->li_lsn;
}
- spin_unlock(&ailp->xa_mount->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
return lsn;
}
* the push is run asynchronously in a separate thread, so we return the tail
* of the log right now instead of the tail after the push. This means we will
* either continue right away, or we will sleep waiting on the async thread to
- * do it's work.
+ * do its work.
*
* We do this unlocked - we only need to know whether there is anything in the
* AIL at the time we are called. We don't need to access the contents of
* any of the objects, so the lock is not needed.
*/
void
-xfs_trans_push_ail(
- xfs_mount_t *mp,
- xfs_lsn_t threshold_lsn)
+xfs_trans_ail_push(
+ struct xfs_ail *ailp,
+ xfs_lsn_t threshold_lsn)
{
- xfs_log_item_t *lip;
+ xfs_log_item_t *lip;
- lip = xfs_ail_min(mp->m_ail);
- if (lip && !XFS_FORCED_SHUTDOWN(mp)) {
- if (XFS_LSN_CMP(threshold_lsn, mp->m_ail->xa_target) > 0)
- xfsaild_wakeup(mp->m_ail, threshold_lsn);
+ lip = xfs_ail_min(ailp);
+ if (lip && !XFS_FORCED_SHUTDOWN(ailp->xa_mount)) {
+ if (XFS_LSN_CMP(threshold_lsn, ailp->xa_target) > 0)
+ xfsaild_wakeup(ailp, threshold_lsn);
}
}
/*
* Now that the traversal is complete, we need to remove the cursor
* from the list of traversing cursors. Avoid removing the embedded
- * push cursor, but use the fact it is alway present to make the
+ * push cursor, but use the fact it is always present to make the
* list deletion simple.
*/
void
list_for_each_entry(lip, &ailp->xa_ail, li_ail) {
if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0)
- break;
+ goto out;
}
lip = NULL;
out:
xfs_mount_t *mp = ailp->xa_mount;
struct xfs_ail_cursor *cur = &ailp->xa_cursors;
- spin_lock(&mp->m_ail_lock);
+ spin_lock(&ailp->xa_lock);
xfs_trans_ail_cursor_init(ailp, cur);
lip = xfs_trans_ail_cursor_first(ailp, cur, *last_lsn);
if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
* AIL is empty or our push has reached the end.
*/
xfs_trans_ail_cursor_done(ailp, cur);
- spin_unlock(&mp->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
last_pushed_lsn = 0;
return tout;
}
* skip to the next item in the list.
*/
lock_result = IOP_TRYLOCK(lip);
- spin_unlock(&mp->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
switch (lock_result) {
case XFS_ITEM_SUCCESS:
XFS_STATS_INC(xs_push_ail_success);
break;
}
- spin_lock(&mp->m_ail_lock);
+ spin_lock(&ailp->xa_lock);
/* should we bother continuing? */
if (XFS_FORCED_SHUTDOWN(mp))
break;
lsn = lip->li_lsn;
}
xfs_trans_ail_cursor_done(ailp, cur);
- spin_unlock(&mp->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
if (flush_log) {
/*
*/
void
xfs_trans_unlocked_item(
- xfs_mount_t *mp,
+ struct xfs_ail *ailp,
xfs_log_item_t *lip)
{
xfs_log_item_t *min_lip;
* over some potentially valid data.
*/
if (!(lip->li_flags & XFS_LI_IN_AIL) ||
- XFS_FORCED_SHUTDOWN(mp)) {
+ XFS_FORCED_SHUTDOWN(ailp->xa_mount)) {
return;
}
* the call to xfs_log_move_tail() doesn't do anything if there's
* not enough free space to wake people up so we're safe calling it.
*/
- min_lip = xfs_ail_min(mp->m_ail);
+ min_lip = xfs_ail_min(ailp);
if (min_lip == lip)
- xfs_log_move_tail(mp, 1);
+ xfs_log_move_tail(ailp->xa_mount, 1);
} /* xfs_trans_unlocked_item */
* is dropped before returning.
*/
void
-xfs_trans_update_ail(
- xfs_mount_t *mp,
+xfs_trans_ail_update(
+ struct xfs_ail *ailp,
xfs_log_item_t *lip,
- xfs_lsn_t lsn) __releases(mp->m_ail_lock)
+ xfs_lsn_t lsn) __releases(ailp->xa_lock)
{
- xfs_log_item_t *dlip=NULL;
+ xfs_log_item_t *dlip = NULL;
xfs_log_item_t *mlip; /* ptr to minimum lip */
- mlip = xfs_ail_min(mp->m_ail);
+ mlip = xfs_ail_min(ailp);
if (lip->li_flags & XFS_LI_IN_AIL) {
- dlip = xfs_ail_delete(mp->m_ail, lip);
+ dlip = xfs_ail_delete(ailp, lip);
ASSERT(dlip == lip);
- xfs_trans_ail_cursor_clear(mp->m_ail, dlip);
+ xfs_trans_ail_cursor_clear(ailp, dlip);
} else {
lip->li_flags |= XFS_LI_IN_AIL;
}
lip->li_lsn = lsn;
- xfs_ail_insert(mp->m_ail, lip);
+ xfs_ail_insert(ailp, lip);
if (mlip == dlip) {
- mlip = xfs_ail_min(mp->m_ail);
- spin_unlock(&mp->m_ail_lock);
- xfs_log_move_tail(mp, mlip->li_lsn);
+ mlip = xfs_ail_min(ailp);
+ spin_unlock(&ailp->xa_lock);
+ xfs_log_move_tail(ailp->xa_mount, mlip->li_lsn);
} else {
- spin_unlock(&mp->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
}
* is dropped before returning.
*/
void
-xfs_trans_delete_ail(
- xfs_mount_t *mp,
- xfs_log_item_t *lip) __releases(mp->m_ail_lock)
+xfs_trans_ail_delete(
+ struct xfs_ail *ailp,
+ xfs_log_item_t *lip) __releases(ailp->xa_lock)
{
xfs_log_item_t *dlip;
xfs_log_item_t *mlip;
if (lip->li_flags & XFS_LI_IN_AIL) {
- mlip = xfs_ail_min(mp->m_ail);
- dlip = xfs_ail_delete(mp->m_ail, lip);
+ mlip = xfs_ail_min(ailp);
+ dlip = xfs_ail_delete(ailp, lip);
ASSERT(dlip == lip);
- xfs_trans_ail_cursor_clear(mp->m_ail, dlip);
+ xfs_trans_ail_cursor_clear(ailp, dlip);
lip->li_flags &= ~XFS_LI_IN_AIL;
lip->li_lsn = 0;
if (mlip == dlip) {
- mlip = xfs_ail_min(mp->m_ail);
- spin_unlock(&mp->m_ail_lock);
- xfs_log_move_tail(mp, (mlip ? mlip->li_lsn : 0));
+ mlip = xfs_ail_min(ailp);
+ spin_unlock(&ailp->xa_lock);
+ xfs_log_move_tail(ailp->xa_mount,
+ (mlip ? mlip->li_lsn : 0));
} else {
- spin_unlock(&mp->m_ail_lock);
+ spin_unlock(&ailp->xa_lock);
}
}
else {
* If the file system is not being shutdown, we are in
* serious trouble if we get to this stage.
*/
- if (XFS_FORCED_SHUTDOWN(mp))
- spin_unlock(&mp->m_ail_lock);
- else {
+ struct xfs_mount *mp = ailp->xa_mount;
+
+ spin_unlock(&ailp->xa_lock);
+ if (!XFS_FORCED_SHUTDOWN(mp)) {
xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
"%s: attempting to delete a log item that is not in the AIL",
__func__);
- spin_unlock(&mp->m_ail_lock);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
}
}
ailp->xa_mount = mp;
INIT_LIST_HEAD(&ailp->xa_ail);
+ spin_lock_init(&ailp->xa_lock);
error = xfsaild_start(ailp);
if (error)
goto out_free_ailp;