Commit 166afccd authored by Steven Whitehouse's avatar Steven Whitehouse
Browse files

[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: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 233e515f
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -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)) {
			if (!atomic_read(&aspace->i_writecount))
				return 0;

			if (time_after_eq(jiffies, t)) {
				stuck_releasepage(bh);
					t = jiffies;
				/* should we withdraw here? */
				return 0;
			}

			yield();
				continue;
			}

			return 0;
		}

		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);