diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.c | 6 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_ail.c | 50 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_priv.h | 7 |
4 files changed, 61 insertions, 9 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index debe2822c930..9ad956052b69 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "xfs_log.h" | 22 | #include "xfs_log.h" |
| 23 | #include "xfs_inum.h" | 23 | #include "xfs_inum.h" |
| 24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 25 | #include "xfs_trans_priv.h" | ||
| 25 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
| 26 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
| 27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
| @@ -462,6 +463,9 @@ xfs_sync_worker( | |||
| 462 | else | 463 | else |
| 463 | xfs_log_force(mp, 0); | 464 | xfs_log_force(mp, 0); |
| 464 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); | 465 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); |
| 466 | |||
| 467 | /* start pushing all the metadata that is currently dirty */ | ||
| 468 | xfs_ail_push_all(mp->m_ail); | ||
| 465 | } | 469 | } |
| 466 | 470 | ||
| 467 | /* queue us up again */ | 471 | /* queue us up again */ |
| @@ -1027,8 +1031,9 @@ xfs_reclaim_inode_shrink( | |||
| 1027 | 1031 | ||
| 1028 | mp = container_of(shrink, struct xfs_mount, m_inode_shrink); | 1032 | mp = container_of(shrink, struct xfs_mount, m_inode_shrink); |
| 1029 | if (nr_to_scan) { | 1033 | if (nr_to_scan) { |
| 1030 | /* kick background reclaimer */ | 1034 | /* kick background reclaimer and push the AIL */ |
| 1031 | xfs_syncd_queue_reclaim(mp); | 1035 | xfs_syncd_queue_reclaim(mp); |
| 1036 | xfs_ail_push_all(mp->m_ail); | ||
| 1032 | 1037 | ||
| 1033 | if (!(gfp_mask & __GFP_FS)) | 1038 | if (!(gfp_mask & __GFP_FS)) |
| 1034 | return -1; | 1039 | return -1; |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 25efa9b8a602..24643169e632 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -761,7 +761,7 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
| 761 | break; | 761 | break; |
| 762 | case XLOG_STATE_COVER_NEED: | 762 | case XLOG_STATE_COVER_NEED: |
| 763 | case XLOG_STATE_COVER_NEED2: | 763 | case XLOG_STATE_COVER_NEED2: |
| 764 | if (!xfs_trans_ail_tail(log->l_ailp) && | 764 | if (!xfs_ail_min_lsn(log->l_ailp) && |
| 765 | xlog_iclogs_empty(log)) { | 765 | xlog_iclogs_empty(log)) { |
| 766 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | 766 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) |
| 767 | log->l_covered_state = XLOG_STATE_COVER_DONE; | 767 | log->l_covered_state = XLOG_STATE_COVER_DONE; |
| @@ -801,7 +801,7 @@ xlog_assign_tail_lsn( | |||
| 801 | xfs_lsn_t tail_lsn; | 801 | xfs_lsn_t tail_lsn; |
| 802 | struct log *log = mp->m_log; | 802 | struct log *log = mp->m_log; |
| 803 | 803 | ||
| 804 | tail_lsn = xfs_trans_ail_tail(mp->m_ail); | 804 | tail_lsn = xfs_ail_min_lsn(mp->m_ail); |
| 805 | if (!tail_lsn) | 805 | if (!tail_lsn) |
| 806 | tail_lsn = atomic64_read(&log->l_last_sync_lsn); | 806 | tail_lsn = atomic64_read(&log->l_last_sync_lsn); |
| 807 | 807 | ||
| @@ -1239,7 +1239,7 @@ xlog_grant_push_ail( | |||
| 1239 | * the filesystem is shutting down. | 1239 | * the filesystem is shutting down. |
| 1240 | */ | 1240 | */ |
| 1241 | if (!XLOG_FORCED_SHUTDOWN(log)) | 1241 | if (!XLOG_FORCED_SHUTDOWN(log)) |
| 1242 | xfs_trans_ail_push(log->l_ailp, threshold_lsn); | 1242 | xfs_ail_push(log->l_ailp, threshold_lsn); |
| 1243 | } | 1243 | } |
| 1244 | 1244 | ||
| 1245 | /* | 1245 | /* |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 8012bfbc6dc0..acdb92f14d51 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
| @@ -90,6 +90,20 @@ xfs_ail_min( | |||
| 90 | return list_first_entry(&ailp->xa_ail, xfs_log_item_t, li_ail); | 90 | return list_first_entry(&ailp->xa_ail, xfs_log_item_t, li_ail); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* | ||
| 94 | * Return a pointer to the last item in the AIL. If the AIL is empty, then | ||
| 95 | * return NULL. | ||
| 96 | */ | ||
| 97 | static xfs_log_item_t * | ||
| 98 | xfs_ail_max( | ||
| 99 | struct xfs_ail *ailp) | ||
| 100 | { | ||
| 101 | if (list_empty(&ailp->xa_ail)) | ||
| 102 | return NULL; | ||
| 103 | |||
| 104 | return list_entry(ailp->xa_ail.prev, xfs_log_item_t, li_ail); | ||
| 105 | } | ||
| 106 | |||
| 93 | /* | 107 | /* |
| 94 | * Return a pointer to the item which follows the given item in the AIL. If | 108 | * Return a pointer to the item which follows the given item in the AIL. If |
| 95 | * the given item is the last item in the list, then return NULL. | 109 | * the given item is the last item in the list, then return NULL. |
| @@ -114,7 +128,7 @@ xfs_ail_next( | |||
| 114 | * item in the AIL. | 128 | * item in the AIL. |
| 115 | */ | 129 | */ |
| 116 | xfs_lsn_t | 130 | xfs_lsn_t |
| 117 | xfs_trans_ail_tail( | 131 | xfs_ail_min_lsn( |
| 118 | struct xfs_ail *ailp) | 132 | struct xfs_ail *ailp) |
| 119 | { | 133 | { |
| 120 | xfs_lsn_t lsn = 0; | 134 | xfs_lsn_t lsn = 0; |
| @@ -130,6 +144,25 @@ xfs_trans_ail_tail( | |||
| 130 | } | 144 | } |
| 131 | 145 | ||
| 132 | /* | 146 | /* |
| 147 | * Return the maximum lsn held in the AIL, or zero if the AIL is empty. | ||
| 148 | */ | ||
| 149 | static xfs_lsn_t | ||
| 150 | xfs_ail_max_lsn( | ||
| 151 | struct xfs_ail *ailp) | ||
| 152 | { | ||
| 153 | xfs_lsn_t lsn = 0; | ||
| 154 | xfs_log_item_t *lip; | ||
| 155 | |||
| 156 | spin_lock(&ailp->xa_lock); | ||
| 157 | lip = xfs_ail_max(ailp); | ||
| 158 | if (lip) | ||
| 159 | lsn = lip->li_lsn; | ||
| 160 | spin_unlock(&ailp->xa_lock); | ||
| 161 | |||
| 162 | return lsn; | ||
| 163 | } | ||
| 164 | |||
| 165 | /* | ||
| 133 | * AIL traversal cursor initialisation. | 166 | * AIL traversal cursor initialisation. |
| 134 | * | 167 | * |
| 135 | * The cursor keeps track of where our current traversal is up | 168 | * The cursor keeps track of where our current traversal is up |
| @@ -504,7 +537,7 @@ xfs_ail_worker( | |||
| 504 | * any of the objects, so the lock is not needed. | 537 | * any of the objects, so the lock is not needed. |
| 505 | */ | 538 | */ |
| 506 | void | 539 | void |
| 507 | xfs_trans_ail_push( | 540 | xfs_ail_push( |
| 508 | struct xfs_ail *ailp, | 541 | struct xfs_ail *ailp, |
| 509 | xfs_lsn_t threshold_lsn) | 542 | xfs_lsn_t threshold_lsn) |
| 510 | { | 543 | { |
| @@ -526,6 +559,19 @@ xfs_trans_ail_push( | |||
| 526 | } | 559 | } |
| 527 | 560 | ||
| 528 | /* | 561 | /* |
| 562 | * Push out all items in the AIL immediately | ||
| 563 | */ | ||
| 564 | void | ||
| 565 | xfs_ail_push_all( | ||
| 566 | struct xfs_ail *ailp) | ||
| 567 | { | ||
| 568 | xfs_lsn_t threshold_lsn = xfs_ail_max_lsn(ailp); | ||
| 569 | |||
| 570 | if (threshold_lsn) | ||
| 571 | xfs_ail_push(ailp, threshold_lsn); | ||
| 572 | } | ||
| 573 | |||
| 574 | /* | ||
| 529 | * This is to be called when an item is unlocked that may have | 575 | * This is to be called when an item is unlocked that may have |
| 530 | * been in the AIL. It will wake up the first member of the AIL | 576 | * been in the AIL. It will wake up the first member of the AIL |
| 531 | * wait list if this item's unlocking might allow it to progress. | 577 | * wait list if this item's unlocking might allow it to progress. |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 6ebd322bd37c..6b164e9e9a1f 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
| @@ -104,12 +104,13 @@ xfs_trans_ail_delete( | |||
| 104 | xfs_trans_ail_delete_bulk(ailp, &lip, 1); | 104 | xfs_trans_ail_delete_bulk(ailp, &lip, 1); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | void xfs_trans_ail_push(struct xfs_ail *, xfs_lsn_t); | 107 | void xfs_ail_push(struct xfs_ail *, xfs_lsn_t); |
| 108 | void xfs_ail_push_all(struct xfs_ail *); | ||
| 109 | xfs_lsn_t xfs_ail_min_lsn(struct xfs_ail *ailp); | ||
| 110 | |||
| 108 | void xfs_trans_unlocked_item(struct xfs_ail *, | 111 | void xfs_trans_unlocked_item(struct xfs_ail *, |
| 109 | xfs_log_item_t *); | 112 | xfs_log_item_t *); |
| 110 | 113 | ||
| 111 | xfs_lsn_t xfs_trans_ail_tail(struct xfs_ail *ailp); | ||
| 112 | |||
| 113 | struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp, | 114 | struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp, |
| 114 | struct xfs_ail_cursor *cur, | 115 | struct xfs_ail_cursor *cur, |
| 115 | xfs_lsn_t lsn); | 116 | xfs_lsn_t lsn); |
