mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 22:21:21 +00:00
xfs: implement freezing by emptying the AIL
Now that we write back all metadata either synchronously or through the AIL we can simply implement metadata freezing in terms of emptying the AIL. The implementation for this is fairly simply and straight-forward: A new routine is added that asks the xfsaild to push the AIL to the end and waits for it to complete and send a wakeup. The routine will then loop if the AIL is not actually empty, and continue to do so until the AIL is compeltely empty. We keep an inode reclaim pass in the freeze process to avoid having memory pressure have to reclaim inodes that require dirtying the filesystem to be reclaimed after the freeze has completed. This means we can also treat unmount in the exact same way as freeze. As an upside we can now remove the radix tree based inode writeback and xfs_unmountfs_writesb. [ Dave Chinner: - Cleaned up commit message. - Added inode reclaim passes back into freeze. - Cleaned up wakeup mechanism to avoid the use of a new sleep counter variable. ] Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
parent
1c30462542
commit
211e4d434b
5 changed files with 56 additions and 135 deletions
|
@ -383,9 +383,8 @@ xfsaild_push(
|
|||
spin_lock(&ailp->xa_lock);
|
||||
}
|
||||
|
||||
target = ailp->xa_target;
|
||||
lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn);
|
||||
if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
|
||||
if (!lip) {
|
||||
/*
|
||||
* AIL is empty or our push has reached the end.
|
||||
*/
|
||||
|
@ -408,6 +407,7 @@ xfsaild_push(
|
|||
* lots of contention on the AIL lists.
|
||||
*/
|
||||
lsn = lip->li_lsn;
|
||||
target = ailp->xa_target;
|
||||
while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
|
||||
int lock_result;
|
||||
/*
|
||||
|
@ -466,11 +466,6 @@ xfsaild_push(
|
|||
}
|
||||
|
||||
spin_lock(&ailp->xa_lock);
|
||||
/* should we bother continuing? */
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
break;
|
||||
ASSERT(mp->m_log);
|
||||
|
||||
count++;
|
||||
|
||||
/*
|
||||
|
@ -610,6 +605,30 @@ xfs_ail_push_all(
|
|||
xfs_ail_push(ailp, threshold_lsn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push out all items in the AIL immediately and wait until the AIL is empty.
|
||||
*/
|
||||
void
|
||||
xfs_ail_push_all_sync(
|
||||
struct xfs_ail *ailp)
|
||||
{
|
||||
struct xfs_log_item *lip;
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
spin_lock(&ailp->xa_lock);
|
||||
while ((lip = xfs_ail_max(ailp)) != NULL) {
|
||||
prepare_to_wait(&ailp->xa_empty, &wait, TASK_UNINTERRUPTIBLE);
|
||||
ailp->xa_target = lip->li_lsn;
|
||||
wake_up_process(ailp->xa_task);
|
||||
spin_unlock(&ailp->xa_lock);
|
||||
schedule();
|
||||
spin_lock(&ailp->xa_lock);
|
||||
}
|
||||
spin_unlock(&ailp->xa_lock);
|
||||
|
||||
finish_wait(&ailp->xa_empty, &wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfs_trans_ail_update - bulk AIL insertion operation.
|
||||
*
|
||||
|
@ -737,6 +756,8 @@ xfs_trans_ail_delete_bulk(
|
|||
if (mlip_changed) {
|
||||
if (!XFS_FORCED_SHUTDOWN(ailp->xa_mount))
|
||||
xlog_assign_tail_lsn_locked(ailp->xa_mount);
|
||||
if (list_empty(&ailp->xa_ail))
|
||||
wake_up_all(&ailp->xa_empty);
|
||||
spin_unlock(&ailp->xa_lock);
|
||||
|
||||
xfs_log_space_wake(ailp->xa_mount);
|
||||
|
@ -773,6 +794,7 @@ xfs_trans_ail_init(
|
|||
INIT_LIST_HEAD(&ailp->xa_ail);
|
||||
INIT_LIST_HEAD(&ailp->xa_cursors);
|
||||
spin_lock_init(&ailp->xa_lock);
|
||||
init_waitqueue_head(&ailp->xa_empty);
|
||||
|
||||
ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
|
||||
ailp->xa_mount->m_fsname);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue