aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 *);