On Mon, 2011-07-04 at 15:27 +1000, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > The list of active AIL cursors uses a roll-your-own linked list with > special casing for the AIL push cursor. Simplify this code by > replacing the list with standard struct list_head lists, and use a > separate list_head to track the active cursors so that the code can > just treat the AIL push cursor (which is still embedded into the > struct xfs_ail) as a generic cursor. > > Further, fix the duplicate push cursor initialisation that the > special case handling was hiding, and clean up all the comments > around the active cursor list handling. > > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> I suggest a few comment changes below. I also have a question about why the push cursor isn't treated like any other cursors. I added a few bits of commentary as well--you addressed a few things I had been thinking about earlier. I guess I'm interested in your response before signing off. -Alex > --- > fs/xfs/xfs_trans_ail.c | 68 +++++++++++++++------------------------------- > fs/xfs/xfs_trans_priv.h | 5 ++- > 2 files changed, 25 insertions(+), 48 deletions(-) > > diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c > index de7a52a..3b5b5e4 100644 > --- a/fs/xfs/xfs_trans_ail.c > +++ b/fs/xfs/xfs_trans_ail.c > @@ -165,15 +165,11 @@ xfs_ail_max_lsn( > /* > * AIL traversal cursor initialisation. > * > - * The cursor keeps track of where our current traversal is up > - * to by tracking the next ƣtem in the list for us. However, for > - * this to be safe, removing an object from the AIL needs to invalidate > - * any cursor that points to it. hence the traversal cursor needs to > - * be linked to the struct xfs_ail so that deletion can search all the > - * active cursors for invalidation. > - * > - * We don't link the push cursor because it is embedded in the struct > - * xfs_ail and hence easily findable. > + * The cursor keeps track of where our current traversal is up to by tracking > + * the next ƣtem in the list for us. However, for this to be safe, removing an ^ What's up with the weird non-ASCII characters in your code? > + * object from the AIL needs to invalidate any cursor that points to it. hence > + * the traversal cursor needs to be linked to the struct xfs_ail so that > + * deletion can search all the active cursors for invalidation. > */ > STATIC void > xfs_trans_ail_cursor_init( > @@ -181,17 +177,13 @@ xfs_trans_ail_cursor_init( > struct xfs_ail_cursor *cur) > { > cur->item = NULL; > - if (cur == &ailp->xa_cursors) > - return; > - > - cur->next = ailp->xa_cursors.next; > - ailp->xa_cursors.next = cur; > + INIT_LIST_HEAD(&cur->list); > + list_add_tail(&cur->list, &ailp->xa_cursors); This is good. I was thinking as I looked at this earlier that it would be nicer if newer cursors were added to the end of the list. > } > > /* > - * Get the next item in the traversal and advance the cursor. > - * If the cursor was invalidated (inidicated by a lip of 1), > - * restart the traversal. > + * Get the next item in the traversal and advance the cursor. If the cursor > + * was invalidated (inidicated by a lip of 1), restart the traversal. indicated Actually, it's indicated by a low-order bit of 1. Why is it that you decided to just set the bit rather than overwrite the item pointer? Just for the benefit of debugging? (That is a good reason...) If not, I suggest defining an XFS_ITEM_INVALID constant pointer rather than just using 1. > */ > struct xfs_log_item * > xfs_trans_ail_cursor_next( > @@ -208,39 +200,24 @@ xfs_trans_ail_cursor_next( > } > > /* > - * Now that the traversal is complete, we need to remove the cursor > - * from the list of traversing cursors. Avoid removing the embedded > - * push cursor, but use the fact it is always present to make the > - * list deletion simple. > + * When the traversal is complete, we need to remove the cursor from the list > + * of traversing cursors. > */ > void > xfs_trans_ail_cursor_done( > struct xfs_ail *ailp, > - struct xfs_ail_cursor *done) > + struct xfs_ail_cursor *cur) > { > - struct xfs_ail_cursor *prev = NULL; > - struct xfs_ail_cursor *cur; > - > - done->item = NULL; This eliminates the curious situation where the end of the list was marked by a null *item* pointer rather than something having to do with the next pointer. > - if (done == &ailp->xa_cursors) > - return; > - prev = &ailp->xa_cursors; > - for (cur = prev->next; cur; prev = cur, cur = prev->next) { > - if (cur == done) { > - prev->next = cur->next; > - break; . . . > - * invalidation and the end of the list when getting the next item > + * 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 Fix this comment to reflect the use of the low bit rather than just 1. > + * between an invalidation and the end of the list when getting the next item > * from the cursor. > */ > STATIC void . . . > nt_t)cur->item | 1); > @@ -416,7 +392,7 @@ xfs_ail_worker( > struct xfs_ail *ailp = container_of(to_delayed_work(work), > struct xfs_ail, xa_work); > xfs_mount_t *mp = ailp->xa_mount; > - struct xfs_ail_cursor *cur = &ailp->xa_cursors; > + struct xfs_ail_cursor *cur = &ailp->xa_push_cursor; Is the push cursor defined in the ail structure just so it's easier to find? > xfs_log_item_t *lip; > xfs_lsn_t lsn; > xfs_lsn_t target; > @@ -428,7 +404,6 @@ xfs_ail_worker( > > spin_lock(&ailp->xa_lock); > target = ailp->xa_target; > - xfs_trans_ail_cursor_init(ailp, cur); I don't see why the push cursor should be treated any differently from any others. If something gets invalidated the push cursor needs to be notified also, doesn't it? I must be missing something here... > lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn); > if (!lip || XFS_FORCED_SHUTDOWN(mp)) { > /* . . . _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs