aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-09-19 11:17:38 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-09-19 11:17:38 -0400
commit74669416f747363c14dba2ee6137540ae5a6834f (patch)
tree280aaacf7ec5e68b0d301b093a7a2358795e339c /fs/gfs2/log.c
parent7d308590ae60d1f038a54a94e78a385c5c163452 (diff)
[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/log.c')
-rw-r--r--fs/gfs2/log.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 08b80b263ade..6112d648b7ee 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)
62{ 62{
63 struct list_head *head = &sdp->sd_ail1_list; 63 struct list_head *head = &sdp->sd_ail1_list;
64 u64 sync_gen; 64 u64 sync_gen;
65 struct list_head *first, *tmp; 65 struct list_head *first;
66 struct gfs2_ail *first_ai, *ai; 66 struct gfs2_ail *first_ai, *ai, *tmp;
67 int done = 0;
67 68
68 gfs2_log_lock(sdp); 69 gfs2_log_lock(sdp);
69 if (list_empty(head)) { 70 if (list_empty(head)) {
@@ -75,27 +76,25 @@ void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags)
75 first = head->prev; 76 first = head->prev;
76 first_ai = list_entry(first, struct gfs2_ail, ai_list); 77 first_ai = list_entry(first, struct gfs2_ail, ai_list);
77 first_ai->ai_sync_gen = sync_gen; 78 first_ai->ai_sync_gen = sync_gen;
78 gfs2_ail1_start_one(sdp, first_ai); 79 gfs2_ail1_start_one(sdp, first_ai); /* This may drop log lock */
79 80
80 if (flags & DIO_ALL) 81 if (flags & DIO_ALL)
81 first = NULL; 82 first = NULL;
82 83
83 for (;;) { 84 while(!done) {
84 if (first && (head->prev != first || 85 if (first && (head->prev != first ||
85 gfs2_ail1_empty_one(sdp, first_ai, 0))) 86 gfs2_ail1_empty_one(sdp, first_ai, 0)))
86 break; 87 break;
87 88
88 for (tmp = head->prev; tmp != head; tmp = tmp->prev) { 89 done = 1;
89 ai = list_entry(tmp, struct gfs2_ail, ai_list); 90 list_for_each_entry_safe_reverse(ai, tmp, head, ai_list) {
90 if (ai->ai_sync_gen >= sync_gen) 91 if (ai->ai_sync_gen >= sync_gen)
91 continue; 92 continue;
92 ai->ai_sync_gen = sync_gen; 93 ai->ai_sync_gen = sync_gen;
93 gfs2_ail1_start_one(sdp, ai); 94 gfs2_ail1_start_one(sdp, ai); /* This may drop log lock */
95 done = 0;
94 break; 96 break;
95 } 97 }
96
97 if (tmp == head)
98 break;
99 } 98 }
100 99
101 gfs2_log_unlock(sdp); 100 gfs2_log_unlock(sdp);