diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-19 11:17:38 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-19 11:17:38 -0400 |
commit | 74669416f747363c14dba2ee6137540ae5a6834f (patch) | |
tree | 280aaacf7ec5e68b0d301b093a7a2358795e339c /fs/gfs2 | |
parent | 7d308590ae60d1f038a54a94e78a385c5c163452 (diff) | |
download | op-kernel-dev-74669416f747363c14dba2ee6137540ae5a6834f.zip op-kernel-dev-74669416f747363c14dba2ee6137540ae5a6834f.tar.gz |
[GFS2] Use list_for_each_entry_safe_reverse in gfs2_ail1_start()
This is an attempt to fix Red Hat bz 204364. I don't hit it all
the time, but with these changes, running postmark which used to
trigger it on a regular basis no longer appears to. So I'm not
saying that its 100% certain that its fixed, but it does look
promising at the moment.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/log.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 08b80b2..6112d64 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -62,8 +62,9 @@ void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) { struct list_head *head = &sdp->sd_ail1_list; u64 sync_gen; - struct list_head *first, *tmp; - struct gfs2_ail *first_ai, *ai; + struct list_head *first; + struct gfs2_ail *first_ai, *ai, *tmp; + int done = 0; gfs2_log_lock(sdp); if (list_empty(head)) { @@ -75,27 +76,25 @@ void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) first = head->prev; first_ai = list_entry(first, struct gfs2_ail, ai_list); first_ai->ai_sync_gen = sync_gen; - gfs2_ail1_start_one(sdp, first_ai); + gfs2_ail1_start_one(sdp, first_ai); /* This may drop log lock */ if (flags & DIO_ALL) first = NULL; - for (;;) { + while(!done) { if (first && (head->prev != first || gfs2_ail1_empty_one(sdp, first_ai, 0))) break; - for (tmp = head->prev; tmp != head; tmp = tmp->prev) { - ai = list_entry(tmp, struct gfs2_ail, ai_list); + done = 1; + list_for_each_entry_safe_reverse(ai, tmp, head, ai_list) { if (ai->ai_sync_gen >= sync_gen) continue; ai->ai_sync_gen = sync_gen; - gfs2_ail1_start_one(sdp, ai); + gfs2_ail1_start_one(sdp, ai); /* This may drop log lock */ + done = 0; break; } - - if (tmp == head) - break; } gfs2_log_unlock(sdp); |