diff options
author | David Chinner <david@fromorbit.com> | 2008-10-30 02:38:39 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 02:38:39 -0400 |
commit | 27d8d5fe0ef9daeaafbdd32b14b32a2211930062 (patch) | |
tree | e170fd577c1f6e58bee1cabb5cad75ced643c3ac /fs/xfs/xfs_log.c | |
parent | 82fa9012458d867936d7bf130e6e14bdebc6873c (diff) |
[XFS] Use a cursor for AIL traversal.
To replace the current generation number ensuring sanity of the AIL
traversal, replace it with an external cursor that is linked to the AIL.
Basically, we store the next item in the cursor whenever we want to drop
the AIL lock to do something to the current item. When we regain the lock.
the current item may already be free, so we can't reference it, but the
next item in the traversal is already held in the cursor.
When we move or delete an object, we search all the active cursors and if
there is an item match we clear the cursor(s) that point to the object.
This forces the traversal to restart transparently.
We don't invalidate the cursor on insert because the cursor still points
to a valid item. If the intem is inserted between the current item and the
cursor it does not matter; the traversal is considered to be past the
insertion point so it will be picked up in the next traversal.
Hence traversal restarts pretty much disappear altogether with this method
of traversal, which should substantially reduce the overhead of pushing on
a busy AIL.
Version 2 o add restart logic o comment cursor interface o minor cleanups
SGI-PV: 988143
SGI-Modid: xfs-linux-melb:xfs-kern:32347a
Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 0b02c644355..4184085d44a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -900,7 +900,7 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
900 | int | 900 | int |
901 | xfs_log_need_covered(xfs_mount_t *mp) | 901 | xfs_log_need_covered(xfs_mount_t *mp) |
902 | { | 902 | { |
903 | int needed = 0, gen; | 903 | int needed = 0; |
904 | xlog_t *log = mp->m_log; | 904 | xlog_t *log = mp->m_log; |
905 | 905 | ||
906 | if (!xfs_fs_writable(mp)) | 906 | if (!xfs_fs_writable(mp)) |
@@ -909,7 +909,7 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
909 | spin_lock(&log->l_icloglock); | 909 | spin_lock(&log->l_icloglock); |
910 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || | 910 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || |
911 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) | 911 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) |
912 | && !xfs_trans_first_ail(mp, &gen) | 912 | && !xfs_trans_first_ail(mp, NULL) |
913 | && xlog_iclogs_empty(log)) { | 913 | && xlog_iclogs_empty(log)) { |
914 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | 914 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) |
915 | log->l_covered_state = XLOG_STATE_COVER_DONE; | 915 | log->l_covered_state = XLOG_STATE_COVER_DONE; |