aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-02-22 06:15:03 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-02-22 06:15:03 -0500
commit13538b8e46022b6a3721cda097fe3e0d91f16959 (patch)
tree7daf34dadd8bcdf5d98a09b17284a7755823c027 /fs
parentf55ab26a8f92a23988c3e6da28dae4741933a4e2 (diff)
[GFS2] Add list empty test to databuf_lo_add
Heinz had spotted that I'd forgotten to test in databuf_lo_add() that the data buffer in question hadn't already been added to the list. This was causing an infinite loop later on in the "before commit" routine. This means that GFS2 is now ready to be tested by everybody. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/lops.c33
1 files changed, 8 insertions, 25 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 5e7e7d91fc5e..ef39fb2e7234 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -291,7 +291,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
291 291
292 while (!list_empty(head)) { 292 while (!list_empty(head)) {
293 rv = list_entry(head->next, struct gfs2_revoke, rv_le.le_list); 293 rv = list_entry(head->next, struct gfs2_revoke, rv_le.le_list);
294 list_del(&rv->rv_le.le_list); 294 list_del_init(&rv->rv_le.le_list);
295 sdp->sd_log_num_revoke--; 295 sdp->sd_log_num_revoke--;
296 296
297 if (offset + sizeof(uint64_t) > sdp->sd_sb.sb_bsize) { 297 if (offset + sizeof(uint64_t) > sdp->sd_sb.sb_bsize) {
@@ -460,10 +460,12 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
460 gfs2_pin(sdp, bd->bd_bh); 460 gfs2_pin(sdp, bd->bd_bh);
461 } 461 }
462 gfs2_log_lock(sdp); 462 gfs2_log_lock(sdp);
463 if (ip->i_di.di_flags & GFS2_DIF_JDATA) 463 if (!list_empty(&le->le_list)) {
464 sdp->sd_log_num_jdata++; 464 if (ip->i_di.di_flags & GFS2_DIF_JDATA)
465 sdp->sd_log_num_databuf++; 465 sdp->sd_log_num_jdata++;
466 list_add(&le->le_list, &sdp->sd_log_le_databuf); 466 sdp->sd_log_num_databuf++;
467 list_add(&le->le_list, &sdp->sd_log_le_databuf);
468 }
467 gfs2_log_unlock(sdp); 469 gfs2_log_unlock(sdp);
468} 470}
469 471
@@ -503,25 +505,21 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
503 unsigned int total_jdata = sdp->sd_log_num_jdata; 505 unsigned int total_jdata = sdp->sd_log_num_jdata;
504 unsigned int num, n; 506 unsigned int num, n;
505 __be64 *ptr = NULL; 507 __be64 *ptr = NULL;
506 unsigned i;
507 508
508 offset += (2*sizeof(__be64) - 1); 509 offset += (2*sizeof(__be64) - 1);
509 offset &= ~(2*sizeof(__be64) - 1); 510 offset &= ~(2*sizeof(__be64) - 1);
510 limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); 511 limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64);
511 512
512 /* printk(KERN_INFO "totals: jdata=%u dbuf=%u\n", total_jdata, total_dbuf); */
513 /* 513 /*
514 * Start writing ordered buffers, write journaled buffers 514 * Start writing ordered buffers, write journaled buffers
515 * into the log along with a header 515 * into the log along with a header
516 */ 516 */
517 gfs2_log_lock(sdp); 517 gfs2_log_lock(sdp);
518 /* printk(KERN_INFO "locked in lops databuf_before_commit\n"); */
519 bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, bd_le.le_list); 518 bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, bd_le.le_list);
520 while(total_dbuf) { 519 while(total_dbuf) {
521 num = total_jdata; 520 num = total_jdata;
522 if (num > limit) 521 if (num > limit)
523 num = limit; 522 num = limit;
524 /* printk(KERN_INFO "total_dbuf=%u num=%u\n", total_dbuf, num); */
525 n = 0; 523 n = 0;
526 i = 0; 524 i = 0;
527 list_for_each_entry_safe_continue(bd1, bdt, &sdp->sd_log_le_databuf, bd_le.le_list) { 525 list_for_each_entry_safe_continue(bd1, bdt, &sdp->sd_log_le_databuf, bd_le.le_list) {
@@ -542,21 +540,12 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
542 gfs2_log_lock(sdp); 540 gfs2_log_lock(sdp);
543 } 541 }
544 brelse(bd1->bd_bh); 542 brelse(bd1->bd_bh);
545 /* printk(KERN_INFO "db write %p\n", bd1); */
546 if (++i > 100000) {
547 printk(KERN_INFO "looping bd1=%p bdt=%p eol=%p started=%p\n", bd1, bdt, &sdp->sd_log_le_databuf, &started);
548 dump_stack();
549 BUG();
550 }
551 continue; 543 continue;
552 } 544 }
553 /* printk(KERN_INFO "db skip\n"); */
554 continue; 545 continue;
555 } else if (bd1->bd_bh) { /* A journaled buffer */ 546 } else if (bd1->bd_bh) { /* A journaled buffer */
556 int magic; 547 int magic;
557 gfs2_log_unlock(sdp); 548 gfs2_log_unlock(sdp);
558 printk(KERN_INFO "journaled buffer %p\n", bd1->bd_bh);
559 printk(KERN_INFO "%lu %u %p %p\n", bd1->bd_bh->b_blocknr, bd1->bd_bh->b_size, bd1->bd_bh->b_data, bd1->bd_bh->b_page);
560 if (!bh) { 549 if (!bh) {
561 bh = gfs2_log_get_buf(sdp); 550 bh = gfs2_log_get_buf(sdp);
562 ld = (struct gfs2_log_descriptor *)bh->b_data; 551 ld = (struct gfs2_log_descriptor *)bh->b_data;
@@ -570,12 +559,9 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
570 ld->ld_data2 = cpu_to_be32(0); 559 ld->ld_data2 = cpu_to_be32(0);
571 memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); 560 memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved));
572 } 561 }
573 /* printk(KERN_INFO "check_magic\n"); */
574 magic = gfs2_check_magic(bd1->bd_bh); 562 magic = gfs2_check_magic(bd1->bd_bh);
575 /* printk(KERN_INFO "write data\n"); */
576 *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); 563 *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr);
577 *ptr++ = cpu_to_be64((__u64)magic); 564 *ptr++ = cpu_to_be64((__u64)magic);
578 /* printk(KERN_INFO "mark escaped or not\n"); */
579 clear_buffer_escaped(bd1->bd_bh); 565 clear_buffer_escaped(bd1->bd_bh);
580 if (unlikely(magic != 0)) 566 if (unlikely(magic != 0))
581 set_buffer_escaped(bd1->bd_bh); 567 set_buffer_escaped(bd1->bd_bh);
@@ -591,7 +577,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
591 bh = NULL; 577 bh = NULL;
592 } 578 }
593 n = 0; 579 n = 0;
594 /* printk(KERN_INFO "totals2: jdata=%u dbuf=%u\n", total_jdata, total_dbuf); */
595 gfs2_log_lock(sdp); 580 gfs2_log_lock(sdp);
596 list_for_each_entry_continue(bd2, &sdp->sd_log_le_databuf, bd_le.le_list) { 581 list_for_each_entry_continue(bd2, &sdp->sd_log_le_databuf, bd_le.le_list) {
597 if (!bd2->bd_bh) 582 if (!bd2->bd_bh)
@@ -621,14 +606,13 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
621 } 606 }
622 gfs2_log_unlock(sdp); 607 gfs2_log_unlock(sdp);
623 608
624 /* printk(KERN_INFO "wait on ordered data buffers\n"); */
625 /* Wait on all ordered buffers */ 609 /* Wait on all ordered buffers */
626 while (!list_empty(&started)) { 610 while (!list_empty(&started)) {
611 gfs2_log_lock(sdp);
627 bd1 = list_entry(started.next, struct gfs2_bufdata, bd_le.le_list); 612 bd1 = list_entry(started.next, struct gfs2_bufdata, bd_le.le_list);
628 list_del(&bd1->bd_le.le_list); 613 list_del(&bd1->bd_le.le_list);
629 sdp->sd_log_num_databuf--; 614 sdp->sd_log_num_databuf--;
630 615
631 gfs2_log_lock(sdp);
632 bh = bd1->bd_bh; 616 bh = bd1->bd_bh;
633 if (bh) { 617 if (bh) {
634 set_v2bd(bh, NULL); 618 set_v2bd(bh, NULL);
@@ -641,7 +625,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
641 kfree(bd1); 625 kfree(bd1);
642 } 626 }
643 627
644 /* printk(KERN_INFO "sd_log_num_databuf %u sd_log_num_jdata %u\n", sdp->sd_log_num_databuf, sdp->sd_log_num_jdata); */
645 /* We've removed all the ordered write bufs here, so only jdata left */ 628 /* We've removed all the ordered write bufs here, so only jdata left */
646 gfs2_assert_warn(sdp, sdp->sd_log_num_databuf == sdp->sd_log_num_jdata); 629 gfs2_assert_warn(sdp, sdp->sd_log_num_databuf == sdp->sd_log_num_jdata);
647} 630}