aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/lops.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2007-07-24 15:05:31 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:54:51 -0400
commit905d2aefa9e06ebb995df96920d273a516fcd3f9 (patch)
tree0c4ac325365a673d82bd5b00cbdc0cc22ac7d8e6 /fs/gfs2/lops.c
parent7b08fc620109c2f66575e9ae884f45c37933ea18 (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.c17
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
172static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) 182static 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);