diff options
Diffstat (limited to 'fs/xfs/xfs_trans_ail.c')
-rw-r--r-- | fs/xfs/xfs_trans_ail.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 77acc53f2f31..0425ca16738b 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -383,9 +383,8 @@ xfsaild_push( | |||
383 | spin_lock(&ailp->xa_lock); | 383 | spin_lock(&ailp->xa_lock); |
384 | } | 384 | } |
385 | 385 | ||
386 | target = ailp->xa_target; | ||
387 | lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn); | 386 | lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn); |
388 | if (!lip || XFS_FORCED_SHUTDOWN(mp)) { | 387 | if (!lip) { |
389 | /* | 388 | /* |
390 | * AIL is empty or our push has reached the end. | 389 | * AIL is empty or our push has reached the end. |
391 | */ | 390 | */ |
@@ -408,6 +407,7 @@ xfsaild_push( | |||
408 | * lots of contention on the AIL lists. | 407 | * lots of contention on the AIL lists. |
409 | */ | 408 | */ |
410 | lsn = lip->li_lsn; | 409 | lsn = lip->li_lsn; |
410 | target = ailp->xa_target; | ||
411 | while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { | 411 | while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { |
412 | int lock_result; | 412 | int lock_result; |
413 | /* | 413 | /* |
@@ -466,11 +466,6 @@ xfsaild_push( | |||
466 | } | 466 | } |
467 | 467 | ||
468 | spin_lock(&ailp->xa_lock); | 468 | spin_lock(&ailp->xa_lock); |
469 | /* should we bother continuing? */ | ||
470 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
471 | break; | ||
472 | ASSERT(mp->m_log); | ||
473 | |||
474 | count++; | 469 | count++; |
475 | 470 | ||
476 | /* | 471 | /* |
@@ -611,6 +606,30 @@ xfs_ail_push_all( | |||
611 | } | 606 | } |
612 | 607 | ||
613 | /* | 608 | /* |
609 | * Push out all items in the AIL immediately and wait until the AIL is empty. | ||
610 | */ | ||
611 | void | ||
612 | xfs_ail_push_all_sync( | ||
613 | struct xfs_ail *ailp) | ||
614 | { | ||
615 | struct xfs_log_item *lip; | ||
616 | DEFINE_WAIT(wait); | ||
617 | |||
618 | spin_lock(&ailp->xa_lock); | ||
619 | while ((lip = xfs_ail_max(ailp)) != NULL) { | ||
620 | prepare_to_wait(&ailp->xa_empty, &wait, TASK_UNINTERRUPTIBLE); | ||
621 | ailp->xa_target = lip->li_lsn; | ||
622 | wake_up_process(ailp->xa_task); | ||
623 | spin_unlock(&ailp->xa_lock); | ||
624 | schedule(); | ||
625 | spin_lock(&ailp->xa_lock); | ||
626 | } | ||
627 | spin_unlock(&ailp->xa_lock); | ||
628 | |||
629 | finish_wait(&ailp->xa_empty, &wait); | ||
630 | } | ||
631 | |||
632 | /* | ||
614 | * xfs_trans_ail_update - bulk AIL insertion operation. | 633 | * xfs_trans_ail_update - bulk AIL insertion operation. |
615 | * | 634 | * |
616 | * @xfs_trans_ail_update takes an array of log items that all need to be | 635 | * @xfs_trans_ail_update takes an array of log items that all need to be |
@@ -737,6 +756,8 @@ xfs_trans_ail_delete_bulk( | |||
737 | if (mlip_changed) { | 756 | if (mlip_changed) { |
738 | if (!XFS_FORCED_SHUTDOWN(ailp->xa_mount)) | 757 | if (!XFS_FORCED_SHUTDOWN(ailp->xa_mount)) |
739 | xlog_assign_tail_lsn_locked(ailp->xa_mount); | 758 | xlog_assign_tail_lsn_locked(ailp->xa_mount); |
759 | if (list_empty(&ailp->xa_ail)) | ||
760 | wake_up_all(&ailp->xa_empty); | ||
740 | spin_unlock(&ailp->xa_lock); | 761 | spin_unlock(&ailp->xa_lock); |
741 | 762 | ||
742 | xfs_log_space_wake(ailp->xa_mount); | 763 | xfs_log_space_wake(ailp->xa_mount); |
@@ -773,6 +794,7 @@ xfs_trans_ail_init( | |||
773 | INIT_LIST_HEAD(&ailp->xa_ail); | 794 | INIT_LIST_HEAD(&ailp->xa_ail); |
774 | INIT_LIST_HEAD(&ailp->xa_cursors); | 795 | INIT_LIST_HEAD(&ailp->xa_cursors); |
775 | spin_lock_init(&ailp->xa_lock); | 796 | spin_lock_init(&ailp->xa_lock); |
797 | init_waitqueue_head(&ailp->xa_empty); | ||
776 | 798 | ||
777 | ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s", | 799 | ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s", |
778 | ailp->xa_mount->m_fsname); | 800 | ailp->xa_mount->m_fsname); |