diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-21 07:51:39 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-21 07:51:39 -0500 |
commit | f55ab26a8f92a23988c3e6da28dae4741933a4e2 (patch) | |
tree | b6f9e89ce1b2ccde8d81314aeea06f6a02f882f7 /fs/gfs2/lops.c | |
parent | 5c4e9e036678fae65c9288e1c00a6f33cd447283 (diff) |
[GFS2] Use mutices rather than semaphores
As well as a number of minor bug fixes, this patch changes GFS
to use mutices rather than semaphores. This results in better
information in case there are any locking problems.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r-- | fs/gfs2/lops.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 23be00141901..5e7e7d91fc5e 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -502,7 +502,8 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
502 | unsigned int total_dbuf = sdp->sd_log_num_databuf; | 502 | unsigned int total_dbuf = sdp->sd_log_num_databuf; |
503 | unsigned int total_jdata = sdp->sd_log_num_jdata; | 503 | unsigned int total_jdata = sdp->sd_log_num_jdata; |
504 | unsigned int num, n; | 504 | unsigned int num, n; |
505 | __be64 *ptr; | 505 | __be64 *ptr = NULL; |
506 | unsigned i; | ||
506 | 507 | ||
507 | offset += (2*sizeof(__be64) - 1); | 508 | offset += (2*sizeof(__be64) - 1); |
508 | offset &= ~(2*sizeof(__be64) - 1); | 509 | offset &= ~(2*sizeof(__be64) - 1); |
@@ -513,14 +514,17 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
513 | * Start writing ordered buffers, write journaled buffers | 514 | * Start writing ordered buffers, write journaled buffers |
514 | * into the log along with a header | 515 | * into the log along with a header |
515 | */ | 516 | */ |
517 | gfs2_log_lock(sdp); | ||
518 | /* printk(KERN_INFO "locked in lops databuf_before_commit\n"); */ | ||
516 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, bd_le.le_list); | 519 | bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, bd_le.le_list); |
517 | while(total_dbuf) { | 520 | while(total_dbuf) { |
518 | num = total_jdata; | 521 | num = total_jdata; |
519 | if (num > limit) | 522 | if (num > limit) |
520 | num = limit; | 523 | num = limit; |
524 | /* printk(KERN_INFO "total_dbuf=%u num=%u\n", total_dbuf, num); */ | ||
521 | n = 0; | 525 | n = 0; |
526 | i = 0; | ||
522 | list_for_each_entry_safe_continue(bd1, bdt, &sdp->sd_log_le_databuf, bd_le.le_list) { | 527 | list_for_each_entry_safe_continue(bd1, bdt, &sdp->sd_log_le_databuf, bd_le.le_list) { |
523 | gfs2_log_lock(sdp); | ||
524 | /* An ordered write buffer */ | 528 | /* An ordered write buffer */ |
525 | if (bd1->bd_bh && !buffer_pinned(bd1->bd_bh)) { | 529 | if (bd1->bd_bh && !buffer_pinned(bd1->bd_bh)) { |
526 | list_move(&bd1->bd_le.le_list, &started); | 530 | list_move(&bd1->bd_le.le_list, &started); |
@@ -531,20 +535,28 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
531 | total_dbuf--; | 535 | total_dbuf--; |
532 | if (bd1->bd_bh) { | 536 | if (bd1->bd_bh) { |
533 | get_bh(bd1->bd_bh); | 537 | get_bh(bd1->bd_bh); |
534 | gfs2_log_unlock(sdp); | ||
535 | if (buffer_dirty(bd1->bd_bh)) { | 538 | if (buffer_dirty(bd1->bd_bh)) { |
539 | gfs2_log_unlock(sdp); | ||
536 | wait_on_buffer(bd1->bd_bh); | 540 | wait_on_buffer(bd1->bd_bh); |
537 | ll_rw_block(WRITE, 1, &bd1->bd_bh); | 541 | ll_rw_block(WRITE, 1, &bd1->bd_bh); |
542 | gfs2_log_lock(sdp); | ||
538 | } | 543 | } |
539 | brelse(bd1->bd_bh); | 544 | 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 | } | ||
540 | continue; | 551 | continue; |
541 | } | 552 | } |
542 | gfs2_log_unlock(sdp); | 553 | /* printk(KERN_INFO "db skip\n"); */ |
543 | continue; | 554 | continue; |
544 | } else if (bd1->bd_bh) { /* A journaled buffer */ | 555 | } else if (bd1->bd_bh) { /* A journaled buffer */ |
545 | int magic; | 556 | int magic; |
546 | gfs2_log_unlock(sdp); | 557 | gfs2_log_unlock(sdp); |
547 | /* printk(KERN_INFO "journaled buffer\n"); */ | 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); | ||
548 | if (!bh) { | 560 | if (!bh) { |
549 | bh = gfs2_log_get_buf(sdp); | 561 | bh = gfs2_log_get_buf(sdp); |
550 | ld = (struct gfs2_log_descriptor *)bh->b_data; | 562 | ld = (struct gfs2_log_descriptor *)bh->b_data; |
@@ -558,16 +570,21 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
558 | ld->ld_data2 = cpu_to_be32(0); | 570 | ld->ld_data2 = cpu_to_be32(0); |
559 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); | 571 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); |
560 | } | 572 | } |
573 | /* printk(KERN_INFO "check_magic\n"); */ | ||
561 | magic = gfs2_check_magic(bd1->bd_bh); | 574 | magic = gfs2_check_magic(bd1->bd_bh); |
575 | /* printk(KERN_INFO "write data\n"); */ | ||
562 | *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); | 576 | *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); |
563 | *ptr++ = cpu_to_be64((__u64)magic); | 577 | *ptr++ = cpu_to_be64((__u64)magic); |
578 | /* printk(KERN_INFO "mark escaped or not\n"); */ | ||
564 | clear_buffer_escaped(bd1->bd_bh); | 579 | clear_buffer_escaped(bd1->bd_bh); |
565 | if (unlikely(magic != 0)) | 580 | if (unlikely(magic != 0)) |
566 | set_buffer_escaped(bd1->bd_bh); | 581 | set_buffer_escaped(bd1->bd_bh); |
582 | gfs2_log_lock(sdp); | ||
567 | if (n++ > num) | 583 | if (n++ > num) |
568 | break; | 584 | break; |
569 | } | 585 | } |
570 | } | 586 | } |
587 | gfs2_log_unlock(sdp); | ||
571 | if (bh) { | 588 | if (bh) { |
572 | set_buffer_dirty(bh); | 589 | set_buffer_dirty(bh); |
573 | ll_rw_block(WRITE, 1, &bh); | 590 | ll_rw_block(WRITE, 1, &bh); |
@@ -575,10 +592,12 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
575 | } | 592 | } |
576 | n = 0; | 593 | n = 0; |
577 | /* printk(KERN_INFO "totals2: jdata=%u dbuf=%u\n", total_jdata, total_dbuf); */ | 594 | /* printk(KERN_INFO "totals2: jdata=%u dbuf=%u\n", total_jdata, total_dbuf); */ |
595 | gfs2_log_lock(sdp); | ||
578 | list_for_each_entry_continue(bd2, &sdp->sd_log_le_databuf, bd_le.le_list) { | 596 | list_for_each_entry_continue(bd2, &sdp->sd_log_le_databuf, bd_le.le_list) { |
579 | if (!bd2->bd_bh) | 597 | if (!bd2->bd_bh) |
580 | continue; | 598 | continue; |
581 | /* copy buffer if it needs escaping */ | 599 | /* copy buffer if it needs escaping */ |
600 | gfs2_log_unlock(sdp); | ||
582 | if (unlikely(buffer_escaped(bd2->bd_bh))) { | 601 | if (unlikely(buffer_escaped(bd2->bd_bh))) { |
583 | void *kaddr; | 602 | void *kaddr; |
584 | struct page *page = bd2->bd_bh->b_page; | 603 | struct page *page = bd2->bd_bh->b_page; |
@@ -592,6 +611,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
592 | } | 611 | } |
593 | set_buffer_dirty(bh); | 612 | set_buffer_dirty(bh); |
594 | ll_rw_block(WRITE, 1, &bh); | 613 | ll_rw_block(WRITE, 1, &bh); |
614 | gfs2_log_lock(sdp); | ||
595 | if (++n >= num) | 615 | if (++n >= num) |
596 | break; | 616 | break; |
597 | } | 617 | } |
@@ -599,6 +619,8 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
599 | total_dbuf -= num; | 619 | total_dbuf -= num; |
600 | total_jdata -= num; | 620 | total_jdata -= num; |
601 | } | 621 | } |
622 | gfs2_log_unlock(sdp); | ||
623 | |||
602 | /* printk(KERN_INFO "wait on ordered data buffers\n"); */ | 624 | /* printk(KERN_INFO "wait on ordered data buffers\n"); */ |
603 | /* Wait on all ordered buffers */ | 625 | /* Wait on all ordered buffers */ |
604 | while (!list_empty(&started)) { | 626 | while (!list_empty(&started)) { |
@@ -701,12 +723,10 @@ static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
701 | 723 | ||
702 | while (!list_empty(head)) { | 724 | while (!list_empty(head)) { |
703 | bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); | 725 | bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); |
704 | list_del_init(&bd->bd_le.le_list); | 726 | list_del(&bd->bd_le.le_list); |
705 | sdp->sd_log_num_databuf--; | 727 | sdp->sd_log_num_databuf--; |
706 | sdp->sd_log_num_jdata--; | 728 | sdp->sd_log_num_jdata--; |
707 | gfs2_unpin(sdp, bd->bd_bh, ai); | 729 | gfs2_unpin(sdp, bd->bd_bh, ai); |
708 | brelse(bd->bd_bh); | ||
709 | kfree(bd); | ||
710 | } | 730 | } |
711 | gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf); | 731 | gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf); |
712 | gfs2_assert_warn(sdp, !sdp->sd_log_num_jdata); | 732 | gfs2_assert_warn(sdp, !sdp->sd_log_num_jdata); |