diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-08-24 19:59:40 (GMT) |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-08-24 19:59:40 (GMT) |
commit | 166afccd71fbb7bd758ab9fc770eef4924081077 (patch) | |
tree | 05ba592267ca899e0f5b9313fc7a8d1415bc5f63 /fs | |
parent | 233e515f4062f99569c24f00ad7429a860b23db4 (diff) | |
download | linux-166afccd71fbb7bd758ab9fc770eef4924081077.tar.xz |
[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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/ops_address.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 4c59cb1..4872042 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) struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; struct gfs2_bufdata *bd = bh->b_private; struct gfs2_glock *gl; +static unsigned limit = 0; + + if (limit++ > 3) + return; fs_warn(sdp, "stuck in gfs2_releasepage() %p\n", inode); fs_warn(sdp, "blkno = %llu, bh->b_count = %d\n", @@ -736,28 +740,24 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info; struct buffer_head *bh, *head; struct gfs2_bufdata *bd; - unsigned long t; + unsigned long t = jiffies + gfs2_tune_get(sdp, gt_stall_secs) * HZ; if (!page_has_buffers(page)) goto out; head = bh = page_buffers(page); do { - t = jiffies; - while (atomic_read(&bh->b_count)) { - if (atomic_read(&aspace->i_writecount)) { - if (time_after_eq(jiffies, t + - gfs2_tune_get(sdp, gt_stall_secs) * HZ)) { - stuck_releasepage(bh); - t = jiffies; - } - - yield(); - continue; + if (!atomic_read(&aspace->i_writecount)) + return 0; + + if (time_after_eq(jiffies, t)) { + stuck_releasepage(bh); + /* should we withdraw here? */ + return 0; } - return 0; + yield(); } gfs2_assert_warn(sdp, !buffer_pinned(bh)); @@ -773,8 +773,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) } bh = bh->b_this_page; - } - while (bh != head); + } while (bh != head); out: return try_to_free_buffers(page); |