aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_ail.c
diff options
context:
space:
mode:
authorDavid Chinner <david@fromorbit.com>2008-10-30 02:39:00 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 02:39:00 -0400
commit5b00f14fbd60d42441f78c0e414a539cbfba5cb9 (patch)
tree6ecce1247c704666e2835883de73cb300c1b0693 /fs/xfs/xfs_trans_ail.c
parent27d8d5fe0ef9daeaafbdd32b14b32a2211930062 (diff)
[XFS] move the AIl traversal over to a consistent interface
With the new cursor interface, it makes sense to make all the traversing code use the cursor interface and make the old one go away. This means more of the AIL interfacing is done by passing struct xfs_ail pointers around the place instead of struct xfs_mount pointers. We can replace the use of xfs_trans_first_ail() in xfs_log_need_covered() as it is only checking if the AIL is empty. We can do that with a call to xfs_trans_ail_tail() instead, where a zero LSN returned indicates and empty AIL... SGI-PV: 988143 SGI-Modid: xfs-linux-melb:xfs-kern:32348a 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_trans_ail.c')
-rw-r--r--fs/xfs/xfs_trans_ail.c117
1 files changed, 42 insertions, 75 deletions
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 7b8bfcf1d3da..286934d56ec7 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -50,20 +50,20 @@ STATIC void xfs_ail_check(struct xfs_ail *, xfs_log_item_t *);
50 * lsn of the last item in the AIL. 50 * lsn of the last item in the AIL.
51 */ 51 */
52xfs_lsn_t 52xfs_lsn_t
53xfs_trans_tail_ail( 53xfs_trans_ail_tail(
54 xfs_mount_t *mp) 54 struct xfs_ail *ailp)
55{ 55{
56 xfs_lsn_t lsn; 56 xfs_lsn_t lsn;
57 xfs_log_item_t *lip; 57 xfs_log_item_t *lip;
58 58
59 spin_lock(&mp->m_ail_lock); 59 spin_lock(&ailp->xa_mount->m_ail_lock);
60 lip = xfs_ail_min(mp->m_ail); 60 lip = xfs_ail_min(ailp);
61 if (lip == NULL) { 61 if (lip == NULL) {
62 lsn = (xfs_lsn_t)0; 62 lsn = (xfs_lsn_t)0;
63 } else { 63 } else {
64 lsn = lip->li_lsn; 64 lsn = lip->li_lsn;
65 } 65 }
66 spin_unlock(&mp->m_ail_lock); 66 spin_unlock(&ailp->xa_mount->m_ail_lock);
67 67
68 return lsn; 68 return lsn;
69} 69}
@@ -111,7 +111,7 @@ xfs_trans_push_ail(
111 * We don't link the push cursor because it is embedded in the struct 111 * We don't link the push cursor because it is embedded in the struct
112 * xfs_ail and hence easily findable. 112 * xfs_ail and hence easily findable.
113 */ 113 */
114void 114STATIC void
115xfs_trans_ail_cursor_init( 115xfs_trans_ail_cursor_init(
116 struct xfs_ail *ailp, 116 struct xfs_ail *ailp,
117 struct xfs_ail_cursor *cur) 117 struct xfs_ail_cursor *cur)
@@ -143,7 +143,7 @@ xfs_trans_ail_cursor_set(
143 * If the cursor was invalidated (inidicated by a lip of 1), 143 * If the cursor was invalidated (inidicated by a lip of 1),
144 * restart the traversal. 144 * restart the traversal.
145 */ 145 */
146STATIC struct xfs_log_item * 146struct xfs_log_item *
147xfs_trans_ail_cursor_next( 147xfs_trans_ail_cursor_next(
148 struct xfs_ail *ailp, 148 struct xfs_ail *ailp,
149 struct xfs_ail_cursor *cur) 149 struct xfs_ail_cursor *cur)
@@ -157,30 +157,6 @@ xfs_trans_ail_cursor_next(
157} 157}
158 158
159/* 159/*
160 * Invalidate any cursor that is pointing to this item. This is
161 * called when an item is removed from the AIL. Any cursor pointing
162 * to this object is now invalid and the traversal needs to be
163 * terminated so it doesn't reference a freed object. We set the
164 * cursor item to a value of 1 so we can distinguish between an
165 * invalidation and the end of the list when getting the next item
166 * from the cursor.
167 */
168STATIC void
169xfs_trans_ail_cursor_clear(
170 struct xfs_ail *ailp,
171 struct xfs_log_item *lip)
172{
173 struct xfs_ail_cursor *cur;
174
175 /* need to search all cursors */
176 for (cur = &ailp->xa_cursors; cur; cur = cur->next) {
177 if (cur->item == lip)
178 cur->item = (struct xfs_log_item *)
179 ((__psint_t)cur->item | 1);
180 }
181}
182
183/*
184 * Now that the traversal is complete, we need to remove the cursor 160 * Now that the traversal is complete, we need to remove the cursor
185 * from the list of traversing cursors. Avoid removing the embedded 161 * from the list of traversing cursors. Avoid removing the embedded
186 * push cursor, but use the fact it is alway present to make the 162 * push cursor, but use the fact it is alway present to make the
@@ -208,31 +184,55 @@ xfs_trans_ail_cursor_done(
208} 184}
209 185
210/* 186/*
187 * Invalidate any cursor that is pointing to this item. This is
188 * called when an item is removed from the AIL. Any cursor pointing
189 * to this object is now invalid and the traversal needs to be
190 * terminated so it doesn't reference a freed object. We set the
191 * cursor item to a value of 1 so we can distinguish between an
192 * invalidation and the end of the list when getting the next item
193 * from the cursor.
194 */
195STATIC void
196xfs_trans_ail_cursor_clear(
197 struct xfs_ail *ailp,
198 struct xfs_log_item *lip)
199{
200 struct xfs_ail_cursor *cur;
201
202 /* need to search all cursors */
203 for (cur = &ailp->xa_cursors; cur; cur = cur->next) {
204 if (cur->item == lip)
205 cur->item = (struct xfs_log_item *)
206 ((__psint_t)cur->item | 1);
207 }
208}
209
210/*
211 * Return the item in the AIL with the current lsn. 211 * Return the item in the AIL with the current lsn.
212 * Return the current tree generation number for use 212 * Return the current tree generation number for use
213 * in calls to xfs_trans_next_ail(). 213 * in calls to xfs_trans_next_ail().
214 */ 214 */
215STATIC xfs_log_item_t * 215xfs_log_item_t *
216xfs_trans_first_push_ail( 216xfs_trans_ail_cursor_first(
217 struct xfs_ail *ailp, 217 struct xfs_ail *ailp,
218 struct xfs_ail_cursor *cur, 218 struct xfs_ail_cursor *cur,
219 xfs_lsn_t lsn) 219 xfs_lsn_t lsn)
220{ 220{
221 xfs_log_item_t *lip; 221 xfs_log_item_t *lip;
222 222
223 xfs_trans_ail_cursor_init(ailp, cur);
223 lip = xfs_ail_min(ailp); 224 lip = xfs_ail_min(ailp);
224 xfs_trans_ail_cursor_set(ailp, cur, lip);
225 if (lsn == 0) 225 if (lsn == 0)
226 return lip; 226 goto out;
227 227
228 list_for_each_entry(lip, &ailp->xa_ail, li_ail) { 228 list_for_each_entry(lip, &ailp->xa_ail, li_ail) {
229 if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0) { 229 if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0)
230 xfs_trans_ail_cursor_set(ailp, cur, lip); 230 break;
231 return lip;
232 }
233 } 231 }
234 232 lip = NULL;
235 return NULL; 233out:
234 xfs_trans_ail_cursor_set(ailp, cur, lip);
235 return lip;
236} 236}
237 237
238/* 238/*
@@ -254,7 +254,7 @@ xfsaild_push(
254 254
255 spin_lock(&mp->m_ail_lock); 255 spin_lock(&mp->m_ail_lock);
256 xfs_trans_ail_cursor_init(ailp, cur); 256 xfs_trans_ail_cursor_init(ailp, cur);
257 lip = xfs_trans_first_push_ail(ailp, cur, *last_lsn); 257 lip = xfs_trans_ail_cursor_first(ailp, cur, *last_lsn);
258 if (!lip || XFS_FORCED_SHUTDOWN(mp)) { 258 if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
259 /* 259 /*
260 * AIL is empty or our push has reached the end. 260 * AIL is empty or our push has reached the end.
@@ -552,39 +552,6 @@ xfs_trans_delete_ail(
552 552
553 553
554/* 554/*
555 * Return the item in the AIL with the smallest lsn.
556 * Return the current tree generation number for use
557 * in calls to xfs_trans_next_ail().
558 */
559xfs_log_item_t *
560xfs_trans_first_ail(
561 struct xfs_mount *mp,
562 struct xfs_ail_cursor *cur)
563{
564 xfs_log_item_t *lip;
565 struct xfs_ail *ailp = mp->m_ail;
566
567 lip = xfs_ail_min(ailp);
568 xfs_trans_ail_cursor_set(ailp, cur, lip);
569
570 return lip;
571}
572
573/*
574 * Grab the next item in the AIL from the cursor passed in.
575 */
576xfs_log_item_t *
577xfs_trans_next_ail(
578 struct xfs_mount *mp,
579 struct xfs_ail_cursor *cur)
580{
581 struct xfs_ail *ailp = mp->m_ail;
582
583 return xfs_trans_ail_cursor_next(ailp, cur);
584}
585
586
587/*
588 * The active item list (AIL) is a doubly linked list of log 555 * The active item list (AIL) is a doubly linked list of log
589 * items sorted by ascending lsn. The base of the list is 556 * items sorted by ascending lsn. The base of the list is
590 * a forw/back pointer pair embedded in the xfs mount structure. 557 * a forw/back pointer pair embedded in the xfs mount structure.