Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 262860
b: refs/heads/master
c: e44f411
h: refs/heads/master
v: v3
  • Loading branch information
Alex Elder committed Aug 9, 2011
1 parent 35088d2 commit 8e8eedf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2ddb4e94065470828e131351566102274ea9e83f
refs/heads/master: e44f4112a46ca817fe2758aac7bf7893a64a8c0e
67 changes: 29 additions & 38 deletions trunk/fs/xfs/xfs_trans_ail.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ xfs_trans_ail_cursor_last(
* Splice the log item list into the AIL at the given LSN. We splice to the
* tail of the given LSN to maintain insert order for push traversals. The
* cursor is optional, allowing repeated updates to the same LSN to avoid
* repeated traversals.
* repeated traversals. This should not be called with an empty list.
*/
static void
xfs_ail_splice(
Expand All @@ -308,50 +308,39 @@ xfs_ail_splice(
struct list_head *list,
xfs_lsn_t lsn)
{
struct xfs_log_item *lip = cur ? cur->item : NULL;
struct xfs_log_item *next_lip;
struct xfs_log_item *lip;

ASSERT(!list_empty(list));

/*
* Get a new cursor if we don't have a placeholder or the existing one
* has been invalidated.
* Use the cursor to determine the insertion point if one is
* provided. If not, or if the one we got is not valid,
* find the place in the AIL where the items belong.
*/
if (!lip || (__psint_t)lip & 1) {
lip = cur ? cur->item : NULL;
if (!lip || (__psint_t) lip & 1)
lip = __xfs_trans_ail_cursor_last(ailp, lsn);

if (!lip) {
/* The list is empty, so just splice and return. */
if (cur)
cur->item = NULL;
list_splice(list, &ailp->xa_ail);
return;
}
}
/*
* If a cursor is provided, we know we're processing the AIL
* in lsn order, and future items to be spliced in will
* follow the last one being inserted now. Update the
* cursor to point to that last item, now while we have a
* reliable pointer to it.
*/
if (cur)
cur->item = list_entry(list->prev, struct xfs_log_item, li_ail);

/*
* Our cursor points to the item we want to insert _after_, so we have
* to update the cursor to point to the end of the list we are splicing
* in so that it points to the correct location for the next splice.
* i.e. before the splice
*
* lsn -> lsn -> lsn + x -> lsn + x ...
* ^
* | cursor points here
*
* After the splice we have:
*
* lsn -> lsn -> lsn -> lsn -> .... -> lsn -> lsn + x -> lsn + x ...
* ^ ^
* | cursor points here | needs to move here
*
* So we set the cursor to the last item in the list to be spliced
* before we execute the splice, resulting in the cursor pointing to
* the correct item after the splice occurs.
* Finally perform the splice. Unless the AIL was empty,
* lip points to the item in the AIL _after_ which the new
* items should go. If lip is null the AIL was empty, so
* the new items go at the head of the AIL.
*/
if (cur) {
next_lip = list_entry(list->prev, struct xfs_log_item, li_ail);
cur->item = next_lip;
}
list_splice(list, &lip->li_ail);
if (lip)
list_splice(list, &lip->li_ail);
else
list_splice(list, &ailp->xa_ail);
}

/*
Expand Down Expand Up @@ -682,6 +671,7 @@ xfs_trans_ail_update_bulk(
int i;
LIST_HEAD(tmp);

ASSERT(nr_items > 0); /* Not required, but true. */
mlip = xfs_ail_min(ailp);

for (i = 0; i < nr_items; i++) {
Expand All @@ -701,7 +691,8 @@ xfs_trans_ail_update_bulk(
list_add(&lip->li_ail, &tmp);
}

xfs_ail_splice(ailp, cur, &tmp, lsn);
if (!list_empty(&tmp))
xfs_ail_splice(ailp, cur, &tmp, lsn);

if (!mlip_changed) {
spin_unlock(&ailp->xa_lock);
Expand Down

0 comments on commit 8e8eedf

Please sign in to comment.