aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_ail.c
diff options
context:
space:
mode:
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.