浏览代码

[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>
David Chinner 16 年之前
父节点
当前提交
5b00f14fbd
共有 5 个文件被更改,包括 58 次插入92 次删除
  1. 2 2
      fs/xfs/xfs_log.c
  2. 7 8
      fs/xfs/xfs_log_recover.c
  3. 0 1
      fs/xfs/xfs_trans.h
  4. 42 75
      fs/xfs/xfs_trans_ail.c
  5. 7 6
      fs/xfs/xfs_trans_priv.h

+ 2 - 2
fs/xfs/xfs_log.c

@@ -909,7 +909,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
 	spin_lock(&log->l_icloglock);
 	spin_lock(&log->l_icloglock);
 	if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
 	if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
 		(log->l_covered_state == XLOG_STATE_COVER_NEED2))
 		(log->l_covered_state == XLOG_STATE_COVER_NEED2))
-			&& !xfs_trans_first_ail(mp, NULL)
+			&& !xfs_trans_ail_tail(mp->m_ail)
 			&& xlog_iclogs_empty(log)) {
 			&& xlog_iclogs_empty(log)) {
 		if (log->l_covered_state == XLOG_STATE_COVER_NEED)
 		if (log->l_covered_state == XLOG_STATE_COVER_NEED)
 			log->l_covered_state = XLOG_STATE_COVER_DONE;
 			log->l_covered_state = XLOG_STATE_COVER_DONE;
@@ -946,7 +946,7 @@ xlog_assign_tail_lsn(xfs_mount_t *mp)
 	xfs_lsn_t tail_lsn;
 	xfs_lsn_t tail_lsn;
 	xlog_t	  *log = mp->m_log;
 	xlog_t	  *log = mp->m_log;
 
 
-	tail_lsn = xfs_trans_tail_ail(mp);
+	tail_lsn = xfs_trans_ail_tail(mp->m_ail);
 	spin_lock(&log->l_grant_lock);
 	spin_lock(&log->l_grant_lock);
 	if (tail_lsn != 0) {
 	if (tail_lsn != 0) {
 		log->l_tail_lsn = tail_lsn;
 		log->l_tail_lsn = tail_lsn;

+ 7 - 8
fs/xfs/xfs_log_recover.c

@@ -2728,8 +2728,7 @@ xlog_recover_do_efd_trans(
 	 */
 	 */
 	mp = log->l_mp;
 	mp = log->l_mp;
 	spin_lock(&mp->m_ail_lock);
 	spin_lock(&mp->m_ail_lock);
-	xfs_trans_ail_cursor_init(mp->m_ail, &cur);
-	lip = xfs_trans_first_ail(mp, &cur);
+	lip = xfs_trans_ail_cursor_first(mp->m_ail, &cur, 0);
 	while (lip != NULL) {
 	while (lip != NULL) {
 		if (lip->li_type == XFS_LI_EFI) {
 		if (lip->li_type == XFS_LI_EFI) {
 			efip = (xfs_efi_log_item_t *)lip;
 			efip = (xfs_efi_log_item_t *)lip;
@@ -2744,7 +2743,7 @@ xlog_recover_do_efd_trans(
 				break;
 				break;
 			}
 			}
 		}
 		}
-		lip = xfs_trans_next_ail(mp, &cur);
+		lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
 	}
 	}
 	xfs_trans_ail_cursor_done(mp->m_ail, &cur);
 	xfs_trans_ail_cursor_done(mp->m_ail, &cur);
 	spin_unlock(&mp->m_ail_lock);
 	spin_unlock(&mp->m_ail_lock);
@@ -3061,8 +3060,7 @@ xlog_recover_process_efis(
 	mp = log->l_mp;
 	mp = log->l_mp;
 	spin_lock(&mp->m_ail_lock);
 	spin_lock(&mp->m_ail_lock);
 
 
-	xfs_trans_ail_cursor_init(mp->m_ail, &cur);
-	lip = xfs_trans_first_ail(mp, &cur);
+	lip = xfs_trans_ail_cursor_first(mp->m_ail, &cur, 0);
 	while (lip != NULL) {
 	while (lip != NULL) {
 		/*
 		/*
 		 * We're done when we see something other than an EFI.
 		 * We're done when we see something other than an EFI.
@@ -3070,7 +3068,8 @@ xlog_recover_process_efis(
 		 */
 		 */
 		if (lip->li_type != XFS_LI_EFI) {
 		if (lip->li_type != XFS_LI_EFI) {
 #ifdef DEBUG
 #ifdef DEBUG
-			for (; lip; lip = xfs_trans_next_ail(mp, &cur))
+			for (; lip;
+			       lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur))
 				ASSERT(lip->li_type != XFS_LI_EFI);
 				ASSERT(lip->li_type != XFS_LI_EFI);
 #endif
 #endif
 			break;
 			break;
@@ -3081,7 +3080,7 @@ xlog_recover_process_efis(
 		 */
 		 */
 		efip = (xfs_efi_log_item_t *)lip;
 		efip = (xfs_efi_log_item_t *)lip;
 		if (efip->efi_flags & XFS_EFI_RECOVERED) {
 		if (efip->efi_flags & XFS_EFI_RECOVERED) {
-			lip = xfs_trans_next_ail(mp, &cur);
+			lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -3090,7 +3089,7 @@ xlog_recover_process_efis(
 		spin_lock(&mp->m_ail_lock);
 		spin_lock(&mp->m_ail_lock);
 		if (error)
 		if (error)
 			goto out;
 			goto out;
-		lip = xfs_trans_next_ail(mp, &cur);
+		lip = xfs_trans_ail_cursor_next(mp->m_ail, &cur);
 	}
 	}
 out:
 out:
 	xfs_trans_ail_cursor_done(mp->m_ail, &cur);
 	xfs_trans_ail_cursor_done(mp->m_ail, &cur);

+ 0 - 1
fs/xfs/xfs_trans.h

@@ -971,7 +971,6 @@ void		xfs_trans_cancel(xfs_trans_t *, int);
 int		xfs_trans_ail_init(struct xfs_mount *);
 int		xfs_trans_ail_init(struct xfs_mount *);
 void		xfs_trans_ail_destroy(struct xfs_mount *);
 void		xfs_trans_ail_destroy(struct xfs_mount *);
 void		xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
 void		xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
-xfs_lsn_t	xfs_trans_tail_ail(struct xfs_mount *);
 void		xfs_trans_unlocked_item(struct xfs_mount *,
 void		xfs_trans_unlocked_item(struct xfs_mount *,
 					xfs_log_item_t *);
 					xfs_log_item_t *);
 xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
 xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,

+ 42 - 75
fs/xfs/xfs_trans_ail.c

@@ -50,20 +50,20 @@ STATIC void xfs_ail_check(struct xfs_ail *, xfs_log_item_t *);
  * lsn of the last item in the AIL.
  * lsn of the last item in the AIL.
  */
  */
 xfs_lsn_t
 xfs_lsn_t
-xfs_trans_tail_ail(
-	xfs_mount_t	*mp)
+xfs_trans_ail_tail(
+	struct xfs_ail	*ailp)
 {
 {
 	xfs_lsn_t	lsn;
 	xfs_lsn_t	lsn;
 	xfs_log_item_t	*lip;
 	xfs_log_item_t	*lip;
 
 
-	spin_lock(&mp->m_ail_lock);
-	lip = xfs_ail_min(mp->m_ail);
+	spin_lock(&ailp->xa_mount->m_ail_lock);
+	lip = xfs_ail_min(ailp);
 	if (lip == NULL) {
 	if (lip == NULL) {
 		lsn = (xfs_lsn_t)0;
 		lsn = (xfs_lsn_t)0;
 	} else {
 	} else {
 		lsn = lip->li_lsn;
 		lsn = lip->li_lsn;
 	}
 	}
-	spin_unlock(&mp->m_ail_lock);
+	spin_unlock(&ailp->xa_mount->m_ail_lock);
 
 
 	return lsn;
 	return lsn;
 }
 }
@@ -111,7 +111,7 @@ xfs_trans_push_ail(
  * We don't link the push cursor because it is embedded in the struct
  * We don't link the push cursor because it is embedded in the struct
  * xfs_ail and hence easily findable.
  * xfs_ail and hence easily findable.
  */
  */
-void
+STATIC void
 xfs_trans_ail_cursor_init(
 xfs_trans_ail_cursor_init(
 	struct xfs_ail		*ailp,
 	struct xfs_ail		*ailp,
 	struct xfs_ail_cursor	*cur)
 	struct xfs_ail_cursor	*cur)
@@ -143,7 +143,7 @@ xfs_trans_ail_cursor_set(
  * If the cursor was invalidated (inidicated by a lip of 1),
  * If the cursor was invalidated (inidicated by a lip of 1),
  * restart the traversal.
  * restart the traversal.
  */
  */
-STATIC struct xfs_log_item *
+struct xfs_log_item *
 xfs_trans_ail_cursor_next(
 xfs_trans_ail_cursor_next(
 	struct xfs_ail		*ailp,
 	struct xfs_ail		*ailp,
 	struct xfs_ail_cursor	*cur)
 	struct xfs_ail_cursor	*cur)
@@ -156,30 +156,6 @@ xfs_trans_ail_cursor_next(
 	return lip;
 	return lip;
 }
 }
 
 
-/*
- * Invalidate any cursor that is pointing to this item. This is
- * called when an item is removed from the AIL. Any cursor pointing
- * to this object is now invalid and the traversal needs to be
- * terminated so it doesn't reference a freed object. We set the
- * cursor item to a value of 1 so we can distinguish between an
- * invalidation and the end of the list when getting the next item
- * from the cursor.
- */
-STATIC void
-xfs_trans_ail_cursor_clear(
-	struct xfs_ail		*ailp,
-	struct xfs_log_item	*lip)
-{
-	struct xfs_ail_cursor	*cur;
-
-	/* need to search all cursors */
-	for (cur = &ailp->xa_cursors; cur; cur = cur->next) {
-		if (cur->item == lip)
-			cur->item = (struct xfs_log_item *)
-					((__psint_t)cur->item | 1);
-	}
-}
-
 /*
 /*
  * Now that the traversal is complete, we need to remove the cursor
  * Now that the traversal is complete, we need to remove the cursor
  * from the list of traversing cursors. Avoid removing the embedded
  * from the list of traversing cursors. Avoid removing the embedded
@@ -207,32 +183,56 @@ xfs_trans_ail_cursor_done(
 	ASSERT(cur);
 	ASSERT(cur);
 }
 }
 
 
+/*
+ * Invalidate any cursor that is pointing to this item. This is
+ * called when an item is removed from the AIL. Any cursor pointing
+ * to this object is now invalid and the traversal needs to be
+ * terminated so it doesn't reference a freed object. We set the
+ * cursor item to a value of 1 so we can distinguish between an
+ * invalidation and the end of the list when getting the next item
+ * from the cursor.
+ */
+STATIC void
+xfs_trans_ail_cursor_clear(
+	struct xfs_ail		*ailp,
+	struct xfs_log_item	*lip)
+{
+	struct xfs_ail_cursor	*cur;
+
+	/* need to search all cursors */
+	for (cur = &ailp->xa_cursors; cur; cur = cur->next) {
+		if (cur->item == lip)
+			cur->item = (struct xfs_log_item *)
+					((__psint_t)cur->item | 1);
+	}
+}
+
 /*
 /*
  * Return the item in the AIL with the current lsn.
  * Return the item in the AIL with the current lsn.
  * Return the current tree generation number for use
  * Return the current tree generation number for use
  * in calls to xfs_trans_next_ail().
  * in calls to xfs_trans_next_ail().
  */
  */
-STATIC xfs_log_item_t *
-xfs_trans_first_push_ail(
+xfs_log_item_t *
+xfs_trans_ail_cursor_first(
 	struct xfs_ail		*ailp,
 	struct xfs_ail		*ailp,
 	struct xfs_ail_cursor	*cur,
 	struct xfs_ail_cursor	*cur,
 	xfs_lsn_t		lsn)
 	xfs_lsn_t		lsn)
 {
 {
 	xfs_log_item_t		*lip;
 	xfs_log_item_t		*lip;
 
 
+	xfs_trans_ail_cursor_init(ailp, cur);
 	lip = xfs_ail_min(ailp);
 	lip = xfs_ail_min(ailp);
-	xfs_trans_ail_cursor_set(ailp, cur, lip);
 	if (lsn == 0)
 	if (lsn == 0)
-		return lip;
+		goto out;
 
 
 	list_for_each_entry(lip, &ailp->xa_ail, li_ail) {
 	list_for_each_entry(lip, &ailp->xa_ail, li_ail) {
-		if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0) {
-			xfs_trans_ail_cursor_set(ailp, cur, lip);
-			return lip;
-		}
+		if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0)
+			break;
 	}
 	}
-
-	return NULL;
+	lip = NULL;
+out:
+	xfs_trans_ail_cursor_set(ailp, cur, lip);
+	return lip;
 }
 }
 
 
 /*
 /*
@@ -254,7 +254,7 @@ xfsaild_push(
 
 
 	spin_lock(&mp->m_ail_lock);
 	spin_lock(&mp->m_ail_lock);
 	xfs_trans_ail_cursor_init(ailp, cur);
 	xfs_trans_ail_cursor_init(ailp, cur);
-	lip = xfs_trans_first_push_ail(ailp, cur, *last_lsn);
+	lip = xfs_trans_ail_cursor_first(ailp, cur, *last_lsn);
 	if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
 	if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
 		/*
 		/*
 		 * AIL is empty or our push has reached the end.
 		 * AIL is empty or our push has reached the end.
@@ -551,39 +551,6 @@ xfs_trans_delete_ail(
 
 
 
 
 
 
-/*
- * Return the item in the AIL with the smallest lsn.
- * Return the current tree generation number for use
- * in calls to xfs_trans_next_ail().
- */
-xfs_log_item_t *
-xfs_trans_first_ail(
-	struct xfs_mount	*mp,
-	struct xfs_ail_cursor	*cur)
-{
-	xfs_log_item_t		*lip;
-	struct xfs_ail		*ailp = mp->m_ail;
-
-	lip = xfs_ail_min(ailp);
-	xfs_trans_ail_cursor_set(ailp, cur, lip);
-
-	return lip;
-}
-
-/*
- * Grab the next item in the AIL from the cursor passed in.
- */
-xfs_log_item_t *
-xfs_trans_next_ail(
-	struct xfs_mount	*mp,
-	struct xfs_ail_cursor	*cur)
-{
-	struct xfs_ail		*ailp = mp->m_ail;
-
-	return xfs_trans_ail_cursor_next(ailp, cur);
-}
-
-
 /*
 /*
  * The active item list (AIL) is a doubly linked list of log
  * The active item list (AIL) is a doubly linked list of log
  * items sorted by ascending lsn.  The base of the list is
  * items sorted by ascending lsn.  The base of the list is

+ 7 - 6
fs/xfs/xfs_trans_priv.h

@@ -90,14 +90,15 @@ void			xfs_trans_update_ail(struct xfs_mount *mp,
 void			xfs_trans_delete_ail(struct xfs_mount *mp,
 void			xfs_trans_delete_ail(struct xfs_mount *mp,
 				     struct xfs_log_item *lip)
 				     struct xfs_log_item *lip)
 				     __releases(mp->m_ail_lock);
 				     __releases(mp->m_ail_lock);
-struct xfs_log_item	*xfs_trans_first_ail(struct xfs_mount *mp,
-					struct xfs_ail_cursor *cur);
-struct xfs_log_item	*xfs_trans_next_ail(struct xfs_mount *mp,
-					struct xfs_ail_cursor *cur);
 
 
-void xfs_trans_ail_cursor_init(struct xfs_ail *ailp,
+xfs_lsn_t		xfs_trans_ail_tail(struct xfs_ail *ailp);
+
+struct xfs_log_item	*xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
+					struct xfs_ail_cursor *cur,
+					xfs_lsn_t lsn);
+struct xfs_log_item	*xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
 					struct xfs_ail_cursor *cur);
 					struct xfs_ail_cursor *cur);
-void xfs_trans_ail_cursor_done(struct xfs_ail *ailp,
+void			xfs_trans_ail_cursor_done(struct xfs_ail *ailp,
 					struct xfs_ail_cursor *cur);
 					struct xfs_ail_cursor *cur);
 
 
 long	xfsaild_push(struct xfs_ail *, xfs_lsn_t *);
 long	xfsaild_push(struct xfs_ail *, xfs_lsn_t *);