aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-08-24 15:59:40 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-08-24 15:59:40 -0400
commit166afccd71fbb7bd758ab9fc770eef4924081077 (patch)
tree05ba592267ca899e0f5b9313fc7a8d1415bc5f63
parent233e515f4062f99569c24f00ad7429a860b23db4 (diff)
[GFS2] Tidy up error handling in gfs2_releasepage()
This should clarify the logic in gfs2_releasepage() relating to error handling as well as making the response to errors a bit more graceful. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/ops_address.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 4c59cb110995..48720421c796 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -683,6 +683,10 @@ static void stuck_releasepage(struct buffer_head *bh)
683 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; 683 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
684 struct gfs2_bufdata *bd = bh->b_private; 684 struct gfs2_bufdata *bd = bh->b_private;
685 struct gfs2_glock *gl; 685 struct gfs2_glock *gl;
686static unsigned limit = 0;
687
688 if (limit++ > 3)
689 return;
686 690
687 fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode); 691 fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode);
688 fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n", 692 fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n",
@@ -736,28 +740,24 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
736 struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info; 740 struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info;
737 struct buffer_head *bh, *head; 741 struct buffer_head *bh, *head;
738 struct gfs2_bufdata *bd; 742 struct gfs2_bufdata *bd;
739 unsigned long t; 743 unsigned long t = jiffies + gfs2_tune_get(sdp, gt_stall_secs) * HZ;
740 744
741 if (!page_has_buffers(page)) 745 if (!page_has_buffers(page))
742 goto out; 746 goto out;
743 747
744 head = bh = page_buffers(page); 748 head = bh = page_buffers(page);
745 do { 749 do {
746 t = jiffies;
747
748 while (atomic_read(&bh->b_count)) { 750 while (atomic_read(&bh->b_count)) {
749 if (atomic_read(&aspace->i_writecount)) { 751 if (!atomic_read(&aspace->i_writecount))
750 if (time_after_eq(jiffies, t + 752 return 0;
751 gfs2_tune_get(sdp, gt_stall_secs) * HZ)) { 753
752 stuck_releasepage(bh); 754 if (time_after_eq(jiffies, t)) {
753 t = jiffies; 755 stuck_releasepage(bh);
754 } 756 /* should we withdraw here? */
755 757 return 0;
756 yield();
757 continue;
758 } 758 }
759 759
760 return 0; 760 yield();
761 } 761 }
762 762
763 gfs2_assert_warn(sdp, !buffer_pinned(bh)); 763 gfs2_assert_warn(sdp, !buffer_pinned(bh));
@@ -773,8 +773,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
773 } 773 }
774 774
775 bh = bh->b_this_page; 775 bh = bh->b_this_page;
776 } 776 } while (bh != head);
777 while (bh != head);
778 777
779out: 778out:
780 return try_to_free_buffers(page); 779 return try_to_free_buffers(page);