aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
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
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')
-rw-r--r--fs/xfs/xfs_log.c4
-rw-r--r--fs/xfs/xfs_log_recover.c15
-rw-r--r--fs/xfs/xfs_trans.h1
-rw-r--r--fs/xfs/xfs_trans_ail.c117
-rw-r--r--fs/xfs/xfs_trans_priv.h13
5 files changed, 58 insertions, 92 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 4184085d44af..31fbb2eea092 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -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, NULL) 912 && !xfs_trans_ail_tail(mp->m_ail)
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;
@@ -946,7 +946,7 @@ xlog_assign_tail_lsn(xfs_mount_t *mp)
946 xfs_lsn_t tail_lsn; 946 xfs_lsn_t tail_lsn;
947 xlog_t *log = mp->m_log; 947 xlog_t *log = mp->m_log;
948 948
949 tail_lsn = xfs_trans_tail_ail(mp); 949 tail_lsn = xfs_trans_ail_tail(mp->m_ail);
950 spin_lock(&log->l_grant_lock); 950 spin_lock(&log->l_grant_lock);
951 if (tail_lsn != 0) { 951 if (tail_lsn != 0) {
952 log->l_tail_lsn = tail_lsn; 952 log->l_tail_lsn = tail_lsn;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 37ba4899f3e6..45ea0d950138 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2728,8 +2728,7 @@ xlog_recover_do_efd_trans(
2728 */ 2728 */
2729 mp = log->l_mp; 2729 mp = log->l_mp;
2730 spin_lock(&mp->m_ail_lock); 2730 spin_lock(&mp->m_ail_lock);
2731 xfs_trans_ail_cursor_init(mp->m_ail, &cur); 2731 lip = xfs_trans_ail_cursor_first(mp->m_ail, &cur, 0);
2732 lip = xfs_trans_first_ail(mp, &cur);
2733 while (lip != NULL) { 2732 while (lip != NULL) {
2734 if (lip->li_type == XFS_LI_EFI) { 2733 if (lip->li_type == XFS_LI_EFI) {
2735 efip = (xfs_efi_log_item_t *)lip; 2734 efip = (xfs_efi_log_item_t *)lip;
@@ -2744,7 +2743,7 @@ xlog_recover_do_efd_trans(
2744 break; 2743 break;
2745 } 2744 }
2746 } 2745 }
2747 lip = xfs_trans_next_ail(mp, &cur); 2746 lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
2748 } 2747 }
2749 xfs_trans_ail_cursor_done(mp->m_ail, &cur); 2748 xfs_trans_ail_cursor_done(mp->m_ail, &cur);
2750 spin_unlock(&mp->m_ail_lock); 2749 spin_unlock(&mp->m_ail_lock);
@@ -3061,8 +3060,7 @@ xlog_recover_process_efis(
3061 mp = log->l_mp; 3060 mp = log->l_mp;
3062 spin_lock(&mp->m_ail_lock); 3061 spin_lock(&mp->m_ail_lock);
3063 3062
3064 xfs_trans_ail_cursor_init(mp->m_ail, &cur); 3063 lip = xfs_trans_ail_cursor_first(mp->m_ail, &cur, 0);
3065 lip = xfs_trans_first_ail(mp, &cur);
3066 while (lip != NULL) { 3064 while (lip != NULL) {
3067 /* 3065 /*
3068 * We're done when we see something other than an EFI. 3066 * We're done when we see something other than an EFI.
@@ -3070,7 +3068,8 @@ xlog_recover_process_efis(
3070 */ 3068 */
3071 if (lip->li_type != XFS_LI_EFI) { 3069 if (lip->li_type != XFS_LI_EFI) {
3072#ifdef DEBUG 3070#ifdef DEBUG
3073 for (; lip; lip = xfs_trans_next_ail(mp, &cur)) 3071 for (; lip;
3072 lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur))
3074 ASSERT(lip->li_type != XFS_LI_EFI); 3073 ASSERT(lip->li_type != XFS_LI_EFI);
3075#endif 3074#endif
3076 break; 3075 break;
@@ -3081,7 +3080,7 @@ xlog_recover_process_efis(
3081 */ 3080 */
3082 efip = (xfs_efi_log_item_t *)lip; 3081 efip = (xfs_efi_log_item_t *)lip;
3083 if (efip->efi_flags & XFS_EFI_RECOVERED) { 3082 if (efip->efi_flags & XFS_EFI_RECOVERED) {
3084 lip = xfs_trans_next_ail(mp, &cur); 3083 lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
3085 continue; 3084 continue;
3086 } 3085 }
3087 3086
@@ -3090,7 +3089,7 @@ xlog_recover_process_efis(
3090 spin_lock(&mp->m_ail_lock); 3089 spin_lock(&mp->m_ail_lock);
3091 if (error) 3090 if (error)
3092 goto out; 3091 goto out;
3093 lip = xfs_trans_next_ail(mp, &cur); 3092 lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
3094 } 3093 }
3095out: 3094out:
3096 xfs_trans_ail_cursor_done(mp->m_ail, &cur); 3095 xfs_trans_ail_cursor_done(mp->m_ail, &cur);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 1d89d50a5b99..ae2ae3e020d6 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -971,7 +971,6 @@ void xfs_trans_cancel(xfs_trans_t *, int);
971int xfs_trans_ail_init(struct xfs_mount *); 971int xfs_trans_ail_init(struct xfs_mount *);
972void xfs_trans_ail_destroy(struct xfs_mount *); 972void xfs_trans_ail_destroy(struct xfs_mount *);
973void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t); 973void xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
974xfs_lsn_t xfs_trans_tail_ail(struct xfs_mount *);
975void xfs_trans_unlocked_item(struct xfs_mount *, 974void xfs_trans_unlocked_item(struct xfs_mount *,
976 xfs_log_item_t *); 975 xfs_log_item_t *);
977xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, 976xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
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.
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index f114d388570a..aa5853502529 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -90,14 +90,15 @@ void xfs_trans_update_ail(struct xfs_mount *mp,
90void xfs_trans_delete_ail(struct xfs_mount *mp, 90void xfs_trans_delete_ail(struct xfs_mount *mp,
91 struct xfs_log_item *lip) 91 struct xfs_log_item *lip)
92 __releases(mp->m_ail_lock); 92 __releases(mp->m_ail_lock);
93struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *mp,
94 struct xfs_ail_cursor *cur);
95struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *mp,
96 struct xfs_ail_cursor *cur);
97 93
98void xfs_trans_ail_cursor_init(struct xfs_ail *ailp, 94xfs_lsn_t xfs_trans_ail_tail(struct xfs_ail *ailp);
95
96struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
97 struct xfs_ail_cursor *cur,
98 xfs_lsn_t lsn);
99struct xfs_log_item *xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
99 struct xfs_ail_cursor *cur); 100 struct xfs_ail_cursor *cur);
100void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, 101void xfs_trans_ail_cursor_done(struct xfs_ail *ailp,
101 struct xfs_ail_cursor *cur); 102 struct xfs_ail_cursor *cur);
102 103
103long xfsaild_push(struct xfs_ail *, xfs_lsn_t *); 104long xfsaild_push(struct xfs_ail *, xfs_lsn_t *);