diff options
author | Bob Peterson <rpeterso@redhat.com> | 2007-07-24 15:05:31 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:54:51 -0400 |
commit | 905d2aefa9e06ebb995df96920d273a516fcd3f9 (patch) | |
tree | 0c4ac325365a673d82bd5b00cbdc0cc22ac7d8e6 /fs/gfs2/lops.c | |
parent | 7b08fc620109c2f66575e9ae884f45c37933ea18 (diff) |
[GFS2] Move some code inside the log lock
This is the first of five patches for bug #248176:
There were still some critical variables being manipulated outside
the log_lock spinlock. That usually resulted in a hang.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r-- | fs/gfs2/lops.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 3b395c41b2f3..a0371f835cfb 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -117,7 +117,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
117 | struct buffer_head *bh; | 117 | struct buffer_head *bh; |
118 | struct gfs2_log_descriptor *ld; | 118 | struct gfs2_log_descriptor *ld; |
119 | struct gfs2_bufdata *bd1 = NULL, *bd2; | 119 | struct gfs2_bufdata *bd1 = NULL, *bd2; |
120 | unsigned int total = sdp->sd_log_num_buf; | 120 | unsigned int total; |
121 | unsigned int offset = BUF_OFFSET; | 121 | unsigned int offset = BUF_OFFSET; |
122 | unsigned int limit; | 122 | unsigned int limit; |
123 | unsigned int num; | 123 | unsigned int num; |
@@ -127,12 +127,16 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
127 | limit = buf_limit(sdp); | 127 | limit = buf_limit(sdp); |
128 | /* for 4k blocks, limit = 503 */ | 128 | /* for 4k blocks, limit = 503 */ |
129 | 129 | ||
130 | gfs2_log_lock(sdp); | ||
131 | total = sdp->sd_log_num_buf; | ||
130 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); | 132 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); |
131 | while(total) { | 133 | while(total) { |
132 | num = total; | 134 | num = total; |
133 | if (total > limit) | 135 | if (total > limit) |
134 | num = limit; | 136 | num = limit; |
137 | gfs2_log_unlock(sdp); | ||
135 | bh = gfs2_log_get_buf(sdp); | 138 | bh = gfs2_log_get_buf(sdp); |
139 | gfs2_log_lock(sdp); | ||
136 | ld = (struct gfs2_log_descriptor *)bh->b_data; | 140 | ld = (struct gfs2_log_descriptor *)bh->b_data; |
137 | ptr = (__be64 *)(bh->b_data + offset); | 141 | ptr = (__be64 *)(bh->b_data + offset); |
138 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 142 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
@@ -152,21 +156,27 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
152 | break; | 156 | break; |
153 | } | 157 | } |
154 | 158 | ||
159 | gfs2_log_unlock(sdp); | ||
155 | set_buffer_dirty(bh); | 160 | set_buffer_dirty(bh); |
156 | ll_rw_block(WRITE, 1, &bh); | 161 | ll_rw_block(WRITE, 1, &bh); |
162 | gfs2_log_lock(sdp); | ||
157 | 163 | ||
158 | n = 0; | 164 | n = 0; |
159 | list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf, | 165 | list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf, |
160 | bd_le.le_list) { | 166 | bd_le.le_list) { |
167 | gfs2_log_unlock(sdp); | ||
161 | bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); | 168 | bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); |
162 | set_buffer_dirty(bh); | 169 | set_buffer_dirty(bh); |
163 | ll_rw_block(WRITE, 1, &bh); | 170 | ll_rw_block(WRITE, 1, &bh); |
171 | gfs2_log_lock(sdp); | ||
164 | if (++n >= num) | 172 | if (++n >= num) |
165 | break; | 173 | break; |
166 | } | 174 | } |
167 | 175 | ||
176 | BUG_ON(total < num); | ||
168 | total -= num; | 177 | total -= num; |
169 | } | 178 | } |
179 | gfs2_log_unlock(sdp); | ||
170 | } | 180 | } |
171 | 181 | ||
172 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 182 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) |
@@ -524,7 +534,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
524 | struct gfs2_log_descriptor *ld; | 534 | struct gfs2_log_descriptor *ld; |
525 | unsigned int limit; | 535 | unsigned int limit; |
526 | unsigned int total_dbuf; | 536 | unsigned int total_dbuf; |
527 | unsigned int total_jdata = sdp->sd_log_num_jdata; | 537 | unsigned int total_jdata; |
528 | unsigned int num, n; | 538 | unsigned int num, n; |
529 | __be64 *ptr = NULL; | 539 | __be64 *ptr = NULL; |
530 | 540 | ||
@@ -536,6 +546,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
536 | */ | 546 | */ |
537 | gfs2_log_lock(sdp); | 547 | gfs2_log_lock(sdp); |
538 | total_dbuf = sdp->sd_log_num_databuf; | 548 | total_dbuf = sdp->sd_log_num_databuf; |
549 | total_jdata = sdp->sd_log_num_jdata; | ||
539 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, | 550 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, |
540 | bd_le.le_list); | 551 | bd_le.le_list); |
541 | while(total_dbuf) { | 552 | while(total_dbuf) { |
@@ -621,10 +632,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
621 | } | 632 | } |
622 | gfs2_log_unlock(sdp); | 633 | gfs2_log_unlock(sdp); |
623 | if (bh) { | 634 | if (bh) { |
624 | set_buffer_mapped(bh); | ||
625 | set_buffer_dirty(bh); | 635 | set_buffer_dirty(bh); |
626 | ll_rw_block(WRITE, 1, &bh); | 636 | ll_rw_block(WRITE, 1, &bh); |
627 | bh = NULL; | 637 | bh = NULL; |
638 | ptr = NULL; | ||
628 | } | 639 | } |
629 | n = 0; | 640 | n = 0; |
630 | gfs2_log_lock(sdp); | 641 | gfs2_log_lock(sdp); |