diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-22 06:15:03 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-22 06:15:03 -0500 |
commit | 13538b8e46022b6a3721cda097fe3e0d91f16959 (patch) | |
tree | 7daf34dadd8bcdf5d98a09b17284a7755823c027 /fs/gfs2 | |
parent | f55ab26a8f92a23988c3e6da28dae4741933a4e2 (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/gfs2')
-rw-r--r-- | fs/gfs2/lops.c | 33 |
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 | } |